docs: record Next and Go target architecture
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
# Proposal: Next.js Frontend And Go Backend Architecture
|
||||
|
||||
## Status
|
||||
|
||||
- Proposed by task: `20260812-go-backend-migration-6f4a92`
|
||||
- Human direction: confirmed on 2026-08-12
|
||||
- Implementation: not started
|
||||
- Canonical promotion: pending Integration Gate
|
||||
|
||||
## Decision
|
||||
|
||||
Adopt a same-origin, two-workload target architecture:
|
||||
|
||||
```text
|
||||
Browser
|
||||
|
|
||||
v
|
||||
ACK Ingress
|
||||
|-- page and static paths ----------------> Next.js frontend
|
||||
|-- /api, /uploads, /generated-results ---> Go backend
|
||||
|
||||
Next.js frontend -- internal HTTP for SSR --> Go backend
|
||||
Go backend ------> RDS PostgreSQL
|
||||
Go backend ------> Alibaba Cloud OSS
|
||||
Go backend ------> generation providers and Webhook destinations
|
||||
Go backend ------> embedded asynchronous WorkerLoop
|
||||
```
|
||||
|
||||
The initial steady state is one Next.js Pod and one Go Pod. The Go process owns the HTTP backend and the asynchronous task loop. Split the Worker into a third workload only after measured traffic, backlog, independent scaling, or failure-isolation requirements justify the additional deployment and operations cost.
|
||||
|
||||
## Module Interfaces And Seams
|
||||
|
||||
### Next.js frontend Module
|
||||
|
||||
Interface:
|
||||
|
||||
- Serves pages, static assets, and SSR output.
|
||||
- Browser calls remain same-origin and retain the current `/api/**` paths.
|
||||
- SSR forwards the incoming Cookie and request origin to the Go session/introspection interface.
|
||||
|
||||
Implementation constraints:
|
||||
|
||||
- Must not connect to RDS.
|
||||
- Must not hold provider, OSS, billing, or migration credentials.
|
||||
- Must not independently decide account status, organization status, `sessionVersion`, or authorization after the Go identity Module owns them.
|
||||
- Retaining SSR means Next.js remains a server process; it is database-free, not necessarily statically exported.
|
||||
|
||||
### Go backend Module
|
||||
|
||||
External Interface:
|
||||
|
||||
- Preserve current browser and public HTTP paths, JSON fields, status codes, Cookie behavior, idempotency rules, and tenant-not-found behavior.
|
||||
- Own health and database readiness endpoints.
|
||||
|
||||
Deep internal Modules:
|
||||
|
||||
- `Identity`: login, logout, current session, password changes, role and organization authorization.
|
||||
- `Administration`: organizations, accounts, account archival, usage administration, settings visibility, and logs.
|
||||
- `Assets`: upload, registration, list/get/delete, authenticated download, and metadata.
|
||||
- `Jobs`: submit, query, cancel, retry, claim, provider polling, terminal transitions, refunds, and Webhooks.
|
||||
- `Billing`: quotes, wallets, price rules, charges, settlements, refunds, ledger queries, and adjustments.
|
||||
- `Usage`: platform/public attribution and immutable usage recording.
|
||||
|
||||
Internal seams exist only where multiple Adapters are real:
|
||||
|
||||
- Object storage: Alibaba Cloud OSS and a local development Adapter.
|
||||
- Provider execution: Jimeng/Volcengine, EvoLink, Bailian, Seedance, and deterministic fake Adapters.
|
||||
- PostgreSQL transport: `pgx` Pool and transaction Adapter; domain callers do not learn SQL transport details.
|
||||
- Clock/ID sources only where deterministic tests require alternate Adapters.
|
||||
|
||||
Do not create one repository Interface per table or translate every TypeScript store function into a shallow Go RPC.
|
||||
|
||||
### PostgreSQL concurrency authority
|
||||
|
||||
RDS remains the source of truth for relational state and cross-instance concurrency. Go must continue calling:
|
||||
|
||||
- `claim_generation_jobs(text, integer, integer)` for `FOR UPDATE SKIP LOCKED`, lease acquisition, stale-lock recovery, priority, and schedule ordering.
|
||||
- `billing_post_wallet_entry(...)` for organization-scoped idempotency, wallet row locking, balance enforcement, and ledger insertion.
|
||||
|
||||
Do not replace either function with Go process-local locks. A Go Pod restart, multiple replicas, or a rolling update must not weaken job or wallet correctness.
|
||||
|
||||
### WorkerLoop lifecycle
|
||||
|
||||
The initial Go process embeds a context-cancelled WorkerLoop:
|
||||
|
||||
- HTTP readiness becomes healthy only when database schema and required privileges are ready.
|
||||
- WorkerLoop uses a bounded batch and provider concurrency.
|
||||
- Shutdown stops new claims, allows a bounded drain, and releases/ages leases according to the existing database contract.
|
||||
- Horizontal Go scaling also scales WorkerLoop concurrency and database/provider load. Until that coupling is acceptable, keep the Go Deployment replica count explicit.
|
||||
|
||||
## Authentication Compatibility Contract
|
||||
|
||||
The existing `zhinian_session` contract is part of the migration Interface, not an implementation detail:
|
||||
|
||||
- HMAC-SHA256 over base64url JSON payload.
|
||||
- Value format: `payload.signature`.
|
||||
- Cookie chunk size 3000 characters; names `zhinian_session`, `.1`, `.2`, up to 20 chunks.
|
||||
- Payload version 1, `authMode`, expiry, user/client identity, and `sessionVersion` validation.
|
||||
- `HttpOnly`, `SameSite=Lax`, `Path=/`, production `Secure`, and complete chunk clearing on logout.
|
||||
- Each authenticated request revalidates active user, `sessionVersion`, organization state, and role constraints in PostgreSQL.
|
||||
|
||||
Go may parse the existing Cookie to avoid a forced logout. If an implementation deliberately changes the format, the release plan must explicitly announce and test a one-time global re-login.
|
||||
|
||||
## Storage Contract
|
||||
|
||||
Production generated and uploaded assets must use shared object storage before either workload scales horizontally. The current local runtime directory is acceptable only for explicit development or a documented single-Pod fallback.
|
||||
|
||||
The migration should move toward private OSS objects with authenticated or presigned access. Until that is implemented, preserve current URL/storage-path/delete behavior and document the existing `public-read` exposure.
|
||||
|
||||
## Deployment And Secret Ownership
|
||||
|
||||
| Workload | Owns |
|
||||
|---|---|
|
||||
| Next.js | public origin and internal Go base URL; no business Secret |
|
||||
| Go backend | application RDS URL/CA, session Secret, provider keys, OSS credentials, Webhook Secret, public API keys |
|
||||
| Migration Job | separate DDL-capable RDS URL/CA and application role name |
|
||||
|
||||
Ingress routes must explicitly send `/api`, `/uploads`, and `/generated-results` to Go and all page/static paths to Next. The internal Worker tick endpoint and Node Worker Deployment disappear only when the Go WorkerLoop is complete and verified.
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
Although the target is approved as a complete architecture, implementation should remain reversible:
|
||||
|
||||
1. Freeze executable golden contracts for HTTP, Cookie, authorization, database functions, task state, billing, and Webhooks.
|
||||
2. Implement Go health/readiness, configuration, PostgreSQL, and identity foundations.
|
||||
3. Migrate vertical slices behind exact path routing. Only side-effect-free reads may be shadowed.
|
||||
4. Keep exactly one owner for every write path; never dual-write jobs, wallets, OSS objects, login counters, Provider operations, or Webhooks.
|
||||
5. Use expand/contract database changes so the previous release remains deployable during the rollback window.
|
||||
6. Stop and drain the Node Worker, account for provider tasks and existing leases, then enable Go WorkerLoop.
|
||||
7. Remove Next Route Handlers, RDS/provider/OSS Secrets, and Node Worker only after parity tests pass.
|
||||
|
||||
## Required Acceptance Tests
|
||||
|
||||
- Cookie creation/parsing/chunking/tamper/expiry/logout and optional no-logout cross-language compatibility.
|
||||
- Concurrent failed login lockout and concurrent password change.
|
||||
- Cross-user, cross-organization, role, public-client, and 401/403/404 authorization matrix.
|
||||
- Job idempotency, database claim uniqueness, stale lease recovery, retry scheduling, cancellation, and terminal transitions.
|
||||
- Wallet idempotency, concurrent charge/no-overdraft, refund and settlement replay, and organization ledger reconciliation.
|
||||
- Provider recovery around external acceptance versus `provider_task_id` persistence.
|
||||
- Webhook byte/HMAC contract, attempt limits, persisted status, and restart behavior.
|
||||
- OSS upload/download/delete/content-type and URL/storage-path compatibility.
|
||||
- Versioned migration checksum/lock/role privileges and readiness failure for missing schema or grants.
|
||||
- Next SSR without RDS credentials, same-origin browser behavior, ACK manifests, image builds, and controlled rollout/rollback.
|
||||
|
||||
## Consequences
|
||||
|
||||
Benefits:
|
||||
|
||||
- Clear ownership and Secret isolation.
|
||||
- Back-end lifecycle and scaling no longer tied to Next.js upgrades.
|
||||
- Removal of the fragile HTTP polling Worker seam.
|
||||
- Go domain logic can be tested through stable Module Interfaces.
|
||||
|
||||
Costs and risks:
|
||||
|
||||
- Large behavior-compatible rewrite across two languages and build systems.
|
||||
- Contract generation/versioning and distributed tracing become required maintenance.
|
||||
- Authentication, tenant isolation, task recovery, wallet correctness, storage, and Webhooks are high-risk parity areas.
|
||||
- An embedded WorkerLoop couples API replica count with task/provider concurrency until deliberately split.
|
||||
|
||||
## Relationship To Existing Decisions
|
||||
|
||||
- Retains `RDS-001`: production PostgreSQL is explicit and fail-closed.
|
||||
- Retains `RDS-002`: schema changes remain versioned, checksummed, advisory-locked one-shot migrations.
|
||||
- Supersedes `ACK-001` only after implementation: Go, rather than Next Web, owns database access and asynchronous execution; the separate HTTP-polling Node Worker is removed.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Task: Migrate Next backend to Go and prepare main integration
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260812-go-backend-migration-6f4a92
|
||||
- Mode: Feature
|
||||
- Branch: codex/20260812-go-backend-migration-6f4a92-go-backend-migration
|
||||
- Worktree: D:\Datas\OthersProjects\NianAIGC-go-backend-6f4a92
|
||||
- Base commit: a235266bed8f1a7e19518cdd3aa5ed3e0a309b82
|
||||
- Owner: codex
|
||||
- Status: Ready for Integration
|
||||
|
||||
## Scope
|
||||
|
||||
- Record the user-approved Next.js frontend plus Go modular-monolith target architecture.
|
||||
- Capture the current implementation status and the required migration, compatibility, deployment, and verification contracts.
|
||||
- Merge design and progress documentation into `main` through the serialized Integration Gate.
|
||||
- Do not implement or merge Go/application/deployment code in this task.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- The user initially requested a one-step complete migration, then explicitly superseded that instruction: do not implement code; merge only design documentation and progress records.
|
||||
- Preserve current `/api/**`, file-route, JSON/status, session-cookie, multi-tenant, idempotency, billing, and task-state behavior unless a source defect prevents safe preservation.
|
||||
- Production remains explicit PostgreSQL/RDS and fail-closed; keep versioned checksummed migrations and the `claim_generation_jobs` and `billing_post_wallet_entry` database functions.
|
||||
- Use one same-origin Ingress: pages route to Next.js and API/file paths route to Go. Go embeds the worker loop initially so steady state remains two long-lived Pods.
|
||||
- Do not double-write or run the old Node worker beside the Go worker in the final deployment.
|
||||
- Preserve the occupied `main` worktree and its unrelated untracked task record during documentation integration.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Completed a task-scoped architecture proposal covering target workloads, deep Modules, Interfaces and seams, PostgreSQL concurrency, authentication compatibility, storage, Secret ownership, migration sequencing, acceptance tests, and consequences.
|
||||
- Recorded that implementation has not started: current `main` remains Next.js full-stack plus the Node HTTP-polling Worker under accepted decision `ACK-001`.
|
||||
- Six implementation sub-agents were started after the earlier request, then immediately interrupted when the user changed scope. All resulting Go, Docker, Compose, and deployment drafts were removed from the isolated worktree and will not be merged.
|
||||
- No application source, SQL, Docker, ACK manifest, package, or runtime configuration change remains in the task branch.
|
||||
|
||||
## Verification
|
||||
|
||||
- Concurrent Task Gate and Planning Gate passed in isolated worktree `D:\Datas\OthersProjects\NianAIGC-go-backend-6f4a92` at base `a235266`.
|
||||
- Rechecked the current API routes, server/auth/provider modules, PostgreSQL schema/functions, ACK decisions, and peer architecture/configuration task records before writing the proposal.
|
||||
- Confirmed with `git status` and `git diff` that code drafts were removed and only task-owned project documentation remains before integration.
|
||||
- Application tests were not run because application code was not changed.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Implementation remains a future task. It should start from executable HTTP/Cookie/authorization/job/billing/storage contracts rather than from deleted drafts.
|
||||
- Live RDS TLS/roles, OSS/provider calls, Docker daemon execution, and ACK rollout remain unverified.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- Target: accepted architecture decision and canonical architecture documents.
|
||||
Proposal: supersede ACK-001 with a same-origin Next.js frontend plus Go modular-monolith backend, with Go owning RDS and the embedded worker loop.
|
||||
Evidence: user-confirmed architecture task `20260812-next-go-architecture-4d81e2` and task-scoped proposal `20260812-go-backend-migration-6f4a92__next-go-architecture.md`.
|
||||
Future impact: changes module ownership, secrets, deployment topology, health/readiness, worker lifecycle, and feature development language.
|
||||
Semantic conflicts: supersedes ACK-001; must retain RDS-001 and RDS-002.
|
||||
Human confirmation required: already received from the user; promotion still requires Integration Gate validation.
|
||||
Reference in New Issue
Block a user