Technology Stack

Transactional email uses Resend's HTTPS POST /emails API through Node 24 native fetch, with a fixed production destination and no SDK or SMTP client. HTTPS avoids the SMTP port restrictions of the anticipated hosting class and keeps the adapter small. The application receives only stable delivery categories. See ADR 003 for provider prerequisites.

Authentication uses maintained Fastify plugins (@fastify/cookie, @fastify/session, @fastify/csrf-protection, and @fastify/rate-limit). The session store is the project's own PostgreSQL adapter rather than the plugin memory default. Passwords use the native argon2 package with Argon2id; the production Node 24 Alpine image is the compatibility target.

1. Scope and version sources

This document records technology choices and their rationale for the implemented system. Architecture belongs in architecture.md, commands in development.md, test policy in test-strategy.md, and progress in current-state.md. Future product ideas are not implementation requirements.

The root package.json requires Node.js 24.x and declares pnpm 10.34.5. GitHub Actions selects Node major 24; application Docker images use node:24-alpine. These select a major/tag, not an immutable Node patch or image digest. Workspace manifests declare dependency ranges; pnpm-lock.yaml records exact resolutions. Use pnpm install --frozen-lockfile to reproduce them. Do not copy changing package versions into a second authoritative inventory.

2. Implemented application choices

3. Repository and architectural boundaries

The pnpm workspaces are:

Directory Package
frontend/ @foodtruck-order/frontend
backend/ @foodtruck-order/backend
packages/db/ @foodtruck-order/db
tests/e2e/ @foodtruck-order/e2e

The repository uses these directories, not an apps/web, apps/api, or infra/ layout. docker/ contains the local gateway; .github/workflows/ contains CI and publishing. There is no shared frontend/backend domain package, Nx, or Turborepo. The backend depends on @foodtruck-order/db; frontend types mirror the public API without importing backend implementation code.

4. Testing and static quality tools

The canonical static gate is pnpm quality; it includes documentation checks. The authoritative DoD enforcement mapping is CI §14.

5. Containers and CI

Docker Compose supplies the canonical local application environment. Backend images use Node; frontend and gateway images use nginx:1.29-alpine. The gateway serves the page and /api/* on the same browser origin. Database tooling runs in separate migration/seed containers. The local gateway uses HTTP, not HTTPS/Caddy.

GitHub Actions runs the mandatory quality, tests, builds, docs, Docker, coverage, supply-chain, and artifact checks. The staging migration gate and existing hosting assumptions are documented in CI §13. The repository does not publish application Docker images to a registry.

Supply-chain tooling is pinned and local-first: pnpm audit (lockfile; high/critical blocking with narrow expiring entries in supply-chain/audit-exceptions.json), Gitleaks v8.18.4 (zricethezav/gitleaks:v8.18.4), Hadolint v2.12.0 (hadolint/hadolint:v2.12.0), Trivy 0.66.0 (aquasec/trivy:0.66.0) for weekly diagnostics only, and the project's own drizzle-kit migration generator. Scanner wrappers live in scripts/ with fixture tests under tests/ci/; no secrets are required and secret findings stay redacted.

When a transitive dependency range has not yet adopted a patched compatible release, keep the temporary resolver override in the root package.json and remove it after upstream ranges include the fix. The blocking audit remains the source of truth for whether the override is still needed.

6. Documentation tools

OpenAPI 3.1 is the version-controlled HTTP contract in docs/api/openapi.yaml. Redocly validates it, Swagger UI renders it, and TypeDoc generates the intentional public TypeScript reference. A small Node script with marked renders Markdown; there is no separate documentation framework. Marked also supplies the Markdown token/heading model for offline local-link checks; Cheerio 1.2.0 parses generated HTML for site links and fragments. CSpell 9.6.1, with pinned Swedish 2.3.2 and Hungarian 1.1.2 dictionaries, checks scoped authored prose, comments, and UI copy. ESLint's maintained no-restricted-imports/no-restricted-globals rules enforce the repository's narrow architectural boundary baseline without a second dependency parser.

The complete site is generated into ignored docs-site/. Cloudflare Pages hosts a Direct Upload project; a separate Actions workflow invokes the pinned wrangler 4.131.1 with pnpm dlx. GitHub hosts source and executes builds; Cloudflare does not clone or build the repository. GitHub Pages is not used. Tool boundaries and documentation coverage live in documentation.md.

7. Deferred choices and product direction

The implemented application contains a database-backed message, authentication/account recovery, the protected product catalog, and atomic non-commercial order finalization with immutable item snapshots. Product deletion removes a product from the current catalog without changing finalized snapshots. Commercial checkout finalization, order history presentation, payment/POS integrations, real-time updates, backups, and production infrastructure are not implemented. Do not infer them from later MVP specifications or historical plans.

If later specifications require them, the existing direction is:

Future scope and acceptance criteria must be established in specifications before implementation. The developer log preserves informal proposals without changing these technology decisions.