Skip to content

Directory Architecture

The Whole Workspace

The workspace root itself is not a git repository; it holds four independent repositories plus design documents.

design/
โ”œโ”€โ”€ heineken-survey-design-backend/    # API server (Hono + Bun + Drizzle / PostgreSQL)
โ”œโ”€โ”€ heineken-survey-design-frontend/   # Web UI (Next.js 15 App Router)
โ”œโ”€โ”€ Lab-web-extension/                 # Chrome extension (Plasmo)
โ”œโ”€โ”€ heineken-survey-design-docs/       # This documentation (MkDocs Material)
โ”œโ”€โ”€ integration-tests/                 # Playwright integration tests against dev
โ”œโ”€โ”€ cs-api-logs/                       # Real API traffic from the CS editing screen
โ””โ”€โ”€ *.md                               # Implementation plans and CS gap analysis
Directory Description
heineken-survey-design-backend/ REST API running on AWS Lambda as a container image
heineken-survey-design-frontend/ The Web UI operated by survey designers
Lab-web-extension/ The Chrome extension that pushes into and imports from Creative Survey
heineken-survey-design-docs/ This documentation site
integration-tests/ Playwright tests against the dev environment (an independent directory)
cs-api-logs/ Real logs collected to reverse-engineer the CS API

Design Documents at the Root

File Contents
branch-logic-current-state-and-cs-diff.md Current state of branching and the gap against CS; findings from real traffic
branch-cs-parity-implementation-plan.md The CS parity implementation plan and its phases
free-text-multi-fields-implementation-plan.md Implementation plan for multiple FA input fields
text-matrix-implementation-plan.md Implementation plan for the text matrix configuration UI
cs-api-log-collection-guide.md Procedure for collecting real CS logs
cs-import-test-cases.md Test cases for pushing into CS (the CP / I / R checklists)

backend

heineken-survey-design-backend/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ index.ts                  # Entry point for local startup
โ”‚   โ”œโ”€โ”€ lambda.ts                 # Entry point for AWS Lambda
โ”‚   โ”œโ”€โ”€ migrate-handler.ts        # Entry point for the migration Lambda
โ”‚   โ”œโ”€โ”€ app.ts                    # createApp(): auth middleware and router registration
โ”‚   โ”œโ”€โ”€ routes/                   # Route definitions and handlers
โ”‚   โ”œโ”€โ”€ repositories/             # Data access layer (permissions, transactions)
โ”‚   โ”œโ”€โ”€ db/                       # Drizzle schema, types, connection
โ”‚   โ”œโ”€โ”€ lib/                      # Auth, OpenAPI schemas, shared helpers
โ”‚   โ”œโ”€โ”€ types/                    # Domain types
โ”‚   โ”œโ”€โ”€ scripts/                  # OpenAPI export, migrations, seed
โ”‚   โ””โ”€โ”€ test/                     # Test helpers
โ”œโ”€โ”€ drizzle/                      # Generated migration SQL
โ”œโ”€โ”€ openapi.json                  # Exported OpenAPI document
โ”œโ”€โ”€ Dockerfile                    # Container image for the API Lambda
โ””โ”€โ”€ Dockerfile.migration          # Container image for the migration Lambda
Directory Description
src/routes/ Route definitions per resource: surveys / sections / questions / versions / permissions / question-library / users / imports
src/repositories/ survey-store.ts (everything around surveys) and import-store.ts (external imports). DB access and permission checks live here
src/db/ schema.ts (the source of truth for the DB), models.ts (inferred types), client.ts (connection)
src/lib/ auth.ts (user resolution, admin checks), openapi-schemas.ts (Zod schemas), openapi.ts, renumber-questions.ts (question-code renumbering, a pure function)
src/types/domain.ts Domain types shared between the API and the application

Tests live next to their target as *.test.ts (e.g. src/app.test.ts).

frontend

No src/; app/, components/, and lib/ sit at the repository root.

heineken-survey-design-frontend/
โ”œโ”€โ”€ app/                          # App Router
โ”‚   โ”œโ”€โ”€ login/                    # Login
โ”‚   โ”œโ”€โ”€ surveys/                  # List, create, detail, sections, preview
โ”‚   โ”œโ”€โ”€ library/                  # Question library
โ”‚   โ””โ”€โ”€ api/auth/[...nextauth]/   # next-auth handler
โ”œโ”€โ”€ components/
โ”‚   โ”œโ”€โ”€ app-shell/                # Shared shell with sidebar and header
โ”‚   โ”œโ”€โ”€ common/                   # Generic UI (buttons, badges, dialogs, โ€ฆ)
โ”‚   โ”œโ”€โ”€ providers/                # Auth and TanStack Query providers
โ”‚   โ”œโ”€โ”€ surveys/                  # Survey, section, question, and preview screens
โ”‚   โ””โ”€โ”€ library/                  # Question library screen
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ api/                      # API client generated by orval (do not edit)
โ”‚   โ”œโ”€โ”€ orval/client.ts           # customFetch (attaches shared headers)
โ”‚   โ”œโ”€โ”€ surveys/                  # Domain logic such as branch evaluation and validation
โ”‚   โ””โ”€โ”€ format/                   # Utilities such as date formatting
โ”œโ”€โ”€ styles/                       # Shared SCSS
โ”œโ”€โ”€ types/                        # Shared types
โ”œโ”€โ”€ scripts/                      # OpenAPI normalization, orval patch, husky setup
โ”œโ”€โ”€ _templates/                   # hygen component scaffolding
โ”œโ”€โ”€ middleware.ts                 # Auth protection for /surveys/* and /library/*
โ””โ”€โ”€ Dockerfile                    # Container image for App Runner
Directory Description
app/ Routing. page.tsx (server) and page-client.tsx (client) are placed as pairs
components/ One component per directory: index.tsx + index.module.scss
lib/surveys/ Domain logic independent of the UI: branch evaluation, validation, custom hooks
lib/api/ orval output. Do not edit

