Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ jobs:
sarif_file: 'trivy-results.sarif'
continue-on-error: true

supabase-functions-check:
name: Supabase Functions Typecheck
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Deno
uses: denoland/setup-deno@v2
with:
deno-version: v2.x

- name: Typecheck Edge Functions
run: deno check supabase/functions/*/index.ts

deploy-frontend:
name: Deploy Frontend to Vercel
needs: [frontend-tests]
Expand Down
2 changes: 2 additions & 0 deletions docs/07-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ Check build logs in Vercel dashboard. Common issues:

- Confirm the calling origin is in the `ALLOWED_ORIGINS` list in
`supabase/functions/_shared/cors.ts`
- Vercel preview origins (`https://nutrisync-frontend-*.vercel.app`) are
allowed via the `VERCEL_PREVIEW_ORIGIN` regex in the same file
- Redeploy the function after changing it

### Database connection errors
Expand Down
38 changes: 38 additions & 0 deletions supabase/functions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Supabase Edge Functions

Deno functions backing the NutriSync frontend. Full deploy walkthrough:
[docs/07-deployment.md](../../docs/07-deployment.md).

## Layout

- `<name>/index.ts` - one directory per function; `index.ts` is the entrypoint.
- `_shared/` - helpers imported by functions, never deployed on their own:
`cors.ts` (origin allow-list + JSON responses), `gemini.ts`,
`analyzeFoodImage.ts`, `json.ts`, `supabaseAdmin.ts`.

## Secrets

| Secret | Used by | Notes |
| --- | --- | --- |
| `GOOGLE_API_KEY` | Gemini-backed functions (chat, recommendations, image analysis, ...) | Required |
| `USDA_API_KEY` | `search-food`, `food-details` | Optional; falls back to USDA `DEMO_KEY` (heavily rate-limited) |

`SUPABASE_URL` / `SUPABASE_SERVICE_ROLE_KEY` are injected by Supabase.

```bash
supabase secrets set GOOGLE_API_KEY=<key> USDA_API_KEY=<key>
```

## Local dev and deploy

```bash
supabase functions serve # run all functions locally
supabase functions deploy # deploy all
supabase functions deploy <name> # deploy one
```

## CI

The `supabase-functions-check` job in `.github/workflows/ci.yml` runs
`deno check supabase/functions/*/index.ts` on pushes and PRs. Marking the job
required is a manual branch-protection setting (repo Settings > Branches).
9 changes: 8 additions & 1 deletion supabase/functions/_shared/cors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@ export const ALLOWED_ORIGINS = [
"http://localhost:3000",
];

// Vercel production + preview deployments of the frontend project.
export const VERCEL_PREVIEW_ORIGIN = /^https:\/\/nutrisync-frontend(-[a-z0-9-]+)?\.vercel\.app$/;

function isAllowedOrigin(origin: string): boolean {
return ALLOWED_ORIGINS.includes(origin) || VERCEL_PREVIEW_ORIGIN.test(origin);
}

export function corsHeaders(origin: string | null): Record<string, string> {
const allowOrigin = origin && ALLOWED_ORIGINS.includes(origin) ? origin : ALLOWED_ORIGINS[0];
const allowOrigin = origin && isAllowedOrigin(origin) ? origin : ALLOWED_ORIGINS[0];
return {
"Access-Control-Allow-Origin": allowOrigin,
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
Expand Down
Loading