{"id":20649261,"url":"https://github.com/repalash/supabase-cf-project-starter","last_synced_at":"2025-07-31T00:06:36.107Z","repository":{"id":194503518,"uuid":"686981249","full_name":"repalash/supabase-cf-project-starter","owner":"repalash","description":"Project management starter kit for building simple apps like figma using supabase and cloudflare workers","archived":false,"fork":false,"pushed_at":"2024-12-30T11:44:01.000Z","size":192,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-17T10:12:09.969Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/repalash.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-04T11:04:25.000Z","updated_at":"2024-09-09T18:22:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"c509d6ed-505e-4ded-82a1-7ef1175edfb8","html_url":"https://github.com/repalash/supabase-cf-project-starter","commit_stats":null,"previous_names":["repalash/supabase-cf-project-starter"],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repalash%2Fsupabase-cf-project-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repalash%2Fsupabase-cf-project-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repalash%2Fsupabase-cf-project-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repalash%2Fsupabase-cf-project-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/repalash","download_url":"https://codeload.github.com/repalash/supabase-cf-project-starter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242737019,"owners_count":20177092,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T17:13:26.624Z","updated_at":"2025-03-09T19:16:59.749Z","avatar_url":"https://github.com/repalash.png","language":"PLpgSQL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Project Management supabase + cloudflare template\n\nSimple starter kit for the backend that can also be used as is to create a project management system similar to figma(without realtime collaboration right now) with supabase and cloudflare workers.\n\nAll infrastructure is defined as code in the project. The starter sql is present in `starter.sql`, the worker code is in `cf-worker/src/worker.ts` and a sample for the wrangler.toml is present in `wrangler.sample.toml`.\n\nThe starter sql creates the tables, functions, triggers, and policies required for the project. The worker code is a simple proxy to supabase with some additional functionality for user assets and avatar and poster iamges.\n\nThe cloudflare worker project can be used by using it as a template, by copying the code into an existing project, using it as a dependency or as a submodule. \nUsing it as a dependency or a submodule makes it possible to upgrade the worker code easily, but makes it harder to modify the worker code to suit your needs.\n\nNote: This is a very simple project and could serve as a starting point. But this in no way is a complete production ready system, and requires considerable work on the frontend.\n\nNote: Good knowledge of postgreSQL, supabase and cloudflare workers is required to use this project.\n\n## Database\n\n### Tables\n\n- profiles - stores user profiles and links to supabase auth users table\n- projects - stores project details including jsonb data, poster, owner etc\n- user_assets - stores user uploaded assets\n- project_versions - automatic backups of json data of projects\n\n## Setup\n\nHere is the setup checklist, more details are below.\n\n- [ ] Create a supabase project\n- [ ] Run starter SQL script\n- [ ] Create a wrangler.toml file for the worker from wrangler.sample.toml\n- [ ] Set name and route in wrangler.toml, comment route and env.staging if not required.\n- [ ] Create a bucket for user assets, update wrangler.toml\n- [ ] Map the bucket to a domain, update wrangler.toml\n- [ ] Set cors policy for the bucket\n- [ ] Set the supabase url, anon token in wrangler.toml\n- [ ] Deploy the worker for the first time\n- [ ] Create a new .dev.vars file with the jwt secret for local development\n- [ ] Set the jwt secret on deployment(s)\n- [ ] Use the worker endpoint with supabase in the frontend.\n\n### Supabase setup\nCreate a new supabase project, either a managed project from the supabase dashboard or a self hosted project.\n\nCopy all the code from `starter.sql` and paste it into the SQL Editor in the supabase project. \n\nPress `Run` to create the tables, functions, triggers, and policies.\n\n### Worker setup\n\nMove into the `cf-worker` directory\n```sh\ncd cf-worker\n```\n\nCopy wrangler.sample.toml to wrangler.toml\n```sh\ncp wrangler.sample.toml wrangler.toml\n```\n\nSet the name, account_id of the worker in wrangler.toml\n```toml\naccount_id = \"\u003ccloudflare account id\u003e\"\nname = \"\u003cworker name\u003e\"\n```\n\nCreate a bucket for user assets, and put the name in wrangler.toml\n```sh\nnpx wrangler r2 bucket create \u003cbucket-name\u003e\n```\n```toml\n[[r2_buckets]]\nbinding = \"USER_ASSETS_BUCKET_1\"\nbucket_name = \"\u003cbucket name\u003e\"\n```\n\nNext [add a cors policy for the bucket](https://developers.cloudflare.com/r2/buckets/cors/#add-cors-policies-from-the-dashboard) to be able to access the files from the frontend.\nHere's a sample for allowing all domains: \n```json\n[\n  {\n    \"AllowedOrigins\": [ \"*\" ],\n    \"AllowedMethods\": [ \"GET\" ]\n  }\n]\n```\nSet `*` to the domain for the frontend, if only one domain is required.\n\nMap the bucket to a domain or enable public access from the cloudflare portal, then set `USER_ASSET_BASE_URL_1` in wrangler.toml to the domain or bucket url like:\n```toml\nUSER_ASSET_BASE_URL_1 = \"https://cdn1.\u003cyour domain\u003e.com\"\n```\n\nSet the `SUPABASE_URL`, `SUPABASE_ANON_TOKEN` variables in wrangler.toml to the url and jwt secret in the supabase project.\n```toml\nSUPABASE_URL = \"https://\u003csupabase project id\u003e.supabase.co\"\nSUPABASE_ANON_TOKEN = \"\u003csupabase anonymous token\u003e\"\n```\n\n`SUPABASE_JWT_SECRET` has to be set as an encrypted value in the cloudflare dashboard or via cli(after first deployment).\n\nIt has to be set for every environment(like staging)\n\nTo set it via cli (do this after first deployment), run:\n```sh\nwrangler secret put SUPABASE_JWT_SECRET\nwrangler secret put SUPABASE_JWT_SECRET --env staging\n```\n\nFor local development create a `.dev.vars` with the secret:\n```sh\necho \"SUPABASE_JWT_SECRET=\u003cjwt_secret\u003e\" \u003e .dev.vars\n```\n\n## Test the worker locally \n    \n```sh\nnpm run start # same as wrangler dev\n```\n\n## Deploy the worker \n\nDeploy to staging\n```sh\nnpm run deploy # same as wrangler deploy --env staging\n```\n\nDeploy to prod\n```sh\nnpm run deploy:prod # same as wrangler deploy\n```\n\n## Usage in frontend\n\nPass the worker url directly into the supabase `createClient` function.\n```js\nconst supabase = createClient(\n  'https://\u003cworker name\u003e.\u003cyour domain\u003e.workers.dev', // or your custom domain mapped to the worker\n  '0' // this can be '0' because defined in wrangler.toml\n)\n```\n\n### Proxy to supabase\n\nAll the supabase API works as is, but the worker adds some additional functionality, like custom domains and removing the need to pass the anonymous key in the frontend. It could simply be an empty string if defined in wrangler.toml\n\nHere's an example for making a direct request, but for most cases directly using supabase client will be enough.\n```js\nconst response = await fetch(WORKER_URL + '/rest/v1/projects?select=*\u0026limit=1', {\n    headers: {\n        'Authorization': 'Bearer ' + session.access_token\n    },\n})\n```\n\n### User asset management\nPUT, DELETE, GET are allowed to `/api/v1/user_asset/\u003cfilePath\u003e` if the user is logged in.\nLogin is verified by setting the Authorization header to the supabase access token. \n\nThis will also create or delete the respective rows in the `user_assets` table in the supabase project.\n\nUpdate is not possible, to update, delete and upload again with the same file path. The asset url will change on doing this.\n\n#### Upload\nSend a `PUT` request to `/api/v1/user_asset/\u003cfilePath\u003e` and include the file in the body of the request. Set the `Content-Type` header to the mime type of the file.\n\n```js\nconst response = await fetch(WORKER_URL + '/api/v1/user_asset/' + filePath + \"?type=texture\", {\n    body: file,\n    headers: {\n        'Authorization': 'Bearer ' + session.access_token,\n        'Content-Type': file.type\n    },\n    method: 'PUT' \n})\n```\n\n#### Delete\nSend a `DELETE` request to `/api/v1/user_asset/\u003cfilePath\u003e`.\n\n```js\nconst response = await fetch(WORKER_URL + '/api/v1/user_asset/' + filePath, {\n    headers: {\n        'Authorization': 'Bearer ' + session.access_token\n    },\n    method: 'DELETE' \n})\n```\n\n#### Download\nSend a `GET` request to `/api/v1/user_asset/\u003cfilePath\u003e`.\n\n```js\nconst response = await fetch(WORKER_URL + '/api/v1/user_asset/' + filePath, {\n    headers: {\n        'Authorization': 'Bearer ' + session.access_token\n    },\n    method: 'GET' \n})\n```\n\nNote: this is for authenticated use only, to access the asset publicly, use the public asset url that's in the db or generated with the user asset base path.\n\n### Image Management\n\nPosters for user assets, projects and avatars for profiles can be uploaded and downloaded using the image endpoint. It adds extra features for serving and processing images.\n\nThe API works similar to the user_asset endpoint.\n\nFor user assets: `/api/v1/image/\u003cfilePath\u003e`\n\nFor user profile avatars: `/api/v1/image/.profiles/\u003cuserId\u003e`\n\nFor project posters: `/api/v1/image/.projects/\u003cprojectId\u003e`\n\n## Local development\n\n```sh\nnpm run start # same as wrangler dev\n```\n\n## Deploy\n\n```sh\nnpm run deploy # same as wrangler deploy\n```\n\n\n## Notes\nFile path should be unique per user\nFile path should not start with dot `.`\nFile path should not contain `..`\nFile path should not start with a number\n\nJetbrains IDEs(like Webstorm) can be used to connect to the supabase postgresql database. When connected all context-aware autocomplete work with the live database in SQL files.\n\nWhen making changes to the database, its recommended to change the starter script and run the necessary commands on the database. For any additions to the database, consider creating a new SQL file and using that.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frepalash%2Fsupabase-cf-project-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frepalash%2Fsupabase-cf-project-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frepalash%2Fsupabase-cf-project-starter/lists"}