docs: establish approved Phase 1 design + Phase 2 spec as project foundation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# DATA_MODEL.md
|
||||
Content model for the bilingual content collections. All schemas zod-validated at build; a schema violation fails CI. (Conceptual field lists — not code.)
|
||||
|
||||
---
|
||||
|
||||
## 1. Collections overview
|
||||
|
||||
```
|
||||
content/
|
||||
├── profile/ singleton per locale (hero, chips, about)
|
||||
├── projects/ 3 entries × 2 locales (jobtrack, inboxintel, homelab)
|
||||
├── experience/ 5 entries × 2 locales (council, side roles, education, 2023-now)
|
||||
├── skills/ 3 group entries × 2 locales
|
||||
└── meta/ colophon page, 404 copy, contact page copy × 2 locales
|
||||
```
|
||||
|
||||
Locale-invariant fields live on the EN entry and merge into NO at load (I18N_SPEC §3). Below, fields marked **[inv]** are invariant; everything else is per-locale prose.
|
||||
|
||||
## 2. `profile` (singleton)
|
||||
|
||||
- `name` [inv], `roleLine`, `heroTagline` (the one-sentence claim), `heroSummary` (≤ 2 lines)
|
||||
- `chips[]`: `{ id [inv], label }` — location, permit, availability, languages
|
||||
- `statusLine` (trace-dot tooltip: "open to work" / "åpen for muligheter")
|
||||
- `aboutParagraphs[]` (3), `interestsLine`
|
||||
- `photo` [inv]: asset ref + per-locale `alt`, `caption`
|
||||
- `links` [inv]: email, linkedinRedirect (`/Linkedin`), gitea, phone
|
||||
- `cv` [inv]: `{ en: {path, sizeKb, updated}, no: {...} }`
|
||||
|
||||
## 3. `projects`
|
||||
|
||||
- `id`/`slug` [inv, per-locale slug via slug map], `name` [inv], `order` [inv]
|
||||
- `status` [inv]: `active | in-development | archived` (drives chip semantics per COLOUR_SYSTEM §3.4)
|
||||
- `valueProp` (one-liner), `cardTeaser` (2 lines for homepage card)
|
||||
- `stack[]` [inv]: `{ name, contextLine? per-locale }` (chip + tooltip)
|
||||
- `links[]` [inv]: `{ type: repo|live|docs, url, public: bool }` (repo links only if/when repos are public — publish decision is content, not code)
|
||||
- `tldr`: `{ what, why, stack, role }` (4 strings)
|
||||
- `sections[]`: ordered `{ anchorId per-locale, heading, body (markdown) }` — canonical section kinds: `problem`, `architecture`, `decisions`, `security`, `screenshots`, `next`
|
||||
- `decisions[]`: structured `{ n, choice, alternative, rationale }` (rendered as the numbered trade-off blocks)
|
||||
- `diagram` [inv]: SVG asset ref + per-locale `title`, `desc` (a11y), `nodes[]` label overrides per locale
|
||||
- `media[]` [inv refs]: `{ image, width, height, per-locale alt + caption, order }` — dimensions mandatory (CLS 0)
|
||||
- `template` [inv]: `case-study | capability` (homelab uses the lighter template)
|
||||
- `summaryOnly?` (NO-side flag per I18N_SPEC §4.2)
|
||||
|
||||
## 4. `experience`
|
||||
|
||||
- `id` [inv], `employer` [inv], `location` [inv], `period` [inv]: `{ from, to|null }`
|
||||
- `role`, `summary`, `highlights[]` (featured only)
|
||||
- `emphasis` [inv]: `featured | compact`
|
||||
- `progression?` [inv]: for the council entry — `[{from: 2015, to: 2017, label-per-locale: "Apprentice"}, {from: 2017, to: 2023, label: "System Developer"}]`
|
||||
- `anchor?` — the confirmed concrete bullet (streetlight/highways system) is content, phrased per CANONICAL_CONTENT
|
||||
- Entries: `warwickshire` (featured), `royal-vapes`, `hodcarrier`, `nuffield` (compact, `alongside: true` [inv] flag renders the "alongside" grouping), `education`, `norway-now` (2023–, norskkurs + products)
|
||||
|
||||
## 5. `skills`
|
||||
|
||||
- `id` [inv], `order` [inv], `title`, `contextLine`, `skills[]`: `{ name [inv], tooltip? }`
|
||||
- Groups: `development`, `devops-infrastructure`, `practices`
|
||||
|
||||
## 6. Page-meta (every routable page)
|
||||
|
||||
- `title`, `description` (≤155 chars), `ogImage` [generated per locale], `pageId` [inv → slug map join]
|
||||
- Case studies additionally emit structured-data fields (SEO_SPEC §3)
|
||||
|
||||
## 7. Asset conventions
|
||||
|
||||
- Screenshots: `assets/projects/<id>/<capture>.png` source of truth at 2×, seeded demo data only (Phase 3 prerequisite); pipeline emits AVIF/WebP/fallback + srcset.
|
||||
- Diagrams: hand-authored SVGs following the design-system diagram style; text within diagrams uses per-locale label injection at build (single SVG source, two rendered outputs) — avoids maintaining twin diagrams.
|
||||
- Fonts/CVs/favicons in `public/` (unprocessed, stable URLs).
|
||||
|
||||
## 8. Validation rules (CI)
|
||||
|
||||
1. Locale parity (I18N_SPEC §4.1).
|
||||
2. Every `media[]` entry has dimensions + both alts.
|
||||
3. Every project has ≥3 `decisions[]` and a `security` section (the site's promise to P2 is structural).
|
||||
4. `status` transitions logged in git only — no "archived" entry may appear on the homepage cards (query rule).
|
||||
5. Description lengths, title lengths enforced (SEO).
|
||||
6. All external `links[].url` respond 200 in a scheduled link-check workflow (not per-commit).
|
||||
Reference in New Issue
Block a user