helix-tribune migrates from Supabase/Cloudflare to AWS (SST + Fargate + Aurora + Clerk)
saratpediredla-level5 replaced the entire runtime foundation of this fork across three commits: Supabase out, Aurora Serverless v2 and Clerk in; Cloudflare Workers out, Fargate behind an ALB and CloudFront plus Lambda in. The SST v3 config covering VPC, RDS, S3, Fargate, and the Next.js site is the single infrastructure source of truth.
The main squash (03011e6) bundles nine logical stages. At the data layer, a new Drizzle schema in backend/src/db/schema.ts translates all 16 tables from the legacy backend/schema.sql, dropping Postgres row-level security in full. Access decisions move into Express route handlers via access.ts helpers; user_id columns retype from uuid to text for Clerk identifiers. Every supabase-js callsite across the backend is rewritten to Drizzle. Auth middleware (backend/src/middleware/auth.ts) now verifies Clerk JWTs via @clerk/backend and bootstraps user_profiles rows in-process on first request, replacing the dropped handle_new_user trigger. Storage shifts from R2 to S3 using IAM-role credentials from the Fargate task role; email moves from Resend to SESv2. The frontend wraps in ClerkProvider, and the OpenNext adapter switches from @opennextjs/cloudflare to @opennextjs/aws.
The initial sst.config.ts mixed v2 syntax (SSTConfig, stacks()) with v3 primitives - npx sst diff would fail on import. A same-day correction (338483f) rewrites it to valid v3 $config({ app(), async run() }), adds the required sst.aws.Cluster between Vpc and Service, replaces loadBalancer.public with an explicit ports: [{ listen: "80/http", forward: "3001/http" }] array, sets bastion: true on the VPC so Drizzle migrations can run from a laptop via sst tunnel, and introduces a FrontendUrl SST secret to break the CORS URL cycle. HTTPS and custom domain on the Next.js site are deferred, flagged inline.
The third commit (806025e) renames the SST app from mike to helix-tribune and flips the default region from N. Virginia to eu-west-2 across sst.config.ts, the Fargate environment block, and the fallback strings in storage.ts and email.ts.
A few things to flag if you're evaluating the code for reuse. RLS is completely absent - every access check is now in route code, so any upstream feature that assumed a Postgres-level backstop will silently lose it on merge. The first-request profile bootstrap is in-memory; it survives restarts correctly (it's a cache, not authoritative), but each fresh Fargate task will re-bootstrap. backend/schema.sql is intentionally left on disk as a no-op to ease three-way merges from upstream. The tagWIdsOnRenderedDom refactor in DocxView (now accepts a token argument) will conflict with upstream changes to that file.
Spotted something wrong? Or know the PR text has fresher detail than the writeup above?