Repository navigation
Code Server
Go module quizzivy: a modular monolith. One process, one database, eleven
bounded contexts that talk to each other only through the ports they declare.
The decision record is docs/plan/60-backend-architecture.md; this file is the
map.
server/
cmd/ entry points only: api (the server), import-worker, maintenance, migrate,
seedadmin, and the Word tools (word-convert, word-extract, word-inspect,
word-recognize, verify-import-storage)
internal/
core/ the composition root: wiring/ builds each module, router/ fronts them,
adapters/ bridge ports, jobs/ run background commands, maintenance/ holds
the operator's commands cmd/maintenance runs
platform/ technical adapters: config, db (pgx; the Context and Repository every module embeds),
storage (S3), google (OIDC), probe (audio), httpx (middleware), httpserver,
ratelimit, httpapi (transport helpers), apidocs (Scalar)
shared/ the kernel every layer may use: cqrs (handler contracts), actor, paging, audit,
stats, opt, validation, content (versioned learner content), access (the
permission model: keys, requirements, the principal and its scope),
visibility (who a teacher reaches)
modules/ the bounded contexts
identity/ User aggregate, sessions, the teacher's roster of students, PasswordManager
classes/ Class aggregate, members, join codes (JoinCodeManager, CodeState, JoinCodeKeys)
questions/ Question aggregate with options and blanks, QuestionManager
media/ Asset aggregate in object storage, AssetManager
tests/ Test aggregate, drafts and published versions, PublishManager
assignments/ Assignment aggregate, policies, ScheduleManager
attempts/ Attempt aggregate: the deal, answers, grading, review, monitor, timeline
dashboard/ read models for the teacher's home (no aggregate)
imports/ Word and PDF imports: private sources, processing runs, the review draft, the commit
availability/ the maintenance windows the operator schedules, as the API reads them
access/ roles and their grants, PermissionManager, the cached principal (no transport until R5)
tests/ end-to-end: the whole application in-process, over HTTP
gen/openapi/ generated from api/openapi.yaml, committed, never hand-edited
| layer | holds | may import |
|---|---|---|
domain/ |
aggregate root, entities, value objects, commands, errors, the repository interface, and the managers — the domain's rules that belong to no single entity |
shared, other modules' domain
|
application/ |
the use cases as commands and queries: command/ and query/ hold one struct and one handler per use case, ports/ what the module needs from outside, model/ the results other modules read, internal/support/ what the handlers share; app.go builds Application{Commands, Queries}
|
own domain, other modules' domain and application, shared
|
repositories/ |
Postgres, implementing the domain interface; SQL lives here and nowhere else | own domain, platform, shared
|
http/ |
the operations this module serves, embedded into core's composite strict server; presenters other transports reuse | own domain/application, platform/httpx, platform/httpapi, gen/openapi, other modules' domain, application and http
|
core/tests/architecture_test.go fails the build on any import in the wrong
direction. Managers are reached as package values (domain.Grading.Grade,
domain.JoinCodes.Normalize); applications are constructed by core/wiring
with their repository and ports, and a transport reaches a use case as
h.app.Commands.Create.Handle(ctx, command.Create{…}) or
h.app.Queries.Get.Handle(ctx, query.Get{…}). A port another module fills with
one operation is typed as that module's handler (identity's SelfEnroller is
the classes EnrolNewMember command; the attempts transport's Students is the
identity StudentAccount query).
Three tiers, three build tags, one directory convention: a layer's tests live
in <layer>/tests/ as an external package and use only what the layer
exports. A test that needs a private function is a test of the wrong thing.
| tier | tag | where | needs | runs with |
|---|---|---|---|---|
| unit | none | <layer>/tests/ |
nothing | make test-api-unit |
| integration | integration |
repositories/tests/, application/tests/
|
TEST_DATABASE_URL |
make test-api-integration |
| end-to-end | e2e |
server/tests/ |
TEST_DATABASE_URL, and MinIO (make up) for the isolation suite |
make test-api-e2e |
make test-api runs all three in that order; CI runs them as three steps.
The server serves its own Scalar reference at /docs, loading the contract it
was built from at /docs/openapi.json. The page is platform/apidocs; no
package wraps it, and the Scalar version is pinned there beside its SRI hash.
Both routes are admin only (spec §5.5): open them from the web app's
Settings → Preferences → "Tài liệu API", which mints a fifteen-minute docs
cookie. For local development, DOCS_PUBLIC=true in .env skips that check;
the server refuses it in production.
Generated from server/README.md. Edit that file in the repository; changes made on this page are overwritten.
Generated from the repository's documentation on every push to develop.
Start here
Product
Implementation plan
- 00 Architecture overview
- 10 Phase 0: Scaffold and contract
- 11 Phase 1: Auth, join, shells
- 12 Phase 2: Admin authoring
- 13 Phase 3: Assign and take
- 14 Phase 4: Grade and results
- 15 Phase 5: Hardening
- 16 Phase 4.5: The student at a desk
- 17 Word import: milestone plan
- 18 Word import: teacher workflow
- 19 Versioned content contract
- 20 Data model
- 30 Risk register
- 40 Open items
- 50 Non-functional requirements
- 60 Backend architecture
- 91 September 2026 issue remediation
- 92 Student layouts and interaction rules
Redesign (Phase R)
- 70 Redesign overview
- 71 R1: Foundations (v0.7.0)
- 72 R2: Access (v0.8.0)
- 73 R3: Student console (v0.9.0)
- 74 R4: Teacher workspace (v0.10.0)
- 74d D4: Deck update (v0.11.0)
- 74e E1: Moving a question across a group
- 75 R5: Admin console and email (v0.12.0)
- 76 R6: Question types and scoring (v0.13.0)
- 77 R7: Collaboration (v0.14.0)
- 78 R8: Schedule (v0.15.0)
- 79 R9: Insights (v0.16.0)
- 80 R10: Learn (v0.17.0)
- 81 R11: Landing, leads, v1.0 (v1.0.0)
Setup and operations
- CI
- Deploying
- DNS for quizzivy.com
- Google OAuth client
- Production operations
- Cloudflare R2 bucket
- Word import worker
- R4 rehearsal on a Neon branch
Design
Team
- Agent team
- Verification environment
- Team ledger
- R4 readiness
- R4 verification strategy
- T-R4.51 browser verification
Code READMEs