codingstairs
NotesEDULifeContact
⌕Search⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

Get in touch

Send without signing in. Add your email if you'd like a reply.

  • Leave a message anonymously →
  • ✉ warragon112@gmail.com
  • KakaoTalk Open Chat ↗

© 2026 codingstairs

  • Notes
  • EDU
  • Search
  • Life
  • Contact
  • Legal
  • RSS
  • GitHub
EDU›Monorepo · SSOT · layer separation thinking›Step 2

Step 2

SSOT — where to put it

0 views

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 — .env vs 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

← Step 1

Monorepo vs polyrepo

Step 3 →

Folders as contracts