Skip to content

Roadmap

Planned features and improvements, roughly ordered by priority. This is a living document — items move to Work in Progress when picked up.


Kanban

Backlog To Do In Progress Done
Certification sync — Credly, Databricks (Playwright), MS Learn OAuth infra, weekly ACA job (#606)
Multi-env PR preview + Strapi draft preview (Phases 1-4) — frontend preview mode, token provisioning, preview-button plugin, label-triggered auto-deploy (#604)
OpenAPI version bump on every release Storybook Phase 1+2+3 — component library, vitest browser tests, Chromatic CI, SWA deploy, custom theming, all section stories (#390+)
Auth Phase 1 — Entra ID JWT admin auth (#384)
Auth Phase 2 — MSAL.js admin sign-in → superseded by UIGen native Microsoft OAuth (#435, #474)
Distributed tracing — App Insights (#389)
Blue/green deploys for Azure Container Apps (#423)
CV download endpoint metrics — OTel counters, DB events table, admin endpoint (#0007)
API-backed experience + skills frontend — usePortfolioContent.ts hooks, feature-flagged (#358)
API refactor Phase 6 — loguru, RequestIdMiddleware, DB UIGen tokens (#381)
API refactor Phase 5 — seed.json, ProjectPhase child table (#380)
API refactor Phase 4 — repositories, services, async CV gen (#379)
API refactor Phase 3 — per-domain routers, domain exceptions (#377)
API refactor Phase 2 — Pydantic v2 response schemas (#375)
API refactor Phase 1 — Settings/skeleton/templates (#370)
Content API — experience/skills/projects/awards/certs (#358)
UIGen content API annotations (#363)
UIGen v0.6.0 — /api/docs + /admin/config proxy (#326)
docs-update skill enhancement (parallel + validation)
LlamaPReview CI robustness handover
Docs update post v0.5.0-alpha (#257)
Prod always full redeploy (#255)
IMDS client_id fix (#254)
Backend crash loop + UIGen guest fix (#253)
UIGen custom domain prod (admin.sven-relijveld.com)
Azure App Config feature flags (#247)
UIGen admin portal + auth shim (#207)
CV template polish (#191)
Weekly Azure cost report in docs (#190)
Cline kanban ↔ memory sync skills (#189)
CV generation: publishpipe + cover page (#183)
GitHub Codespaces devcontainer (#180)
Parallel CI test workflow (#186)
Fix CV pagedjs-cli deps (#187)
PostgreSQL CRUD — Phase 3: Tests + CI (#184)
PostgreSQL CRUD — Phase 2: Bicep infra (#181)
End-to-end typing (TS + Pydantic) (#163)
Notify on deploy failure — GitHub Issues (#162)
Docker layer caching in CI (#159)
Runbook: secret rotation / redeploy (#160)
PostgreSQL CRUD — Phase 1: DB layer (#178)
Project detail pages (case studies)
Claude Code GitHub Workflow (#119)
Dependabot-review skill (#97)
C4 + deployment + Azure cloud diagrams
Dark mode toggle (#155)
Resolve Dependabot alerts (#98–#118)
Dependabot bulk updates (#278–#294, #301, #303, #304)
API annotations for UIGen + code review fixes (#299)
fix(infra): app_config_resource_id in bicepparams (#300)
Postgres MI auth bug chain fix (#265–#274)
Feature-flags retry after EasyAuth (#277)
Revision health check schedule reduced (#276)
feat(hero+nav): type-in treatment, SkillBar, role cycler (#454)
fix(uigen): feature-flags override panel + OAuth login loop (#455, #451, #443–#448)
fix(infra/api): UIGen EasyAuth + auth router fixes (#438, #439)
fix(experience): W+B DevOps role, HAI/Albron split (#456)
UIGen v0.16.0 upgrade + create-projects auth guard (#474)
fix(infra): split enable_auth into enable_frontend_auth/enable_uigen_auth (#469)
fix(infra): enable_uigen_auth=true for prod UIGen client secret (#463)
fix(workflows): environment context on validate job for OIDC (#471)
feat: alpha + stable release channels via main/release branches (#472)
Dependabot bulk: npm/pip/uv updates (#459, #465, #466, #468, #478, #479)
chore: ignore *.local.md files (#480)
CMS deployment to dev — custom domain, managed cert, plugins, Postgres MI auth (#507–#516)
feat(content): Content & Presentations section (#560)
feat(content): blog images, webinar seed, interactive embeds (#562)
fix(ci/data+frontend): docs submodule PAT + experience title (#556, #559)
Stable release v0.21.0 — manual stable release process (#585)

Near Term

Frontend

  • [x] Add project detail pages (expand portfolio cards to full case studies)
  • [x] Improve mobile layout for contact section
  • [x] Add dark mode toggle to portfolio site
  • [x] Consume projects API from frontend (React Query hooks, skeleton loading)
  • [x] Add related project links to work experience full page
  • [x] Add IaC Data Platform Framework project (OneDNA internal)
  • [x] Storybook Phase 1 — component library (44 stories), vitest browser interaction tests, Chromatic visual CI, site theming, Azure SWA deploy at /storybook/ — PR #390
  • [x] Project Page V2 cleanup — all 8 Strapi project-page entries seeded, projectV2Data and project-detail.tsx removed (#591, #600)
  • [x] Content Management singletons (Phase 3) — hero, about, footer, contact, how-its-made sections wired to Strapi singletons with static fallback (#592, #600)
  • [x] Storybook Phase 2 — Router/QueryClient wrappers, Chromatic CI, custom OneDNA theming (#390)
  • [x] Storybook Phase 3 — all section stories complete: AboutSection, AwardsSection, CertificationsSection, ContactSection (with .play() form fill), CVDownloadDialog (feature-flag variants), AdminModal, HowItsMadeSection, Footer, SkillBar
  • [x] API-backed experience + skills in frontend — useExperiencePreview, useSkillCategories, useAwards, useCertifications hooks in usePortfolioContent.ts, feature-flagged behind portfolioContentApi — PR #358

Backend

  • [x] Structured logging with correlation IDs — loguru + RequestIdMiddleware, X-Request-Id round-trip — PR #381
  • [x] API refactor Phases 2–6 — response schemas, per-domain routers, repositories, services, seed.json, ProjectPhase, DB-backed UIGen tokens — PRs #375, #377, #379, #380, #381
  • [x] CV download endpoint metrics — OTel counters (cv.downloads, cv.generations, cv.generation.duration), cv_download_events DB table (migration 0007), GET /api/metrics/cv-downloads admin endpoint

Security / Auth

  • [x] Auth Phase 1 — Entra ID JWT admin auth, write-gate on admin API endpoints — PR #384
  • [x] Auth Phase 2 — UIGen v0.10.0 native Microsoft OAuth (MSAL.js prototype shipped then superseded by UIGen's own PKCE+shim flow) — PRs #435, #474

Medium Term

Infrastructure

  • [x] Application Insights distributed tracing — frontend + backend — PR #389
  • [x] Blue/green deployments for Container Apps — Multiple revisions mode, green/blue label traffic shift, rollback via workflow_dispatch (#423)
  • [x] Resolve Dependabot security alerts — bulk resolved via #98–#118

CI/CD + Preview

  • [x] Multi-env PR preview + Strapi draft preview — per-PR isolated environment; frontend fetches ?status=draft from PR CMS via read-only API token; strapi-plugin-preview-button links from Strapi admin to PR frontend; Phase 4 auto-trigger on preview label — PR #604. See plan.

CI/CD

  • [x] Fix DeploymentActive race condition — unified concurrency groups across all three deploy workflows, enriched PR comments, improved ARM poll error handling — PR #161
  • [x] Notify on deployment failure — GitHub Issues with dedup (comment on existing vs. create new), try/catch in all five workflow notify blocks — PR #162
  • [x] Cache Docker layers in GitHub Actions — ACR registry-mode cache via docker/build-push-action@v6, PR-scoped cache tags with cleanup on PR close — PR #159

Docs

  • [x] Add runbook: rotating secrets / re-deploying from scratch — docs/infrastructure/runbook-secret-rotation.md — PR #160
  • [x] Split Frontend and Backend as separate top-level nav sections in MkDocs

Backlog

  • [ ] UIGen config GUI theming — override --color-purple-* CSS variables with OneDNA pink in the port 4500 config GUI. Shim proxy injects <style> with @layer theme, override but Tailwind v4's @layer theme variables are not being overridden by the injected layer; root cause unknown. May need UIGen v0.6.x fix or a different injection strategy.
  • [ ] Authentication Phase 3 — registered users (Entra External ID / B2C, social IdPs: Google + GitHub). See authentication plan.
  • [ ] OpenAPI version bump on every release — sync info.version in FastAPI app definition with the git tag / release version; needed so the UIGen admin UI and shared/api.types.ts drift guard can detect schema version changes
  • [ ] Multi-environment preview deployments per PR (frontend + backend)
  • [x] Cost dashboard: Azure resource costs per environment — weekly GitHub Actions workflow + docs page — auto-committed to docs/infrastructure/cost-dashboard.md
  • [x] CV template improvements: cover page, dot-rating matrix, skills grid, photo, typography polish — PR #191
  • [x] GitHub Codespaces devcontainer — .devcontainer/devcontainer.json + postCreate.sh, Node 20 + Python 3.11 + Azure CLI + Docker-in-Docker — PR #180.
  • [x] End-to-end typing (TypeScript + Pydantic) — pydantic-settings Settings class, ContactRequest field constraints, OpenAPI→TS generation via openapi-typescript into shared/api.types.ts, ESLint with no-explicit-any, CI type-drift guard — PR #163.
  • [x] PostgreSQL CRUD backend — Phase 1 (#178), Phase 2 (#181), Phase 3 (#184). Full CRUD with SQLAlchemy async + asyncpg + Alembic, Azure Flexible Server AAD-only auth, Bicep module, Key Vault secret, admin write endpoints with bearer token, pytest fixtures + CI postgres service. See backend architecture.
  • [x] CV generation — publishpipe build pipeline, custom Nunjucks template + CSS, branded OneDNA cover page, FastAPI feature-flagged endpoints — PR #183. Fix pagedjs-cli deps — PR #187.
  • [x] Parallel CI test workflow — consolidated into test.yml with fail-fast gate — PR #186.

Completed

  • feat(certs): certification sync from Credly (20 badges), Databricks via Playwright (41 credentials), MS Learn OAuth infrastructure; weekly ACA scheduled job; frontend shows badge images, issued/expiry dates, expired card dimming (#606)
  • feat(ci): PR preview + Strapi draft preview Phases 1-4 — cms-fetch.ts helper, PreviewBanner, token provisioning via /api/preview-token Koa route, preview-button plugin wired for 3 content types, preview label auto-deploy (#604)
  • feat(cms): CMS Phase 3 singletons — footer, contact, how-its-made sections wired to Strapi; projectV2Data static fallback removed; NL locale seeded (#599, #600)
  • Stable release v0.22.0 — CMS singletons, project V2 migration complete, NL locale, prod cold-start fix
  • Storybook Phase 3 — all portfolio section stories complete (AboutSection, AwardsSection, CertificationsSection, ContactSection with .play(), CVDownloadDialog feature-flag variants, AdminModal, HowItsMadeSection, Footer, SkillBar)
  • feat(infra/ci): blue/green deployments for Container Apps — Multiple revisions, green/blue label shift, rollback workflow (#423)
  • feat(backend): CV download metrics — OTel counters, cv_download_events table (migration 0007), GET /api/metrics/cv-downloads admin endpoint
  • feat(content): Content & Presentations section — /content landing page, /content/:slug detail, Strapi content-post collection, useContentPosts/useContentPost hooks, ContentModal, home teaser (#560)
  • feat(content): blog images, webinar dbt PDF seed, EMBED_n interactive iframes, nginx /cms/uploads/ proxy fix (#562)
  • fix(ci/data+frontend): docs submodule PAT auth + W+B/experience title fixes (#556, #559)
  • Stable release v0.21.0 — manual tag + GitHub release, release-workflow.md rewritten with 6-step stable release process (#585)
  • UIGen v0.16.0 upgrade + create-projects auth guard (#474)
  • fix(infra): split enable_auth into enable_frontend_auth/enable_uigen_auth, prod UIGen auth fix (#463, #469)
  • fix(workflows): environment context on validate job for OIDC (#471)
  • feat: alpha + stable release channels via main/release branches (#472)
  • Dependabot bulk: npm/pip/uv updates (#459, #465, #466, #468, #478, #479)
  • chore: ignore *.local.md files (#480)
  • [x] fix(experience): W+B Cloud Architect & DevOps role, HAI/Albron split, Albron paused context — Alembic migrations 0008+0009, seed.json, frontend experience.ts — PR #456
  • [x] fix(uigen): feature-flags override panel in UIGen shim (feature-flags.tsx), proxy routing fixes, docker-compose FEATURE_* env vars — PR #455
  • [x] feat(hero+nav): type-in treatment for hero tagline, sliding nav pill, SkillBar component, role cycler behind feature flag, OneDNA logo variants — PR #454
  • [x] fix(uigen): complete OAuth login loop — PyJWT v2 token validation, sessionStorage bearer injection on /api/auth/me, landing page, sessionValidationEndpoint path, userInfoUrl fixes — PRs #443–#451
  • [x] fix(infra/api): exclude /auth/token and /auth/callback from UIGen EasyAuth; register auth router at root so UIGen proxy /auth/me reaches backend — PRs #438, #439
  • [x] refactor(api): Phase 6 — loguru structured logging (configure_logging(), InterceptHandler), RequestIdMiddleware (X-Request-Id read/generate/echo), DB-backed UIGen token store (uigen_tokens table, SHA-256 hashing, issue/validate/revoke), migration 0006 — PR #381
  • [x] refactor(api): Phase 5 — api/data/seed.json canonical static fallback for all content, seed.py lru_cache loader, ProjectPhase ORM model (FK to projects, ordinal, name, description), migration 0005 replaces timeline_encoded ARRAY(Text) with proper child table, selectinload(Project.phases) in projects repository — PR #380
  • [x] refactor(api): Phase 4 — 5 repository modules (api/repositories/), each with AsyncSession | None parameter and seed fallback; EmailService (Jinja2 + SMTP) in api/services/email.py; generate_cv() via asyncio.create_subprocess_exec in api/services/cv.py; get_optional_db() added to api/db/engine.py — PR #379
  • [x] refactor(api): Phase 3 — 9 per-domain router files under api/routers/; domain exception hierarchy (PortfolioError, NotFoundError, ConflictError, ServiceUnavailableError) + register_exception_handlers() in api/core/exceptions.py; shared Limiter in api/core/limiter.py; main.py shrunk to ~150-line create_app() factory — PR #377
  • [x] refactor(api): Phase 2 — 11 Pydantic v2 response schemas (from_attributes=True) in api/schemas/responses.py; killed all _x_to_y hand-converter functions — PR #375
  • [x] refactor(api): Phase 1 — extract Settings to api/core/config.py, skeleton packages (api/core/, api/routers/, api/services/, api/repositories/, api/templates/), move OpenAPI config, extract Jinja2 email templates — PR #370
  • [x] ci(release): add workflow_dispatch trigger to release-please workflow — PR #361
  • [x] fix(backend): skip Alembic migration when DATABASE_URL is not set — PR #360
  • [x] feat(uigen): annotate content API endpoints with x-uigen-id for UIGen grouping — PR #363
  • [x] feat(content-api): API-backed portfolio content with portfolio-content-api feature flag — new endpoints GET /api/experience, /api/skills, /api/projects, /api/projects/{id}, /api/awards, /api/certifications — PR #358
  • [x] UIGen v0.6.0: /api/docs Swagger UI proxy, /admin/config config GUI proxy with asset rewriting, auth shim, PATCH /api/cv/generate — PR #326
  • [x] chore(deps): zod v3→v4, zod-validation-error v3→v5, ecdsa security fix — PR #304
  • [x] Improve API annotations for UIGen (x-uigen-view hints) + fix code review issues — PR #299
  • [x] fix(infra): add app_config_resource_id to dev + prod bicepparams — PR #300
  • [x] Dependabot bulk updates — PRs #278–#294, #301, #303
  • [x] fix(frontend): retry feature-flags fetch up to 5× with backoff after EasyAuth redirect — PR #277
  • [x] chore(ci): reduce revision health check schedule to 12h (was 15 min) — PR #276
  • [x] fix(ci): use ENV_SHORT (prd) for MI resource name lookups in prod — PR #274
  • [x] fix(ci): use MI principal name (not client ID UUID) as Postgres username in workflow DATABASE_URL — PR #273
  • [x] fix(infra): use MI principal name as Postgres username in Bicep-written DATABASE_URL — PR #270
  • [x] fix(db): replace raw urllib IMDS call with azure-identity ManagedIdentityCredential — PR #269
  • [x] fix(backend): retry Alembic migration on IMDS timeout at cold start — PR #267
  • [x] fix(ci): correct smoke test expected HTTP codes (frontend 401, backend /api/health) — PR #266
  • [x] fix: IMDS retry with 5× exponential backoff + UIGen theme.css copied into image — PR #265
  • [x] fix(uigen): bust CI image cache + UIGen 0.5.0 bump — PR #261
  • [x] docs(api): foldable endpoint callouts + ADR-007 nav entry — PR #259
  • [x] docs-update skill: planning-first, parallel edits, reviewer agent, nav sync, ADR suggestions
  • [x] CI artifact detection robustness handover (LlamaPReview P0/P1) — handover_llamapr_ci_robustness.md
  • [x] Docs update post v0.5.0-alpha: UIGen, App Config, Postgres, CI — PR #257
  • [x] Prod always full redeploy: artifact-based env detection in deploy-application.yml / deploy-docs.yml — PR #255
  • [x] fix(db): IMDS client_id for user-assigned managed identity — PR #254
  • [x] fix(prod): Alembic env.py token auth + UIGen guest routing — PR #253
  • [x] UIGen custom domain on prod (admin.sven-relijveld.com) — direct infra push
  • [x] Azure App Configuration feature flags (cv-generation, per-env labels dev/prod) + UIGen custom domain infra — PR #247
  • [x] UIGen admin portal: AdminModal, /api/uigen-token, Node.js auth shim (/auth?token=) — PR #207
  • [x] CV template polish: cover page, dot-rating matrix, skills grid, photo, typography — PR #191
  • [x] Weekly Azure cost report embedded in docs: cost-report.yml, cost-dashboard.md, Cost Management Reader role via Bicep — PR #190
  • [x] Add Cline kanban ↔ memory sync skills (sync-clineboard-to-memory, sync-memory-to-clineboard) — PR #189
  • [x] Cost dashboard: weekly cost-report.yml workflow queries Azure Cost Management (dev + prod), renders docs/infrastructure/cost-dashboard.md, commits with [skip ci]; Cost Management Reader role assigned at subscription scope via Bicep
  • [x] Parallel CI test workflow: consolidated test.yml, fail-fast gate — PR #186
  • [x] Fix CV pagedjs-cli + nodejs runtime dependency — PR #187
  • [x] CV generation: publishpipe, branded OneDNA cover page, Nunjucks+CSS, FastAPI feature-flag endpoints — PR #183
  • [x] GitHub Codespaces devcontainer: Node 20 + Python 3.11 + Azure CLI + Docker-in-Docker — PR #180
  • [x] End-to-end typing: pydantic-settings Settings class, ContactRequest hardening, OpenAPI→TS generation, ESLint, CI drift guard — PR #163
  • [x] Fix DeploymentActive race condition: unified concurrency groups, enriched PR comments, improved ARM poll — PR #161
  • [x] Deploy failure notifications via GitHub Issues with dedup — PR #162
  • [x] Docker layer caching via ACR registry cache + PR cache cleanup on close — PR #159
  • [x] Runbook: secret rotation and full redeploy from scratch — PR #160
  • [x] Fix dark mode toggle in Tailwind CSS 4 (@custom-variant dark) — PR #155
  • [x] Related project links in experience full page — PR #156
  • [x] Add IaC Data Platform Framework project (OneDNA Terraform/Bicep) — PR #156
  • [x] Fix prev/next navigation + local images + nginx DNS + FastAPI upgrade — PR #154
  • [x] Consume /api/projects from frontend with React Query — PR #151
  • [x] Fix bufferutil lock file mismatch in Vitest CI — PR #150
  • [x] Fix duplicate Experience navbar item — PR #148
  • [x] Fix Claude Code review workflow permissions — PR #147
  • [x] Migrate to React 19 — PR #145
  • [x] Migrate to Tailwind CSS 4 — PR #144
  • [x] Migrate to TypeScript 6 — PR #143
  • [x] Upgrade Vite 5→6 — PR #146
  • [x] Architecture docs expansion: C4 Context + Container diagrams, deployment diagram, Azure cloud diagram with embedded icons, architecture index page, overview page relayout — PR #93
  • [x] draw.io architecture diagram with CI PNG export — PR #90/#93
  • [x] Add architecture decision records (ADR) section — PR #82
  • [x] MkDocs glightbox plugin for zoomable images — PR #93
  • [x] Consolidate MkDocs deps into docs/requirements.txt — PR #93
  • [x] Embed Azure icons as base64 SVG data URIs for headless CLI export — PR #93
  • [x] Fix draw.io PNG export in CI — replaced Docker action with .deb install + xvfb-run — PR #93
  • [x] Add smoke test step after container deployment — smoke-test-prod.yml (3x/day weekdays)
  • [x] Rate limiting on contact form endpoint — slowapi already integrated
  • [x] Add API reference auto-generated from FastAPI OpenAPI schema — Swagger UI via mkdocs-swagger-ui-tag
  • [x] Bypass Entra ID SSO in Playwright E2E tests for dev — X-ZUMO-AUTH header approach — PR #83
  • [x] Fix dev Container Apps cost leak: single revision mode + PR close cleanup — PR #96
  • [x] Add dependabot-review skill + fix dependabot.yml config — PR #97
  • [x] Resolve Dependabot security alerts — PRs #98–#118
  • [x] Add Claude Code GitHub Workflow — PR #119
  • [x] Expand project detail pages into full case studies (timeline, lessons learned, prev/next nav)

Items without an owner or timeline are aspirational. Estimates are intentionally omitted — this tracks intent, not deadlines.