79 lines
4.1 KiB
Markdown
79 lines
4.1 KiB
Markdown
# ADR-003: Next.js Frontend And Go Backend Target
|
|
|
|
## Status
|
|
|
|
Accepted and implemented in repository revision `b14b4fc` on 2026-08-16;
|
|
production rollout and live smoke tests remain pending (see `DEP-001`)
|
|
|
|
## Date
|
|
|
|
2026-08-12
|
|
|
|
## Context
|
|
|
|
The original application was a Next.js full-stack Web workload plus a Node
|
|
process that periodically called an internal Worker tick endpoint. The Go
|
|
modular monolith subsequently took ownership of the HTTP and business backend,
|
|
while Next.js retained SSR and an internal Go identity bridge. That remaining
|
|
server-side frontend seam caused the first production login path to fail with
|
|
an RSC error and added Web-to-Go DNS/configuration coupling.
|
|
|
|
The user explicitly approved a stricter boundary: the frontend is a static page
|
|
set and every runtime API is provided by Go.
|
|
|
|
## Decision
|
|
|
|
The approved topology has two long-lived same-origin ACK workloads:
|
|
|
|
- Next.js is a build tool only. An unprivileged Nginx workload serves its static
|
|
`out/` pages and assets. Web has no SSR, Middleware, Route Handlers, runtime
|
|
ConfigMap, session Secret, database credential, or internal Go URL.
|
|
- The browser calls same-origin `/api/**`, `/uploads/**`, and
|
|
`/generated-results/**`; Ingress routes them directly to Go. Browser route
|
|
guards are presentation behavior, never an authorization boundary.
|
|
- Go owns the existing `/api/**`, `/uploads/**`, and `/generated-results/**` contracts; identity, administration, assets, jobs, billing, usage, providers, storage, Webhooks, readiness, and an initially embedded WorkerLoop.
|
|
- RDS PostgreSQL remains the source of relational truth and cross-instance concurrency.
|
|
- Initial schema creation is a manual/CI operator action using the versioned SQL
|
|
plus application-role grants. No migration Job reuses the static Web image.
|
|
- Split the embedded WorkerLoop into a third workload only after independent scaling or failure-isolation needs are demonstrated.
|
|
|
|
The implementation must preserve the existing HTTP and Cookie Interface, multi-tenant authorization, idempotency, task state, wallet, storage, and Webhook behavior. It must continue calling `claim_generation_jobs` and `billing_post_wallet_entry`; Go process-local locks cannot replace these database functions.
|
|
|
|
The checked-in source and ACK manifests implement this boundary. The live
|
|
cluster must still be verified after publishing new immutable Web and Go images.
|
|
|
|
## Rationale
|
|
|
|
- Establishes clear runtime and Secret ownership between UI and backend.
|
|
- Removes request-time frontend rendering and Web-to-Go internal transport.
|
|
- Allows backend lifecycle, testing, and future scaling to evolve independently of Next.js.
|
|
- Removes the internal HTTP tick seam once the Go WorkerLoop is production-ready.
|
|
- Keeps the initial workload count at two rather than introducing a separate API and Worker before evidence justifies it.
|
|
- Preserves the already-reviewed PostgreSQL concurrency and migration contracts.
|
|
|
|
## Consequences
|
|
|
|
- Production pages are public static resources; all protected data and actions
|
|
must be authorized by Go on every request.
|
|
- API failures surface as client state instead of fatal RSC rendering failures.
|
|
- New runtime endpoints belong in Go. Reintroducing Next Route Handlers,
|
|
Middleware authentication, or request-Cookie SSR violates this decision.
|
|
- Go API replica count initially also changes WorkerLoop concurrency and provider/RDS load.
|
|
- The Web workload can scale independently, but Go remains one replica until
|
|
generated/uploaded assets use OSS or another shared store.
|
|
- Executable HTTP/Cookie compatibility and static-boundary tests are mandatory.
|
|
|
|
## Supersedes
|
|
|
|
- ACK-001. Production does not deploy the Node Worker or give Web database
|
|
ownership.
|
|
|
|
## Related
|
|
|
|
- `.project-docs/10-decisions/proposals/20260812-go-backend-migration-6f4a92__next-go-architecture.md`
|
|
- `.project-docs/30-worklog/tasks/20260812-next-go-architecture-4d81e2.md`
|
|
- `.project-docs/30-worklog/tasks/20260812-go-backend-migration-6f4a92.md`
|
|
- `.project-docs/10-decisions/proposals/20260816-static-frontend-go-api-4f8c2a7d__static-web-go-api.md`
|
|
- `.project-docs/30-worklog/tasks/20260816-static-frontend-go-api-4f8c2a7d.md`
|
|
- RDS-001 and RDS-002 in `.project-docs/10-decisions/decision-index.md`
|