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-pageentries seeded,projectV2Dataandproject-detail.tsxremoved (#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,useCertificationshooks inusePortfolioContent.ts, feature-flagged behindportfolioContentApi— 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_eventsDB table (migration 0007),GET /api/metrics/cv-downloadsadmin 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=draftfrom PR CMS via read-only API token;strapi-plugin-preview-buttonlinks from Strapi admin to PR frontend; Phase 4 auto-trigger onpreviewlabel — PR #604. See plan.
CI/CD¶
- [x] Fix
DeploymentActiverace 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, overridebut Tailwind v4's@layer themevariables 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.versionin FastAPI app definition with the git tag / release version; needed so the UIGen admin UI andshared/api.types.tsdrift 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-settingsSettingsclass,ContactRequestfield constraints, OpenAPI→TS generation viaopenapi-typescriptintoshared/api.types.ts, ESLint withno-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.ymlwith 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.tshelper,PreviewBanner, token provisioning via/api/preview-tokenKoa route,preview-buttonplugin wired for 3 content types,previewlabel 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_eventstable (migration 0007),GET /api/metrics/cv-downloadsadmin 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,
SkillBarcomponent, 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/tokenand/auth/callbackfrom UIGen EasyAuth; register auth router at root so UIGen proxy/auth/mereaches backend — PRs #438, #439 - [x] refactor(api): Phase 6 — loguru structured logging (
configure_logging(),InterceptHandler),RequestIdMiddleware(X-Request-Idread/generate/echo), DB-backed UIGen token store (uigen_tokenstable, SHA-256 hashing,issue/validate/revoke), migration 0006 — PR #381 - [x] refactor(api): Phase 5 —
api/data/seed.jsoncanonical static fallback for all content,seed.pylru_cacheloader,ProjectPhaseORM model (FK to projects, ordinal, name, description), migration 0005 replacestimeline_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 withAsyncSession | Noneparameter and seed fallback;EmailService(Jinja2 + SMTP) inapi/services/email.py;generate_cv()viaasyncio.create_subprocess_execinapi/services/cv.py;get_optional_db()added toapi/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()inapi/core/exceptions.py; sharedLimiterinapi/core/limiter.py;main.pyshrunk to ~150-linecreate_app()factory — PR #377 - [x] refactor(api): Phase 2 — 11 Pydantic v2 response schemas (
from_attributes=True) inapi/schemas/responses.py; killed all_x_to_yhand-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_dispatchtrigger to release-please workflow — PR #361 - [x] fix(backend): skip Alembic migration when
DATABASE_URLis not set — PR #360 - [x] feat(uigen): annotate content API endpoints with
x-uigen-idfor UIGen grouping — PR #363 - [x] feat(content-api): API-backed portfolio content with
portfolio-content-apifeature flag — new endpointsGET /api/experience,/api/skills,/api/projects,/api/projects/{id},/api/awards,/api/certifications— PR #358 - [x] UIGen v0.6.0:
/api/docsSwagger UI proxy,/admin/configconfig 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-viewhints) + fix code review issues — PR #299 - [x] fix(infra): add
app_config_resource_idto 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.ymlworkflow queries Azure Cost Management (dev + prod), rendersdocs/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
DeploymentActiverace 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/projectsfrom 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.