Files
Portfolio/docs/superpowers/plans/2026-09-01-portfolio-implementation-roadmap.md

153 lines
6.6 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.
# Portfolio Journey Implementation Roadmap
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build Luca Pîslaru’s accessible, pre-rendered portfolio and its optional night-drive experience from the approved design specification.
**Architecture:** Delivery is split into four independently reviewable phases. Phase 1 produces a complete semantic, responsive, pre-rendered portfolio; Phase 2 adds the isolated journey, Three.js, and Web Audio layers; Phase 3 integrates cleared media and enforces accessibility/performance resilience; Phase 4 packages and verifies an atomic Nginx-hosted production release while the source repository remains private.
**Tech Stack:** Vue 3, TypeScript, Vite, `vue/server-renderer`, Three.js, Web Audio API, Vitest, Vue Test Utils, Playwright, axe-core, Node.js 22, npm 10
**Spec:** `docs/superpowers/specs/2026-09-01-portfolio-journey-design.md`
## Global Constraints
- Public identity is exactly **Luca Pîslaru** and **System Administrator & Full-Stack Developer**.
- Essential content, navigation, and contact links work without JavaScript, WebGL, audio, or video.
- The document uses native scrolling and semantic anchors; do not add Vue Router or scroll hijacking.
- Audio starts only after **START THE DRIVE** activation and never gates content.
- The scene is decorative to assistive technology; one concise text description represents it.
- System reduced motion, visitor pause, data saver, and Static mode prevent automatic scene/video loading.
- Never publish a portrait, CV download, GitHub heatmap, fake metric, skill percentage, AI-generated project image, private product name, private repository URL, or sensitive infrastructure detail.
- Public copy uses **Linux**, never a distribution-specific label.
- `PortfolioContent` is the sole owner of subject-matter and rendered accessibility copy.
- The four mutable production inputs are `PortfolioContent`, public asset manifest, `PreparedAssetSet`, and `siteConfig`.
- Initial source control remains private; the launch artifact is an atomic static release served by Nginx.
- Every task follows test-first development and ends with its own reviewable commit after a repository exists.
---
## Phase order
1. [Phase 1 — Foundation, content, and semantic SSR](2026-09-01-portfolio-phase-1-foundation.md)
2. [Phase 2 — Journey, scene, and audio](2026-09-01-portfolio-phase-2-journey.md)
3. [Phase 3 — Media, accessibility, resilience, and performance](2026-09-01-portfolio-phase-3-quality.md)
4. [Phase 4 — Security, packaging, and deployment](2026-09-01-portfolio-phase-4-release.md)
## Specification coverage matrix
| Specification sections | Owning plan/tasks |
|---|---|
| §1–3 product, goals, audience, evidence balance | Phase 1 Tasks 3–7; Phase 3 Task 6 |
| §4 identity, privacy, approvals, contact | Phase 1 Tasks 2–4; Phase 3 Task 1; Phase 4 Tasks 2–3 |
| §5 journey/page content | Phase 1 Tasks 3–5 |
| §6 visual direction | Phase 1 Task 5; Phase 2 Tasks 4–5; Phase 3 Task 6 |
| §7 motion/navigation/signs | Phase 2 Tasks 1–3 and 7 |
| §8 audio | Phase 2 Task 6; Phase 3 Tasks 3–4 |
| §9 responsive/reduced/static | Phase 1 Task 5; Phase 2 Tasks 3, 5, and 7; Phase 3 Task 3 |
| §10 accessibility | Phase 1 Tasks 4–7; Phase 3 Tasks 2–3 and 6 |
| §11 architecture/SSR/lifecycles | Phase 1 Tasks 1–6; Phase 2 Tasks 3–6 |
| §12 data flow/formulas | Phase 2 Tasks 1–3 |
| §13 loading/resilience/quality | Phase 2 Tasks 3–7; Phase 3 Tasks 2 and 4 |
| §14 performance | Phase 3 Task 5 |
| §15 SEO | Phase 1 Task 6; Phase 4 Tasks 1 and 5 |
| §16 security/hosting/supply chain | Phase 4 Tasks 1–5 |
| §17 reference/license | Phase 2 Task 4; Phase 3 Task 1; Phase 4 Task 5 |
| §18 test strategy | Phase 1 Task 7; Phase 2 Task 7; Phase 3 Tasks 3–6; Phase 4 Tasks 3–5 |
| §19 acceptance gates | Phase 3 completion checkpoint; Phase 4 completion checkpoint |
| §20 implementation boundary | This roadmap and its four phase order |
## Locked file structure
```text
.
├── config/
│ └── site.preview.json
├── content/
│ ├── public/portfolio-content.json
│ └── public/asset-manifest.json
├── docs/
│ ├── accessibility/
│ ├── deployment/
│ ├── performance/
│ └── superpowers/{plans,specs}/
├── inputs/prepared-assets/
├── public/assets/
├── scripts/
│ ├── prerender.mjs
│ ├── prepare-assets.mjs
│ ├── verify-artifacts.mjs
│ ├── build-release.mjs
│ └── smoke-production.mjs
├── src/
│ ├── App.vue
│ ├── app.ts
│ ├── entry-client.ts
│ ├── entry-server.ts
│ ├── audio/
│ ├── components/
│ ├── composables/
│ ├── content/
│ ├── journey/
│ ├── scene/
│ ├── security/
│ └── styles/
├── tests/
│ ├── browser/
│ ├── fixtures/
│ ├── integration/
│ └── unit/
├── index.html
├── nginx.portfolio.conf.example
├── package.json
├── playwright.config.ts
├── tsconfig.json
├── vite.config.ts
└── vitest.config.ts
```
## Cross-phase interfaces
```ts
export interface ProductionInputs {
content: PortfolioContent;
assets: PublicAssetManifest;
preparedAssetRoot: URL;
site: SiteConfig;
}
export interface JourneySnapshot {
activeSectionId: SectionId;
routeProgress: number;
driveSpeed: number;
acceleration: number;
sign: SignSnapshot | null;
chapter: EnvironmentChapter;
arrived: boolean;
}
export interface SceneController {
start(signal: AbortSignal): Promise<void>;
update(snapshot: JourneySnapshot): void;
setPaused(paused: boolean): void;
snapshot(): SceneLifecycleState;
subscribe(listener: (state: SceneLifecycleState) => void): () => void;
dispose(): void;
}
export interface AudioController {
startFromGesture(): Promise<void>;
setMuted(muted: boolean): void;
setVolume(volume: number): void;
setIntensity(intensity: number): void;
suspend(): Promise<void>;
dispose(): Promise<void>;
}
```
Later phases may extend these types with discriminated state unions, but they must not rename or bypass these boundaries.
## Phase completion rule
A phase is complete only when its targeted unit, SSR, browser, accessibility, and artifact tests pass; its generated output contains no private names or source paths; and the next phase can consume its documented interfaces without reaching into private module state.