Screens and Their Implementations

Screen Path Implementation
Login /login components/auth/login-page-client/
Survey list /surveys components/surveys/surveys-page-client/
Create /surveys/new components/surveys/new-survey-client/, survey-theme-form/
Survey detail /surveys/[id] components/surveys/survey-detail-client/, survey-permission-panel/, survey-version-panel/
Section list /surveys/[id]/sections components/surveys/section-list-client/
Section detail /surveys/[id]/sections/[sectionId] components/surveys/section-detail-client/
Preview /surveys/[id]/preview components/surveys/survey-preview/
Question library /library components/library/question-library-page-client/

Chrome Extension

Lab-web-extension/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ background.ts                       # Background script
โ”‚   โ”œโ”€โ”€ popup/                              # Extension popup UI
โ”‚   โ”œโ”€โ”€ contents/
โ”‚   โ”‚   โ”œโ”€โ”€ creative-survey-overlay.tsx     # Operation panel overlaid on the CS screen
โ”‚   โ”‚   โ””โ”€โ”€ cs-api-logger.ts                # Records CS API traffic
โ”‚   โ”œโ”€โ”€ components/creative-survey/         # Push UI and API log panel
โ”‚   โ”œโ”€โ”€ providers/                          # Theme / SurveyUploader providers
โ”‚   โ”œโ”€โ”€ types/                              # Types for the CS API and the design tool JSON
โ”‚   โ””โ”€โ”€ utils/creative-survey/
โ”‚       โ”œโ”€โ”€ api.ts                          # CS API client
โ”‚       โ”œโ”€โ”€ constants.ts                    # answer_type and API URL
โ”‚       โ”œโ”€โ”€ plan/build-import-plan.ts       # Exported JSON โ†’ CS push plan (pure functions)
โ”‚       โ”œโ”€โ”€ execute-import-plan.ts           # Calls the CS API following the plan
โ”‚       โ””โ”€โ”€ reset-survey.ts                 # Resets a questionnaire on the CS side
โ””โ”€โ”€ cs-import-test-cases.md                 # Test cases for pushing into CS

Pushing into CS separates conversion (building the plan) from execution (calling the API). Because the conversion is a pure function, it can be tested exhaustively with Vitest without calling the CS API.

flowchart LR
    Json[Questionnaire JSON] --> Build[build-import-plan.ts<br/>pure functions]
    Build --> Plan[Push plan]
    Plan --> Exec[execute-import-plan.ts]
    Exec --> CS[(Creative Survey API)]

integration-tests

integration-tests/
โ”œโ”€โ”€ config.ts                     # dev URLs and the API account
โ”œโ”€โ”€ playwright.config.ts          # Playwright config (workers: 1, headless: false)
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ 00-smoke.spec.ts          # Connectivity check against dev
โ”‚   โ”œโ”€โ”€ 01-build-survey.spec.ts   # Survey construction (CP1โ€“CP13)
โ”‚   โ””โ”€โ”€ 02-preview-run.spec.ts    # Preview runs (R1โ€“R28)
โ”œโ”€โ”€ pages/                        # Screen operations (question editor / branch / visibility / preview)
โ”œโ”€โ”€ lib/                          # dev API calls, run logic, wait helpers
โ”œโ”€โ”€ fixtures/scenario.ts          # Definition of the question table (Q1โ€“Q13)
โ””โ”€โ”€ scripts/                      # Saving auth state, cleanup, CS log comparison

docs (this site)

heineken-survey-design-docs/
โ”œโ”€โ”€ mkdocs.yml                    # Site configuration, navigation, i18n
โ”œโ”€โ”€ pyproject.toml                # MkDocs dependencies (managed by uv)
โ””โ”€โ”€ docs/
    โ”œโ”€โ”€ home.{ja,en}.md
    โ”œโ”€โ”€ link.{ja,en}.md
    โ”œโ”€โ”€ business-domain/          # Product, actors, features, data model
    โ””โ”€โ”€ development/              # Setup, API, DB, infrastructure, conventions

Japanese pages are *.ja.md and English pages are *.en.md, placed in the same directory (the suffix scheme of mkdocs-static-i18n).

Where to Put New Files

What you are adding Where it goes
An API endpoint backend src/routes/<resource>.ts (register it in src/app.ts for a new resource)
DB access backend src/repositories/survey-store.ts (import-store.ts for external imports)
A table definition backend src/db/schema.ts, then bun run db:generate
Request / response schemas backend src/lib/openapi-schemas.ts
Domain types backend src/types/domain.ts
A screen frontend app/<path>/page.tsx + page-client.tsx, with the body in components/<domain>/
A generic UI component frontend components/common/ (scaffold with bun run new:common)
A screen-specific component frontend components/<domain>/ (bun run new:component)
Logic independent of the UI frontend lib/surveys/ as a pure function, tested with Vitest
CS conversion logic extension src/utils/creative-survey/plan/build-import-plan.ts plus its .test.ts
An integration test scenario integration-tests/tests/ and fixtures/scenario.ts