# TASKS — jasonwoltje.com

**Milestone:** 0.0.1 — Bootstrap (repo, PRD, local scaffold)
**Next:** 0.0.2 — Design system port + collections
**MVP target:** 0.1.0 — Full site deployed on w-docker0, DNS live, all routes

Source of truth for scope: [`PRD.md`](PRD.md).

---

## Legend

| Status | Meaning |
|---|---|
| ☐ | pending |
| ◐ | in progress |
| ✅ | done |
| 🚫 | blocked — see `blocker` column |
| ⏭ | deferred |

---

## Milestone 0.0.1 — Bootstrap

| ID | Task | Status | Owner | Issue | Blocker |
|---|---|---|---|---|---|
| BOOT-01 | Create Gitea repo `jason.woltje/professional-website` | ✅ | orchestrator | — | — |
| BOOT-02 | Commit PRD + TASKS + README + LICENSE + `.gitignore` | ◐ | orchestrator | — | — |
| BOOT-03 | Push bootstrap commit to `main` | ☐ | orchestrator | — | — |
| BOOT-04 | Create first feature branch `feat/scaffold` | ☐ | worker | — | BOOT-03 |

## Milestone 0.0.2 — Scaffold + design system

| ID | Task | Status | Owner |
|---|---|---|---|
| SCAFF-01 | Initialize Next.js 16 + Payload 3 app in `src/` | ☐ | worker |
| SCAFF-02 | Configure pnpm workspace, TS strict, ESLint, Prettier | ☐ | worker |
| SCAFF-03 | Tailwind v3 config: port M3 tokens from stitch HTML | ☐ | worker |
| SCAFF-04 | `next/font`: Space Grotesk + Inter, CSS vars | ☐ | worker |
| SCAFF-05 | Install `lucide-react`, `@tailwindcss/forms`, `@tailwindcss/container-queries` | ☐ | worker |
| SCAFF-06 | Global utility classes: `.ghost-border`, `.glass-card`, `.neon-cta`, StatusTerminal baked vars | ☐ | worker |
| SCAFF-07 | Payload Postgres adapter + local `docker compose` for dev DB | ☐ | worker |
| SCAFF-08 | Health endpoint `/api/health` | ☐ | worker |

## Milestone 0.0.3 — Content model

| ID | Task | Status | Owner |
|---|---|---|---|
| CMS-01 | Collections: `users`, `media`, `categories`, `projects`, `posts`, `gear`, `contactSubmissions` | ☐ | worker |
| CMS-02 | Globals: `home`, `about`, `contact`, `resume`, `navigation`, `seo` | ☐ | worker |
| CMS-03 | Payload hooks: `revalidatePath` on publish | ☐ | worker |
| CMS-04 | Access control: admin-only for sensitive collections | ☐ | worker |
| CMS-05 | Seed script: placeholder content for all collections/globals | ☐ | worker |

## Milestone 0.0.4 — Pages + sections

| ID | Task | Status | Owner |
|---|---|---|---|
| UI-01 | Section components: HeroHeadline, ProjectBentoGrid, MakerMindsetCard, AudioSignalPath, StatusTerminal, ContactForm, NewsletterBand, SocialBento | ☐ | worker |
| UI-02 | `/` page composition | ☐ | worker |
| UI-03 | `/about` page composition | ☐ | worker |
| UI-04 | `/projects` + `/projects/[slug]` | ☐ | worker |
| UI-05 | `/writing` + `/writing/[slug]` | ☐ | worker |
| UI-06 | `/contact` (form + Turnstile + honeypot + rate-limit) | ☐ | worker |
| UI-07 | `/resume` + `/resume.pdf` (react-pdf or puppeteer) | ☐ | worker |
| UI-08 | Sitemap, robots, RSS | ☐ | worker |

## Milestone 0.0.5 — CI + container

| ID | Task | Status | Owner |
|---|---|---|---|
| CI-01 | Multi-stage `Dockerfile` (deps → build → runner, non-root, standalone Next output) | ☐ | worker |
| CI-02 | `.woodpecker/web.yml` — lint/typecheck/build/audit/Kaniko/Trivy/link-package | ☐ | worker |
| CI-03 | First CI run → image pushed to Gitea registry | ☐ | orchestrator |
| CI-04 | Verify image path: `jason.woltje` dot handling | ☐ | orchestrator |

## Milestone 0.0.6 — Deploy

| ID | Task | Status | Owner |
|---|---|---|---|
| DEP-01 | `docker-compose.swarm.yml` — web + postgres, traefik-public external, labels mirror mosaicstack-website | ☐ | worker |
| DEP-02 | `.env.example` committed | ☐ | worker |
| DEP-03 | **ESC-01:** Edge Traefik TLS config for `jasonwoltje.com` | 🚫 | Jason | ESC-01 |
| DEP-04 | Cloudflare DNS: A/CNAME for apex + www, proxied | ☐ | Jason | — |
| DEP-05 | Portainer stack creation on w-docker0 (endpoint 7), env vars populated | ☐ | orchestrator | DEP-03 |
| DEP-06 | First deploy smoke test: `/`, `/admin`, `/api/health`, www→apex 301 | ☐ | orchestrator | DEP-05 |
| DEP-07 | Payload admin bootstrap: Jason creates first admin user | ☐ | Jason | DEP-06 |

## Milestone 0.1.0 — MVP acceptance

See `PRD.md` §11 for full acceptance criteria. Gate conditions:

- All routes render
- Lighthouse thresholds met (Perf ≥85, A11y ≥95, SEO ≥95)
- Contact form end-to-end (submit → Payload → email)
- Headshots uploaded to media collection
- At least 1 project + 1 post published
- Release tag `v0.1.0` pushed; CI tagged build deployed

## Deferred (Phase 2)

| Task | Rationale |
|---|---|
| Auto-deploy via Portainer API | Defer until manual deploys are stable |
| Health-check gate in CI | Same |
| Umami analytics stack | Separate repo/stack |
| Mautic newsletter integration | Separate deploy; newsletter UI is stub until live |
| Offsite backups (B2/R2) | v0.1.x concern |
| MinIO migration | Triggered by volume growth |

---

## Active blockers / escalations

| ID | Description | Unblocks |
|---|---|---|
| ESC-01 | Edge Traefik TLS config for new domain `jasonwoltje.com` | DEP-03 → DEP-05+ |
| ESC-03 | SMTP/Resend credentials for contact form notifications | UI-06 email path |
| ESC-04 | Turnstile site + secret keys | UI-06 CAPTCHA |

Unblocking these does not gate scaffold work — only deploy and contact form completion.
