Step 2
SSOT — where to put it
25 min
SSOT — where to put it
SSOT is a promise: "if a fact lives in many places, one is the truth". The real question is where.
1. What SSOT answers
- DB schema — migrations vs ORM vs live DB?
- API schema — OpenAPI vs code?
- i18n strings — JSON vs DB vs Notion?
- Design tokens — Figma vs CSS?
- Env vars —
.envvs Vault?
Pick one per concern or expect drift.
2. Placement options
| Where | Pros | Cons |
|---|---|---|
| Code (git) | versioned, reviewable | no runtime edits |
| DB | editable at runtime | deploy ≠ change |
| External (Notion/Figma) | non-devs can edit | harder automation |
| Env vars | simple | no structure |
3. DB schema = SQL files
frontend/admin/sql/codingstairs/
├── 001_create_categories.sql
├── 002_create_posts.sql
...
Truth: the file. Live DB and ORM are mirrors. Great for review and reproducibility.
4. Seeds — two-tier
Tier 1 — static data (categories, settings) in TS files
Tier 2 — content (notes, blog posts) in .md files
Walker ingests idempotently.
5. SEO metadata = code
export const metadataMap: Record<string, MetaInfo> = {
"/notes": { title: "Notes", description: "...", keywords: [...] },
};
6. Env = .env (private repo)
.env.local # ignored
.env.dev # committed (private)
.env.prod # committed (private)
In public repos use Vault / 1Password / Secrets Manager.
7. Anti-pattern — two sources
Figma colours + CSS vars, manually synced → drift. Solution: auto-export Figma → CSS vars.
8. Conflict rules
When the same concept lives in multiple places, pin precedence:
service rules.md > shared/*.md > RULES.md > README.md
9. Drift guards
If a non-SSOT place falls out of sync, alert or error.
New SQL column → must update 4 places:
sql/*.sql
seed.ts
frontend types
admin types
Freeze a count test in CI.
10. Gotchas
- SSOT should be the place that changes most often
- ORM as SSOT with multiple consumers → migration pain
- "Truth in someone's head" — always write it down
Closing
SSOT is a team agreement, not a tool choice. Honour it and three-month-old code stays readable.
Next
- 03-folders-as-contracts