docs: add approved portfolio design and plans
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user