Files
ResumeSite/PROJECT_STATUS.md
T
cesnimda bfa8cfd357 feat: homelab case study from live infra; Traefik-based deploy
- rewrote homelab (content + topology diagram + stack) from a live inspection of the host:
  Ubuntu 24.04, ~30 Docker services behind Traefik (Cloudflare-fronted, TLS, HTTP/3),
  Authentik SSO forward-auth, CrowdSec, Pi-hole, self-hosted Gitea + CI runner, socket-proxy,
  per-app network isolation; WordPress framed as being decommissioned (not future arch)
- deploy: docker-compose now uses Traefik labels + traefik_proxy network (was assumed nginx
  edge); .env.example adds SITE_HOST/TRAEFIK_ENTRYPOINT; colophon + ARCHITECTURE/DOCKER/
  DEPLOYMENT specs corrected nginx-edge -> Traefik (site container still serves via nginx)
- PROJECT_STATUS: pre-launch checklist updated; infra section added

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 11:23:09 +02:00

86 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PROJECT_STATUS.md
**Current phase:** Phase 3 — implementation **complete** (all milestones ✅)
**Branch strategy:** feature branches → `main` (never committed directly to `main`)
**Last updated:** 2026-07-04
---
## Milestones
| # | Milestone | Status |
|---|---|---|
| 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 | ✅ |
## 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.
## Deviations from spec (with rationale)
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.
## Pre-launch checklist (owner action)
- [x] ~~`/Linkedin` redirect target~~ — set to `https://www.linkedin.com/in/connor-babbington`.
- [x] ~~JobTrack seed-data screenshots~~ — real captures integrated (`/assets/projects/jobtrack/`).
- [x] ~~Real headshot~~ — integrated (`/assets/portrait.webp`, hero + about).
- [x] ~~ATS-safe CV rework (EN/NO)~~ — done; generator in `tools/cv/`.
- [ ] **InboxIntel screenshots** — still placeholders (no captures provided; it is "in development").
- [ ] **Native-Norwegian review** of all NO content, incl. the NO CV (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.
- [ ] Confirm the Traefik entrypoint / cert-resolver names in `deploy/.env.example` match the host.
## Infrastructure (verified live, July 2026)
Deploy target is the `mediaserver` host (Ubuntu 24.04): ~30 Docker services behind **Traefik**
(Cloudflare-fronted, TLS, HTTP/3), with **Authentik** SSO, **CrowdSec**, **Pi-hole**, and
self-hosted **Gitea + Actions runner** (the CI/CD target for this site). The homelab case study
and `deploy/` now reflect this (Traefik labels, `traefik_proxy` network). WordPress still runs
but is being decommissioned as this site replaces it — not documented as future architecture.
## Resolved
- JobTrack / InboxIntel repos are **private** → repo links intentionally omitted; case studies
describe the architecture without linking code.