Files
NianAIGC/.project-docs/10-decisions/adr-003-next-go-target.md
T

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`