bfa8cfd357
- 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>
86 lines
4.4 KiB
Markdown
86 lines
4.4 KiB
Markdown
# 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.
|