Technology Stack¶
This page records the implementation technology decided in the architecture workshop (2026-06-11). The structural choices are justified in ADR-007 through ADR-011; this page is the practical reference for building the services. Each individual technology is explained in depth in the Technologies section.
1. Topology¶
All seven services from the decomposition deploy independently from the start (ADR-007). The fleet is polyglot by fit (ADR-008): Go where proxying, resilience and event throughput dominate; TypeScript where auth tooling, fast-iterating rules and query-shaped work dominate.
2. Stack by service¶
| Service | Language | Why this language |
|---|---|---|
api-gateway |
Go | Reverse proxy performance, tiny static image, hand-built per Part II §6 — routing, Keycloak token validation, Visitor-ID handling, rate limiting, brand-scope enforcement and the SLO-1 latency histogram are the deliverable. |
passport-service |
Go | I/O-heavy ACL toward Open Food Facts/Agribalyse: circuit breakers, caching and progressive assembly (QAS-1/QAS-2). |
fridge-service |
Go | Event-sourcing fold over the append-only stream; explicit state machines read well in Go. |
measurement-pipeline |
Go | Kafka consumer throughput and windowed aggregation before the privacy wall. |
identity-service |
TypeScript | Visitor identities, linking, consent ledger, Brand — sits next to Keycloak; Node's session/web tooling fits. |
personalization-service ★ |
TypeScript | Versioned rule policies iterate fast; verdict types stay close to the SPA's language. |
brand-analytics-service |
TypeScript | CQRS read models and dashboard-shaped queries. |
Go services¶
| Concern | Choice |
|---|---|
| HTTP routing | chi — stdlib-compatible router, middleware for auth/logging/metrics |
| Postgres access | pgx + sqlc — hand-written SQL compiled to type-safe Go |
| Migrations | golang-migrate, per service schema |
| Kafka client | franz-go |
| Testing | stdlib testing + testify |
TypeScript services¶
| Concern | Choice |
|---|---|
| HTTP framework | Fastify — schema-validated routes (JSON Schema, same tech as the event contracts) |
| Postgres access | Kysely over pg — type-safe SQL, the TS analogue of sqlc |
| Kafka client | @confluentinc/kafka-javascript — maintained librdkafka client |
| Testing | Vitest |
Shared infrastructure¶
| Concern | Choice |
|---|---|
| Database | One PostgreSQL instance, six schemas (passport, personalization, fridge, identity, measurement, brand_analytics), six GRANT-restricted roles — isolation enforced by the database (ADR-009) |
| Messaging | Apache Kafka, KRaft mode, single node — asynchronous domain facts only; synchronous calls stay internal REST (ADR-010) |
| Auth | Keycloak (OIDC) — gateway validates tokens (ADR-011) |
| Event contracts | Versioned JSON Schemas in contracts/ (envelope + payloads only), code generated for Go and TS; consumers tolerate unknown optional fields |
| Observability | Prometheus metrics + /health (liveness/readiness) per service (Part II §7) |
| Frontend | The existing SvelteKit static SPA (client/web-app), served behind the gateway, calling /api/v1 |
3. Service code structure¶
Every service uses the same hexagonal layout, so the domain never depends on HTTP, Postgres or Kafka:
services/<name>/
├── cmd/server/ # Go entry point (TS: src/server.ts)
├── internal/ # TS: src/
│ ├── domain/ # entities, value objects, policies
│ ├── application/ # use cases and ports
│ ├── adapters/
│ │ ├── http/
│ │ ├── postgres/
│ │ └── kafka/
│ └── config/
├── migrations/
├── queries/ + sqlc.yaml # Go services only
├── go.mod / package.json
└── Dockerfile
4. Repository layout¶
packytrace/
├── client/web-app/ # SvelteKit SPA (existing)
├── contracts/ # JSON Schemas + Go/TS codegen config
├── services/
│ ├── api-gateway/
│ ├── passport-service/
│ ├── personalization-service/
│ ├── fridge-service/
│ ├── identity-service/
│ ├── measurement-pipeline/
│ └── brand-analytics-service/
├── deployment/
│ ├── docker-compose.yml # services + Postgres + Kafka + Keycloak
│ └── k8s/ # Part III
├── go.work # spans the Go modules
└── docs/
5. Local development¶
One command brings up the full system:
docker compose -f deployment/docker-compose.yml up
That starts Postgres (with the six schemas and roles provisioned by migration),
Kafka, Keycloak, and all seven services. The SPA runs against the gateway with
npm run dev inside client/web-app during frontend work.