JK
>LADDAR // LADDAR
INITIERAR VY
Produktionsredo mikrotjänstarkitektur med NestJS, PostgreSQL och Docker samordnad via en central API Gateway.
Uppdelning av routing (API Gateway), domänlogik (oberoende tjänster) och databas för fristående driftsättning och skalning.
| Teknik | Version | Syfte | Varför vald |
|---|---|---|---|
| TypeScript | ^5.7.3 | Primary language for all services | Type safety, NestJS ecosystem standard |
| NestJS | ^11.0.1 | Application framework | Modular architecture, dependency injection, TypeScript-first |
| TypeORM | ^0.3.27 | ORM for PostgreSQL access | Active Record/Repository pattern, NestJS integration |
| PostgreSQL | 15 | Primary database | JSONB support, ACID compliance, reliability |
| Docker | — | Containerization for all services | Consistent environments, reproducible deployments |
| Turborepo | ^2.5.8 | Monorepo task orchestration | Fast parallel builds, caching, npm workspaces integration |
| GitHub Actions | — | CI/CD pipeline execution | Free for public repos, tight Git integration |
| Jest | ^30.0.0 | Unit testing framework | NestJS default, snapshot support |
| Swagger | ^11.2.0 | API documentation | Auto-generates OpenAPI from decorators |
| Metod | Rutt | Syfte |
|---|---|---|
| GET | /products | List all products |
| GET | /products/:id | Get product by ID |
| POST | /products | Create product |
| PATCH | /products/:id | Update product |
| DELETE | /products/:id | Delete product |
| GET | /orders | List all orders |
| GET | /orders/:id | Get order by ID |
| POST | /orders | Create order |
| Metod | Rutt | Syfte |
|---|---|---|
| POST | /products | Create product |
| GET | /products | List all products |
| GET | /products/:id | Get product by ID |
| PATCH | /products/:id | Update product |
| DELETE | /products/:id | Delete product |
| Metod | Rutt | Syfte |
|---|---|---|
| POST | /orders | Create order |
| GET | /orders | List all orders |
| GET | /orders/:id | Get order by ID |
| Kolumn | Typ | Anteckningar |
|---|---|---|
| idPK | SERIAL | Auto-generated primary key |
| code | VARCHAR | Product SKU/code |
| name | VARCHAR | Product display name |
| description | VARCHAR | Product description |
| price | DECIMAL | Product price |
| image | VARCHAR | Image URL |
No explicit indexes beyond primary key. No unique constraints on code.
| Kolumn | Typ | Anteckningar |
|---|---|---|
| idPK | SERIAL | Auto-generated primary key |
| customer | JSONB | Stores {name, phone} |
| products | JSONB | Array of {id, name, rate, qty} |
| totalAmount | DECIMAL | Total order amount |
Products stored as JSONB snapshot — intentional denormalization. No foreign keys to product table.
No foreign key relationships. Order.products is a JSONB snapshot — orders are self-contained records that do not reference the product table. Product price changes do not affect existing orders.
Beslut: Both services connect to the same PostgreSQL instance and database (procura_db)
Varför: Simplifies development and deployment — one database to manage
Fördelar: Simpler infrastructure, lower resource usage, easier local development
Avvägningar: Violates database-per-service principle, creates hidden coupling, makes independent scaling harder
Beslut: Order entity stores product data as JSONB rather than foreign key references
Varför: Decouples order data from product lifecycle — orders are immutable snapshots
Fördelar: Orders are self-contained, product changes don't affect historical orders
Avvägningar: No referential integrity, data duplication, no automatic product validation on order creation
Beslut: Simple static API key in x-api-key header, compared against environment variable
Varför: Simplest possible authentication for demonstration purposes
Fördelar: Minimal implementation, no token management, no state
Avvägningar: No user identity, no fine-grained permissions, key is static and shared
Beslut: API Gateway communicates with downstream services via synchronous HTTP (Axios)
Varför: Simplest approach for synchronous request-response pattern
Fördelar: Easy to understand, debug, and test; standard HTTP tooling
Avvägningar: Synchronous coupling, no retry/circuit breaker, no async processing
Beslut: Each service uses a 3-stage Dockerfile (deps → builder → runner)
Varför: Minimizes final image size and attack surface
Fördelar: Production images contain only runtime dependencies and compiled code
Avvägningar: Build time for each stage, no layer caching optimization for src changes
Beslut: Both services use synchronize: true in TypeORM config
Varför: Auto-creates/updates database schema from entities during development
Fördelar: No migration files needed, schema stays in sync with code
Avvägningar: Dangerous in production — can cause data loss on schema changes