46 lines
4.6 KiB
Markdown
46 lines
4.6 KiB
Markdown
# Architecture Decision Records
|
|
|
|
Each file records one decision that was expensive to make and would be expensive to reverse.
|
|
The purpose is not documentation for its own sake — it is so that in a year, when someone asks
|
|
"why is money an integer?" or "why doesn't the admin just query the database?", the answer is
|
|
written down along with what was rejected and why.
|
|
|
|
An ADR is immutable once accepted. If a decision changes, add a new ADR that supersedes it.
|
|
|
|
| ADR | Decision | Status |
|
|
| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -------- |
|
|
| [0001](./0001-monorepo-with-pnpm-workspaces-and-turborepo.md) | Monorepo with pnpm workspaces and Turborepo | Accepted |
|
|
| [0002](./0002-modular-monolith-not-microservices.md) | Modular monolith, not microservices | Accepted |
|
|
| [0003](./0003-product-and-productvariant-as-separate-entities.md) | Product and ProductVariant as separate entities | Accepted |
|
|
| [0004](./0004-the-admin-dashboard-has-no-database-access.md) | The admin dashboard has no database access | Accepted |
|
|
| [0005](./0005-uri-based-api-versioning.md) | URI-based API versioning | Accepted |
|
|
| [0006](./0006-zod-schemas-shared-between-api-and-frontends.md) | Zod schemas shared between API and frontends | Accepted |
|
|
| [0007](./0007-rbac-permissions-instead-of-role-checks.md) | RBAC permissions instead of role checks | Accepted |
|
|
| [0008](./0008-short-access-tokens-rotating-refresh-tokens-separate-audiences.md) | Short access tokens, rotating refresh tokens, separate audiences | Accepted |
|
|
| [0009](./0009-media-in-s3-compatible-storage-metadata-in-postgresql.md) | Media in S3-compatible storage, metadata in PostgreSQL | Accepted |
|
|
| [0010](./0010-redis-is-a-cache-and-an-ephemeral-store-never-a-system-of-record.md) | Redis is a cache and an ephemeral store, never a system of record | Accepted |
|
|
| [0011](./0011-money-as-integer-minor-units.md) | Money as integer minor units | Accepted |
|
|
| [0012](./0012-postgresql-full-text-search-before-a-dedicated-search-engine.md) | PostgreSQL full-text search before a dedicated search engine | Accepted |
|
|
| [0013](./0013-content-translations-in-typed-tables-ui-strings-in-message-catalogs.md) | Content translations in typed tables, UI strings in message catalogs | Accepted |
|
|
| [0014](./0014-denormalised-price-projection-on-product.md) | A denormalised price/stock projection on Product | Accepted |
|
|
| [0015](./0015-frontends-reach-the-api-through-their-own-origin.md) | Frontends reach the API through their own origin | Accepted |
|
|
| [0016](./0016-option-values-are-retained-when-variants-reference-them.md) | Option values are retained when variants reference them | Accepted |
|
|
| [0017](./0017-shadcn-for-infrastructure-hand-built-for-brand.md) | shadcn/ui for infrastructure, hand-built for brand | Accepted |
|
|
|
|
## Decisions deliberately NOT recorded yet
|
|
|
|
These are open and should become ADRs when the need is real, not before:
|
|
|
|
- Payment provider abstraction shape (VNPay / MoMo / ZaloPay / COD) — write it when the second
|
|
provider is integrated, not the first. One provider does not reveal the right abstraction.
|
|
- Whether a third locale ever ships, and whether localised _pathnames_
|
|
(`/vi/san-pham/...`) are worth the routing complexity on top of localised slugs.
|
|
- Facet counts for sport and gender, which need `unnest()` over the array columns —
|
|
worth doing when a UI displays them.
|
|
- Shipping-rate provider integration.
|
|
- Whether guest carts ever get promoted to PostgreSQL before sign-in.
|
|
- Multi-warehouse allocation strategy. The schema supports it; the policy does not exist yet.
|
|
- i18n / multi-currency rollout.
|
|
- Read replicas and connection pooling (PgBouncer) — a scaling decision that needs real traffic
|
|
numbers to make well.
|