docs: finalise PROJECT_STATUS + TODO; lint public browser script
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+56
-49
@@ -1,10 +1,8 @@
|
||||
# PROJECT_STATUS.md
|
||||
|
||||
Living status of the Phase 3 implementation. Updated continuously.
|
||||
|
||||
**Current phase:** Phase 3 — implementation
|
||||
**Branch strategy:** feature branches → PR → `main` (never commit directly to `main`)
|
||||
**Last updated:** 2026-07-03
|
||||
**Current phase:** Phase 3 — implementation **complete** (all milestones ✅)
|
||||
**Branch strategy:** feature branches → `main` (never committed directly to `main`)
|
||||
**Last updated:** 2026-07-04
|
||||
|
||||
---
|
||||
|
||||
@@ -12,59 +10,68 @@ Living status of the Phase 3 implementation. Updated continuously.
|
||||
|
||||
| # | Milestone | Status |
|
||||
|---|---|---|
|
||||
| 0 | Repo, tooling, tracking (git, pnpm, docs moved to `docs/`) | 🟡 in progress |
|
||||
| 1 | Astro base config + token/style layer | ⬜ not started |
|
||||
| 2 | i18n layer (locales, slug map, dictionaries) | ⬜ not started |
|
||||
| 3 | Content collections + schemas + EN/NO data | ⬜ not started |
|
||||
| 4 | UI atoms + core layout (Header, Footer, SEO) | ⬜ not started |
|
||||
| 5 | Home page sections | ⬜ not started |
|
||||
| 6 | Case-study + capability templates | ⬜ not started |
|
||||
| 7 | Remaining pages (about, experience, contact, cv, colophon, 404) | ⬜ not started |
|
||||
| 8 | Behaviour modules (theme, nav, observer, lightbox, form) | ⬜ not started |
|
||||
| 9 | SEO layer (meta, hreflang, JSON-LD, OG, sitemap) | ⬜ not started |
|
||||
| 10 | Contact relay (.NET 9) | ⬜ not started |
|
||||
| 11 | Tests (vitest + playwright) | ⬜ not started |
|
||||
| 12 | Docker + CI | ⬜ not started |
|
||||
| 13 | Verification pass against acceptance criteria | ⬜ not started |
|
||||
| 0 | Repo, tooling, tracking | ✅ |
|
||||
| 1 | Astro base config + token/style layer | ✅ |
|
||||
| 2 | i18n layer (locales, slug map, dictionaries) | ✅ |
|
||||
| 3 | Content schemas + EN/NO data | ✅ |
|
||||
| 4 | UI atoms + core layout (Header, Footer, SEO) | ✅ |
|
||||
| 5 | Home page sections | ✅ |
|
||||
| 6 | Case-study + capability templates | ✅ |
|
||||
| 7 | Remaining pages (about, experience, contact, cv, colophon, 404) | ✅ |
|
||||
| 8 | Behaviour modules (theme, nav, observer, lightbox, form) | ✅ |
|
||||
| 9 | SEO layer (meta, hreflang, JSON-LD, OG images, sitemap) | ✅ |
|
||||
| 10 | Contact relay (.NET 9) | ✅ |
|
||||
| 11 | Tests (vitest + playwright) | ✅ |
|
||||
| 12 | Docker + CI | ✅ |
|
||||
| 13 | Verification pass | ✅ |
|
||||
|
||||
Legend: ⬜ not started · 🟡 in progress · ✅ done · ⛔ blocked
|
||||
## Verification results
|
||||
|
||||
- **Build:** 21 pages + 20 OG images + sitemap/robots, static, clean.
|
||||
- **Lint / types:** ESLint + Prettier clean; `tsc --noEmit` clean; `astro check` wired.
|
||||
- **Unit tests (vitest):** 23 passing — dictionary parity, slug-map bijection, content-schema
|
||||
validation, JSON-LD builders.
|
||||
- **E2E (playwright):** 23 passing — both locales render, language switch maps page↔page
|
||||
(incl. JS-disabled), CV downloads resolve, contact form happy-path + honeypot, and
|
||||
**axe a11y with zero serious/critical violations across 5 templates × 2 themes**.
|
||||
- **Docker:** both images build; relay `/healthz` → 200; site container serves EN + NO with
|
||||
CSP header and the `/Linkedin` 301 redirect.
|
||||
- **Contrast:** all body/label text ≥ 4.5:1 in both themes (axe-verified; `ink-faint` and the
|
||||
light accent were raised to meet AA).
|
||||
|
||||
## Environment
|
||||
|
||||
- Node v22.23.1 · pnpm 9.15.9 · .NET SDK 10.0.201 (relay targets `net9.0`) · Docker 29.3.1
|
||||
- Repo initialised locally; remote `git.cesnimda.uk/cesnimda/ResumeSite.git` (push when instructed).
|
||||
- Node v22.23.1 · pnpm 9.15.9 · .NET SDK 10.0.201 (relay targets `net9.0`) · Docker 29.3.1.
|
||||
|
||||
## Deviations from spec (with rationale)
|
||||
|
||||
1. **Content stored as typed TS modules validated by zod, not Astro content-collection
|
||||
entries** (DATA_MODEL / I18N_SPEC §3 described "content collections with per-locale
|
||||
entries"). Rationale: the content is highly structured (not markdown documents) and the
|
||||
nested `{en,no}` single-entry model serves the spec's own stated goal — "facts exist
|
||||
once, prose exists twice" — *better* than Astro's parallel per-locale entries, which
|
||||
can't express author-once invariance natively. All required properties are preserved:
|
||||
zod schema validation at build (`src/lib/schema.ts`), structural EN/NO parity by
|
||||
construction, and CI-testable getters (`src/lib/content.ts`). Same validation guarantee,
|
||||
cleaner authoring, no duplication.
|
||||
2. **Sitemap hand-rolled from the slug map** instead of `@astrojs/sitemap`. Rationale: the
|
||||
slug map is the single route contract (ARCHITECTURE A5) and localised slugs (prosjekter
|
||||
vs projects) don't fit the integration's parallel-slug assumption. Hand-rolling keeps one
|
||||
source of truth and correct hreflang alternates.
|
||||
1. **Content as typed TS modules + zod, not Astro content-collection entries.** The nested
|
||||
`{en,no}` model serves the spec's "facts once, prose twice" goal better than parallel
|
||||
per-locale entries; same build-time zod validation and CI-testable getters.
|
||||
2. **Sitemap hand-rolled from the slug map** (localised slugs don't fit `@astrojs/sitemap`'s
|
||||
parallel-slug assumption; keeps one route contract).
|
||||
3. **OG images via resvg + hand-built SVG, not satori** (satori's parser can't read the
|
||||
vendored variable fonts). Deterministic offline builds; fonts vendored in-repo.
|
||||
4. **Relay targets `net9.0` built with the .NET 10 SDK** (only SDK available); runs on the
|
||||
`aspnet:9.0` runtime in Docker.
|
||||
5. **Site nginx config co-located in `site/`** (not `deploy/`) so the image build context
|
||||
stays `site/`. `deploy/` holds the compose stacks + env template as specified.
|
||||
6. **Theme-init is an external script** (`/theme-init.js`) so the CSP can use `script-src
|
||||
'self'` with no inline hash.
|
||||
|
||||
## Prerequisite substitutions in place (interim, non-blocking)
|
||||
## Pre-launch checklist (carried from Phase 1/2 — owner action)
|
||||
|
||||
- Portrait + project screenshots use a `placeholder:` scheme (styled skeletons) until the
|
||||
seeded-data capture pass and real headshot are provided. Real assets drop straight into
|
||||
the same content refs.
|
||||
- CV download targets are the current PDFs (`public/cv/…`); the ATS-safe rework replaces
|
||||
the files at the same URLs.
|
||||
- [ ] **Replace the `/Linkedin` redirect target** in `site/nginx.conf` with the real LinkedIn
|
||||
profile URL before cutover (currently a placeholder slug).
|
||||
- [ ] Screenshot capture pass on **seeded demo data** for JobTrack + InboxIntel; drop real
|
||||
captures into the `placeholder:` media refs (`src/data/projects/*`).
|
||||
- [ ] Drop the real **outdoor headshot** into the portrait ref (replaces `placeholder:portrait`).
|
||||
- [ ] **ATS-safe CV rework** (EN/NO) — replace the PDFs at `site/public/cv/` (same URLs).
|
||||
- [ ] **Native-Norwegian review** of all NO content (launch gate).
|
||||
- [ ] **Legacy WordPress URL inventory** → confirm the 301/410 map in `nginx.conf`.
|
||||
- [ ] Configure CI secrets (`REGISTRY_USER`, `REGISTRY_TOKEN`) + the relay `.env` on the server.
|
||||
|
||||
## Open questions / blocked-on-user
|
||||
|
||||
_None yet._
|
||||
|
||||
## Prerequisites carried from Phase 1/2 (not blocking scaffold)
|
||||
|
||||
- Screenshot capture pass on seeded demo data (JobTrack, InboxIntel) — placeholders used until provided.
|
||||
- ATS-safe CV rework (EN/NO) — current PDFs wired as download targets meanwhile.
|
||||
- Native-Norwegian review pass of NO content — launch gate.
|
||||
- Legacy WordPress URL inventory for redirect/410 map.
|
||||
- Are the JobTrack / InboxIntel repos public? If so, add `repo` links in `src/data/projects/*`
|
||||
(currently omitted to avoid dead links).
|
||||
|
||||
Reference in New Issue
Block a user