153 lines
6.6 KiB
Markdown
153 lines
6.6 KiB
Markdown
# 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.
|