docs: integrate static frontend architecture
This commit is contained in:
1 parent
b14b4fced7
commit
bb50d06d1d
13 files changed
+243
-82
No files matched your search
@@ -2,7 +2,8 @@
|
||||
|
||||
## Status
|
||||
|
||||
Accepted target; Go implementation merged into `main` on 2026-08-14 (see `.project-docs/30-worklog/current-state.md`); first production deployment pending — there is no legacy production instance, so no cutover applies (see `DEP-001` in the decision index)
|
||||
Accepted and implemented in repository revision `b14b4fc` on 2026-08-16;
|
||||
production rollout and live smoke tests remain pending (see `DEP-001`)
|
||||
|
||||
## Date
|
||||
|
||||
@@ -10,27 +11,41 @@ Accepted target; Go implementation merged into `main` on 2026-08-14 (see `.proje
|
||||
|
||||
## Context
|
||||
|
||||
The integrated application currently runs as a Next.js full-stack Web workload plus a Node process that periodically calls an internal Worker tick endpoint. Next.js owns browser rendering, HTTP routes, authentication, PostgreSQL access, task execution, billing, providers, storage, and Webhooks. This makes the deployment operationally compact, but keeps the UI framework and the complete business backend in the same runtime.
|
||||
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 long-term split in which Next.js is the frontend and a Go modular monolith owns the backend. The user later clarified that this integration records design and progress only; it does not authorize or claim a completed code migration.
|
||||
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 target is a same-origin ACK topology with two long-lived workloads:
|
||||
The approved topology has two long-lived same-origin ACK workloads:
|
||||
|
||||
- Next.js serves pages, static assets, and SSR. It calls Go over HTTP and does not own RDS, provider, OSS, billing, or migration credentials.
|
||||
- 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.
|
||||
- The one-shot, versioned PostgreSQL migration Job remains separate.
|
||||
- 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.
|
||||
|
||||
Until the implementation is complete and verified, the existing ACK-001 Web/HTTP-polling-Worker architecture remains the deployed and source-code truth.
|
||||
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.
|
||||
@@ -38,19 +53,26 @@ Until the implementation is complete and verified, the existing ACK-001 Web/HTTP
|
||||
|
||||
## Consequences
|
||||
|
||||
- The migration is a substantial behavior-compatible rewrite across TypeScript and Go, not a deployment-only change.
|
||||
- Next.js can remain SSR but is database-free; static export is a separate future choice.
|
||||
- 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.
|
||||
- Executable compatibility tests and reversible, single-writer cutover are mandatory.
|
||||
- Current code, manifests, and configuration remain unchanged by this ADR.
|
||||
- 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 after the Go implementation and cutover are complete. ACK-001 remains the transition-state operational decision until then.
|
||||
- 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`
|
||||
@@ -5,9 +5,9 @@
|
||||
| ID | Decision | Status | Date | Applies To | Detail |
|
||||
|---|---|---|---|---|---|
|
||||
| RDS-001 | Production persistence uses explicit direct PostgreSQL through one server-only adapter; local JSON is explicit development/test mode. | Accepted | 2026-08-12 | Server stores and scripts | `ZHINIAN_DATA_BACKEND=postgres` fails closed and never silently falls back. |
|
||||
| RDS-002 | Database changes use versioned, checksummed, advisory-locked migrations. | Accepted; execution amended 2026-08-14 | 2026-08-12 | Database schema and rollout | Initial production schema is executed manually from `database/migrations/*.sql` plus application-role grants; the one-shot Job manifest is retained but not part of the deployment path. |
|
||||
| ADR-003 | Target architecture is a same-origin Next.js frontend plus Go modular-monolith backend with an initially embedded WorkerLoop. | Accepted target; Go implementation merged into `main` 2026-08-14; first production deployment pending | 2026-08-12 | Application and ACK architecture | First deployment runs the split topology directly; no legacy production instance exists. See `adr-003-next-go-target.md`. |
|
||||
| DEP-001 | Production starts fresh: the first production deployment runs the ADR-003 split topology (Next.js frontend + Go backend), there is no legacy cutover or Node Worker, and the schema is initialized by manually executed SQL. | Accepted | 2026-08-14 | Deployment model and schema initialization | Human decision: no migration Job pod; super administrator is bootstrapped from `ZHINIAN_BOOTSTRAP_ADMIN_*` configuration at Go startup. |
|
||||
| RDS-002 | Database changes use versioned, checksummed, advisory-locked migrations. | Accepted; execution amended 2026-08-14 | 2026-08-12 | Database schema and rollout | Initial production schema is executed manually from `database/migrations/*.sql` plus application-role grants; no migration Job manifest is shipped with the static Web image. |
|
||||
| ADR-003 | Production is a same-origin static Next.js export on Nginx plus a Go modular-monolith backend with an embedded WorkerLoop. | Accepted; repository implementation complete in `b14b4fc`; production rollout pending | 2026-08-12, amended 2026-08-16 | Application and ACK architecture | Browser routes are static; all runtime API/file/auth responsibility belongs to Go. See `adr-003-next-go-target.md`. |
|
||||
| DEP-001 | Production starts fresh with the ADR-003 static Web + Go topology, no legacy cutover or Node Worker, and manual SQL schema initialization. | Accepted; manifests updated 2026-08-16 | 2026-08-14 | Deployment model and schema initialization | No migration Job pod; Go bootstraps the super administrator, owns the session Secret, and receives all runtime/backend configuration. |
|
||||
|
||||
## Superseded Decisions
|
||||
|
||||
|
||||
Reference in new issue
Block a user