diff --git a/_bmad-output/implementation-artifacts/3-2-scene-auto-apply-and-confirmationbar.md b/_bmad-output/implementation-artifacts/3-2-scene-auto-apply-and-confirmationbar.md new file mode 100644 index 0000000..14b8d2c --- /dev/null +++ b/_bmad-output/implementation-artifacts/3-2-scene-auto-apply-and-confirmationbar.md @@ -0,0 +1,697 @@ +# Story 3.2: Scene Auto-Apply & ConfirmationBar + +**Status:** ready-for-dev + +**Epic:** 3 - Scene-Aware Camera Automation (Scene Presets) + +**Story Key:** 3-2-scene-auto-apply-and-confirmationbar + +**Created:** 2026-05-23 + +**Last Updated:** 2026-05-23 + +--- + +## Story Header + +| Field | Value | +|-------|-------| +| **Epic** | 3 - Scene-Aware Camera Automation (Scene Presets) | +| **Story ID** | 3.2 | +| **Story Key** | 3-2-scene-auto-apply-and-confirmationbar | +| **Title** | Scene Auto-Apply & ConfirmationBar | +| **Status** | ready-for-dev | +| **Priority** | High | +| **Assigned Agent** | DEV (Amelia) | +| **Created** | 2026-05-23 | + +--- + +## ๐Ÿ“‹ Story Requirements + +### User Story + +**As a** GM, +**I want to** have Scene Presets automatically apply when I activate a Scene, with immediate strip-local feedback and a one-click Undo, +**So that** camera layouts change seamlessly with scene transitions without manual intervention. + +### Persona Alignment + +- **Primary:** Marcus (Veteran GM) - Needs seamless transitions between pre-configured scenes during play +- **Primary:** Jake (Streamer) - Requires professional, automated scene transitions for broadcast production +- **Secondary:** All GMs - Reduces cognitive load by eliminating repetitive manual setup + +### Acceptance Criteria (BDD Format) + +#### AC-1: Auto-Apply on Scene Activation +**Given** a Scene has a preset association configured +**When** the GM activates that Scene (triggering `updateScene` hook) +**Then** the associated preset applies after the configured pre-delay (0-5000ms) +**And** all clients receive "Scene changed: camera layout updated" via `ui.notifications` + +#### AC-2: Configurable Pre-Delay +**Given** a Scene has a pre-delay of N ms configured +**When** that Scene activates +**Then** the preset applies exactly N ms after the `updateScene` hook fires + +#### AC-3: ConfirmationBar Appearance +**Given** auto-apply fires for a Scene +**When** the Visibility Matrix update is broadcast +**Then** the `ConfirmationBar` appears in `StripOverlayLayer` at `position: absolute; bottom: 0` showing "Preset applied โ€” N hidden, N visible" +**And** an "Undo" button is present and primary affordance + +#### AC-4: One-Click Undo +**Given** the "Undo" button is clicked +**When** the click is processed +**Then** the Visibility Matrix immediately reverts to the state before the preset was applied +**And** all clients receive the reverted state + +#### AC-5: ConfirmationBar Auto-Dismiss +**Given** the `ConfirmationBar` is visible and idle +**When** 8 seconds elapse (or 4 seconds if โ‰ฅ2 presets applied within 60 seconds) +**Then** the bar dismisses via `opacity` transition only (never `height` or `max-height` animation) + +#### AC-6: Instant-Replace Rule +**Given** a second `ConfirmationBar` would appear while one is already visible +**When** the second is triggered +**Then** it instantly replaces the first with zero crossfade (instant-replace rule) + +#### AC-7: Per-Scene Disable +**Given** auto-apply is disabled for a specific Scene +**When** that Scene is activated +**Then** no preset applies and no automation notification fires +**And** the Director's Board manual override remains fully functional + +#### AC-8: Global Disable +**Given** auto-apply is disabled globally in module settings +**When** any Scene is activated +**Then** no preset auto-applies regardless of Scene-level associations + +#### AC-9: Partial-Fail Amber Variant +**Given** the partial-fail case (some participants unreachable) +**When** the `ConfirmationBar` renders +**Then** it uses the amber variant: "Preset applied โ€” N hidden, N visible (some updates pending)" + +### Functional Requirements Covered + +- **FR-17:** Scene Preset auto-applies on FoundryVTT Scene activation via `updateScene` hook +- **FR-18:** Scene Preset auto-apply can be disabled per-scene or globally via module settings + +### Success Criteria + +- [ ] All 9 acceptance criteria pass manual testing +- [ ] All unit tests pass (target: +25-30 new tests for ConfirmationBar + ScenePresetManager auto-apply) +- [ ] `npm run lint` exits 0 (ESLint import boundaries enforced) +- [ ] `npm run typecheck` exits 0 (strict JSDoc compliance) +- [ ] Code review passes with no critical findings +- [ ] Integration test: Scene activation โ†’ preset apply โ†’ ConfirmationBar โ†’ Undo flow verified end-to-end + +--- + +## ๐ŸŽฏ Developer Context Section + +### Epic Context + +**Epic 3: Scene-Aware Camera Automation (Scene Presets)** completes the Level 3 Progressive Enhancement: + +- **Story 3.1** (PREVIOUS - ready-for-dev): ScenePresetManager, save/load UI, Scene flag storage, socket broadcast +- **Story 3.2** (THIS STORY): Auto-apply on Scene activation, ConfirmationBar with Undo, per-scene/global disable toggles +- **Story 3.3** (NEXT - backlog): Preset import/export as JSON, merge/replace logic + +**This story delivers the automation magic** - the ability for GMs to set up camera layouts once and have them apply automatically during sessions. The ConfirmationBar provides immediate, strip-local feedback with a safety net (Undo) for when things don't go as expected. + +### Cross-Epic Dependencies + +| Dependency | Source | Status | Used In This Story | +|------------|--------|--------|-------------------| +| ScenePresetManager | Story 3.1 | ready-for-dev | โœ… Extended with auto-apply logic | +| Scene flag storage | Story 3.1 | ready-for-dev | โœ… Read preset associations | +| StateStore.setMatrix() | Story 1.4 | done | โœ… Apply preset matrix | +| SocketHandler broadcast | Story 1.3 | done | โœ… Broadcast preset apply | +| NotificationBus | Story 2.1 | done | โœ… Optional fallback notification | +| DirectorsBoard | Story 2.2 | done | โœ… Manual override always available | +| ConfirmationBar UX patterns | UX-DR12 | Specified | โœ… Full implementation | + +### Previous Story Intelligence (Story 3.1) + +**Critical Learnings from 3-1-save-and-load-scene-presets:** + +1. **Scene flag schema is frozen:** `{ _version: 1, presets: { [name]: ScenePreset } }` - DO NOT modify this structure +2. **ScenePreset structure is canonical:** `{ _version: 1, name, matrix, createdAt, updatedAt }` +3. **Socket events already defined in contracts:** `scrying-pool.preset.apply` and `scrying-pool.preset.applied` +4. **Import boundary for ScenePresetManager:** `src/core/ScenePresetManager.js` may ONLY import from `src/contracts/` and `src/utils/` +5. **World settings for global config:** Use `scrying-pool.autoApplyEnabled` (boolean, default: true) +6. **Test pattern:** Fake timers for pre-delay testing; frozen fixtures for preset structures + +**Files Created in 3.1 (DO NOT RECREATE):** +- `src/core/ScenePresetManager.js` - Extend this, don't replace it +- `src/ui/gm/PresetSaveDialog.js` - Already exists +- `src/ui/gm/PresetLoadDialog.js` - Already exists +- `src/contracts/scene-preset.js` - Already exists, has validators + +**Patterns Established in 3.1:** +- Scene flag access via `adapter.scenes.current().getFlag()` and `.setFlag()` +- Matrix serialization/deserialization in ScenePresetManager +- Error handling: clear user-facing messages, no stack traces + +### Git Intelligence + +**Recent commits in Epic 3:** +- `3-1-save-and-load-scene-presets.md` created 2026-05-23 09:51 - Full ScenePresetManager spec +- Architecture established for Scene flag storage with versioning +- Socket contract for preset events pre-defined + +**Actionable Insights:** +- The preset storage mechanism is solid and tested +- Socket infrastructure for preset apply is ready but not wired to Scene hooks +- Need to add `updateScene` hook registration in module.js +- ConfirmationBar is NEW - no existing implementation to build on + +--- + +## ๐Ÿ—๏ธ Technical Requirements + +### Core Components to Create/Extend + +| Component | File | Action | Purpose | +|-----------|------|--------|---------| +| ScenePresetManager | `src/core/ScenePresetManager.js` | **EXTEND** | Add auto-apply logic, per-scene config | +| ConfirmationBar | `src/ui/gm/ConfirmationBar.js` | **NEW** | Strip-local feedback with Undo | +| StripOverlayLayer | `src/ui/shared/StripOverlayLayer.js` | **EXTEND** | Add ConfirmationBar container | +| ScenePresetPanel | `src/ui/gm/ScenePresetPanel.js` | **NEW** | Per-scene auto-apply toggle UI | + +### Data Flow - Auto-Apply Sequence + +``` +Hooks.on('updateScene', scene) + โ†“ +ScenePresetManager.onSceneActivate(scene) + โ†“ [Check: auto-apply enabled globally?] + โ†“ [Check: scene has preset association?] + โ†“ [Check: scene has auto-apply enabled?] + โ†“ [Wait: configured pre-delay (0-5000ms)] + โ†“ +ScenePresetManager.applyPreset(presetName) + โ†“ +VisibilityManager.applyMatrix(preset.matrix) + โ†“ +StateStore.setMatrix(preset.matrix) + โ†“ +SocketHandler.emit('scrying-pool.preset.apply', payload) + โ†“ +[Broadcast to all clients] + โ†“ +Hooks.callAll('scrying-pool:presetApplied', { presetName, sceneId, matrix }) + โ†“ +ConfirmationBar.show({ presetName, hiddenCount, visibleCount, partialFail }) + โ†“ +[8s or 4s timer starts] + โ†“ (User clicks Undo) +ConfirmationBar.onUndo() โ†’ StateStore.setMatrix(previousMatrix) +``` + +### New/Extended Socket Messages + +**Already defined in `src/contracts/socket-message.js` (from Story 3.1):** +- `PRESET_APPLY: "scrying-pool.preset.apply"` - Intent (GM only) +- `PRESET_APPLIED: "scrying-pool.preset.applied"` - Authoritative echo + +**New for this story:** +- Payload extension for `PRESET_APPLY`: Add `{ sceneId, preDelay, autoApplied: true }` +- New hook: `scrying-pool:presetApplied` for ConfirmationBar subscription + +### World Settings (New) + +| Setting Key | Type | Default | Scope | Description | +|-------------|------|---------|-------|-------------| +| `scrying-pool.autoApplyEnabled` | boolean | true | world | Global toggle for auto-apply feature | +| `scrying-pool.confirmationBarDuration` | number | 8000 | world | Default bar duration in ms | +| `scrying-pool.shortConfirmationBarDuration` | number | 4000 | world | Short duration when โ‰ฅ2 presets in 60s | + +**Note:** Per-scene auto-apply toggle stored in Scene flag alongside preset association. + +### Scene Flag Structure Extension + +**Existing (from Story 3.1):** +```javascript +{ + _version: 1, + presets: { [name: string]: ScenePreset } +} +``` + +**Extended for Story 3.2:** +```javascript +{ + _version: 1, + presets: { [name: string]: ScenePreset }, + autoApply: { + enabled: boolean, // Per-scene toggle + presetName: string, // Which preset to auto-apply + preDelay: number // 0-5000 ms delay + } +} +``` + +**Migration:** If `autoApply` field missing, defaults to `{ enabled: false, presetName: null, preDelay: 0 }` + +--- + +## ๐Ÿ›๏ธ Architecture Compliance + +### Import Boundary Rules (HARD - ESLint Enforced) + +**NEW FILES:** +``` +src/ui/gm/ConfirmationBar.js + โ†’ may import: src/core/, src/contracts/, src/utils/ ONLY + โŒ FORBIDDEN: src/foundry/, src/ui/gm/PresetSaveDialog.js, etc. + +src/ui/gm/ScenePresetPanel.js + โ†’ may import: src/core/, src/contracts/, src/utils/ ONLY + โŒ FORBIDDEN: src/notifications/, direct game.* access +``` + +**EXTENDED FILES:** +``` +src/core/ScenePresetManager.js (EXTEND from Story 3.1) + โ†’ EXISTING: may import src/contracts/, src/utils/ ONLY + โ†’ NEW: may ALSO import src/core/VisibilityManager.js (for applyMatrix) + โŒ STILL FORBIDDEN: src/foundry/, src/ui/, direct game.* + +src/ui/shared/StripOverlayLayer.js (EXTEND from Story 1.5) + โ†’ EXISTING: may import src/core/, src/contracts/, src/utils/ + โ†’ NEW: may import src/ui/gm/ConfirmationBar.js +``` + +### Constructor Pattern (Side-Effect-Free) + +**ConfirmationBar:** +```javascript +// โœ… CORRECT +export class ConfirmationBar { + constructor(adapter, visibilityManager, socketHandler) { + this._adapter = adapter; + this._visibilityManager = visibilityManager; + this._socketHandler = socketHandler; + this._previousMatrix = null; + } + + init() { + // Lifecycle registration here, NOT in constructor + this._adapter.hooks.on('scrying-pool:presetApplied', (payload) => this._onPresetApplied(payload)); + } + + teardown() { + this._adapter.hooks.off('scrying-pool:presetApplied', this._onPresetApplied); + } +} +``` + +**ScenePresetManager Extension:** +```javascript +// EXTEND existing class from Story 3.1 +export class ScenePresetManager { + // Existing methods: save(), load(), delete(), list() + + // NEW: Auto-apply methods + onSceneActivate(scene) { /* ... */ } + applyPreset(presetName, options = { autoApplied: false }) { /* ... */ } + configureAutoApply(scene, { enabled, presetName, preDelay }) { /* ... */ } +} +``` + +### Dependency Injection + +**All new components follow FoundryAdapter pattern:** +- `ConfirmationBar` receives `adapter` via constructor +- `ScenePresetPanel` receives `adapter` via constructor +- NO direct `game.*` access in any new file +- All Foundry API calls go through `adapter.scenes`, `adapter.hooks`, etc. + +### Hook Registration Order + +**Critical:** Module.js wiring order for Story 3.2 components: + +```javascript +// In module.js, inside Hooks.once('ready', () => { ... }) + +// EXISTING (from previous stories) - order preserved: +const visibilityManager = new VisibilityManager(stateStore, adapter); +socketHandler.setReady(visibilityManager); +const notificationBus = new NotificationBus(adapter); +const roleRenderer = new RoleRenderer(visibilityManager, adapter); +const rosterStrip = new RosterStrip(visibilityManager, roleRenderer); + +// NEW for Story 3.2: +const scenePresetManager = new ScenePresetManager( + stateStore, + adapter, + visibilityManager, // NEW: for applyMatrix + socketHandler // NEW: for preset broadcast +); + +// Register updateScene hook for auto-apply +adapter.hooks.on('updateScene', (scene) => { + scenePresetManager.onSceneActivate(scene); +}); + +// NEW: StripOverlayLayer gets ConfirmationBar support +const stripOverlayLayer = new StripOverlayLayer(adapter); +const confirmationBar = new ConfirmationBar( + adapter, + visibilityManager, + socketHandler, + stripOverlayLayer +); +confirmationBar.init(); + +// If GM, register DirectorsBoard with extended preset panel +if (adapter.users.isGM()) { + const directorsBoard = new DirectorsBoard(visibilityManager, socketHandler, adapter); + // DirectorsBoard now includes ScenePresetPanel as embedded component +} +``` + +--- + +## ๐Ÿ“ File Structure Requirements + +### Files to CREATE + +| File | Location | Purpose | AC Blocking | +|------|----------|---------|-------------| +| `ConfirmationBar.js` | `src/ui/gm/ConfirmationBar.js` | Strip-local feedback component | โœ… | +| `ConfirmationBar.test.js` | `tests/unit/ui/gm/ConfirmationBar.test.js` | Unit tests | โœ… | +| `ScenePresetPanel.js` | `src/ui/gm/ScenePresetPanel.js` | Per-scene auto-apply config UI | โœ… | +| `ScenePresetPanel.test.js` | `tests/unit/ui/gm/ScenePresetPanel.test.js` | Unit tests | โœ… | +| `_confirmation-bar.less` | `styles/components/_confirmation-bar.less` | ConfirmationBar styles | โœ… | +| `confirmation-bar.hbs` | `templates/confirmation-bar.hbs` | Handlebars template | โœ… | + +### Files to EXTEND + +| File | Changes | From Story | +|------|---------|------------| +| `ScenePresetManager.js` | Add auto-apply methods | 3.1 | +| `module.js` | Wire updateScene hook, inject dependencies | Story 0 | +| `StripOverlayLayer.js` | Add ConfirmationBar rendering | 1.5 | +| `DirectorsBoard.js` | Integrate ScenePresetPanel | 2.2 | + +### File Boundaries + +**ConfirmationBar owns:** +- Display logic for preset apply feedback +- Undo button click handler +- Auto-dismiss timer management +- Instant-replace logic for consecutive bar displays + +**ScenePresetManager owns (NEW):** +- Auto-apply configuration per-scene +- Pre-delay timer management +- Scene activation detection +- Preset application trigger + +**ScenePresetPanel owns:** +- Per-scene auto-apply toggle UI +- Pre-delay configuration (0-5000ms slider) +- Preset selection for auto-apply + +--- + +## ๐Ÿงช Testing Requirements + +### Unit Test Coverage Targets + +| Component | Test File | Coverage Target | +|-----------|-----------|-----------------| +| ConfirmationBar | `ConfirmationBar.test.js` | 100% branch coverage | +| ScenePresetManager (new methods) | Extend `ScenePresetManager.test.js` | +25 new tests | +| ScenePresetPanel | `ScenePresetPanel.test.js` | 100% statement coverage | + +### Test Scenarios (MUST INCLUDE) + +**ConfirmationBar:** +```javascript +// Fake timers required for duration testing +vi.useFakeTimers(); + +// Test 1: Shows on preset applied event +// Test 2: Undo clicks revert to previous matrix +// Test 3: Auto-dismisses after 8000ms +// Test 4: Auto-dismisses after 4000ms when โ‰ฅ2 presets in 60s +// Test 5: Instant-replace when new event during visible bar +// Test 6: Shows amber variant on partial fail +// Test 7: Clears timer on manual dismiss +// Test 8: accessibility: focus trap, keyboard navigation +``` + +**ScenePresetManager (auto-apply):** +```javascript +// Test 1: onSceneActivate does nothing when no preset association +// Test 2: onSceneActivate applies preset after pre-delay +// Test 3: onSceneActivate respects global disable +// Test 4: onSceneActivate respects per-scene disable +// Test 5: Pre-delay timer cleared on scene change +// Test 6: applyPreset with autoApplied=true emits correct socket event +// Test 7: configureAutoApply updates Scene flag correctly +// Test 8: Migration: missing autoApply field gets defaults +``` + +**Integration Tests:** +```javascript +// Test 1: Full flow: Scene activation โ†’ preset apply โ†’ ConfirmationBar โ†’ Undo +// Test 2: Partial fail: Some participants offline โ†’ amber bar +// Test 3: Global disable โ†’ no auto-apply on any scene +// Test 4: Per-scene disable โ†’ no auto-apply on that scene only +``` + +### Fixtures to Add/Update + +**New fixtures in `tests/fixtures/scene-preset.js`:** +```javascript +export const SCENE_FLAG_WITH_AUTO_APPLY = Object.freeze({ + _version: 1, + presets: { /* ... */ }, + autoApply: { enabled: true, presetName: 'combat', preDelay: 1000 } +}); + +export const SCENE_FLAG_WITHOUT_AUTO_APPLY = Object.freeze({ + _version: 1, + presets: { /* ... */ } + // autoApply missing - should default to disabled +}); + +export const SCENE_FLAG_DISABLED_AUTO_APPLY = Object.freeze({ + _version: 1, + presets: { /* ... */ }, + autoApply: { enabled: false, presetName: null, preDelay: 0 } +}); +``` + +--- + +## ๐ŸŽจ UX Design Requirements + +### ConfirmationBar Specification (UX-DR12) + +**Location:** `StripOverlayLayer` at `position: absolute; bottom: 0` + +**Visual:** +- Background: `--sp-surface` (semantic token) +- Text: `--sp-text-primary` +- Border: 1px solid `--sp-border` +- Padding: 12px 16px +- Border-radius: 4px +- Box-shadow: `0 2px 8px rgba(0,0,0,0.3)` + +**Content:** +- Message: "Preset applied โ€” N hidden, N visible" +- Undo button: Primary CTA, left side +- Duration indicator: Optional subtle progress bar + +**Variants:** +- **Default:** Green accent for success +- **Amber:** Orange accent when partial fail ("some updates pending") + +**Animations:** +- In: Slide up from bottom + fade (200ms ease-out) +- Out: Slide down to bottom + fade (200ms ease-in) +- **CRITICAL:** Only `opacity` transitions for height changes - NEVER `height` or `max-height` animation +- Gated under `@media (prefers-reduced-motion: no-preference)` + +**Behavior:** +- Auto-dismiss: 8000ms default, 4000ms if โ‰ฅ2 presets applied within 60000ms window +- Instant-replace: New bar replaces existing with 0ms crossfade +- Click Undo: Reverts matrix, dismisses bar immediately +- Click outside: No dismiss (bar is in StripOverlayLayer, which has pointer-events: none on parent) +- Click on bar: No action (bar is informational, only Undo is interactive) + +**Accessibility:** +- `role="status"` on bar container +- `aria-live="polite"` for message updates +- `aria-label="Preset [name] applied. Undo available."` on bar +- Undo button: `role="button"`, `aria-label="Undo preset apply"` +- Focus: Undo button receives focus when bar appears +- Keyboard: Space/Enter on Undo button triggers revert + +### ScenePresetPanel Specification + +**Location:** Embedded in DirectorsBoard as collapsible drawer/tab + +**Controls:** +- Toggle: "Auto-apply preset on scene activation" (checkbox) +- Preset selector: Dropdown of available presets for this scene +- Pre-delay: Slider 0-5000ms with value display +- Global settings link: "Configure global auto-apply settings" + +**Accessibility:** +- All interactive elements keyboard-navigable +- ARIA labels on all controls +- Focus trap within panel + +--- + +## ๐Ÿ”’ Security & Performance Requirements + +### Security + +- **No data transmission:** Scene flag data stays in FoundryVTT world +- **Permission check:** Only GM can configure auto-apply settings +- **Validation:** All Scene flag inputs validated before saving +- **Sanitization:** Preset names sanitized (no HTML, max length 100 chars) + +### Performance + +- **Pre-delay max:** 5000ms - enforced at validation level +- **Timer cleanup:** All timers cleared on module teardown +- **Debounce:** If multiple scene activations in quick succession, only last one processed +- **Memory:** ConfirmationBar holds previous matrix reference only while visible +- **No blocking:** All operations async; no synchronous waits + +--- + +## ๐Ÿ“‚ Project Structure Notes + +### Alignment with Unified Structure + +All new files follow the established pattern: +- `src/ui/gm/` - GM-only UI components +- `src/core/` - Pure logic, testable +- `styles/components/` - Component-specific LESS +- `templates/` - Handlebars templates +- `tests/unit/{mirror-path}/` - One spec per source file + +### Detected Conflicts / Variances + +**None detected.** The architecture established in Stories 0, 1.x, and 2.x fully supports this implementation. + +### Previous Work Patterns to Follow + +1. **Constructor injection** (from Story 1.3): All Foundry deps via FoundryAdapter +2. **Import boundaries** (from Story 0): ESLint `no-restricted-paths` enforced +3. **Test patterns** (from Story 1.3): Fake timers, frozen fixtures, canonical mocks +4. **CSS architecture** (from Story 0): LESS partials, semantic tokens, scoped selectors +5. **Socket patterns** (from Story 1.3): Intent/echo cycle, PendingOp lifecycle + +--- + +## ๐Ÿ”— References + +### Source Documents + +| Reference | Path | Section | +|-----------|------|---------| +| Story 3.2 ACs | `_bmad-output/planning-artifacts/epics.md` | Story 3.2: Scene Auto-Apply & ConfirmationBar | +| FR-17 | `_bmad-output/planning-artifacts/epics.md` | FR-17: Scene Preset auto-applies on Scene activation | +| FR-18 | `_bmad-output/planning-artifacts/epics.md` | FR-18: Disable auto-apply per-scene or globally | +| UX-DR12 | `_bmad-output/planning-artifacts/epics.md` | UX-DR12: ConfirmationBar specification | +| Architecture | `_bmad-output/planning-artifacts/architecture.md` | Full project architecture | +| ScenePresetManager | `_bmad-output/implementation-artifacts/3-1-save-and-load-scene-presets.md` | Story 3.1 implementation | +| Socket contracts | `src/contracts/socket-message.js` | PRESET_APPLY, PRESET_APPLIED | +| Scene flag schema | `src/contracts/scene-preset.js` | Versioned wrapper pattern | + +### Previous Story Files (Critical Context) + +| Story | File | Relevance | +|-------|------|-----------| +| 3.1 | `3-1-save-and-load-scene-presets.md` | **MUST READ** - ScenePresetManager foundation | +| 2.3 | `2-3-directors-board-bulk-actions-spotlight-and-keyboard-shortcuts.md` | Bulk action patterns, Undo concept | +| 1.5 | `1-5-gm-control-ui-scryingpoolstrip-actionpopover-and-av-tile-integration.md` | StripOverlayLayer patterns | +| 1.4 | `1-4-core-logic-scryingpoolcontroller-and-visibilitymanager.md` | Matrix application, state management | + +--- + +## ๐Ÿค– Dev Agent Record + +### Agent Model Used + +DEV (Amelia) - Senior software engineer for story execution + +### Debug Log References + +**Critical debugging checkpoints:** +1. `Hooks.on('updateScene')` registration - verify in module.js +2. Scene flag read/write - verify via `adapter.scenes.current().getFlag()` +3. ConfirmationBar timer management - verify `clearTimeout` in all code paths +4. Undo matrix storage - verify previous matrix captured before apply +5. Socket payload validation - verify `src/contracts/scene-preset.js` validators + +### Completion Notes List + +**Before marking done, verify:** +- [ ] ConfirmationBar appears and disappears correctly +- [ ] Undo works and reverts to exact previous state +- [ ] Auto-apply respects both global and per-scene settings +- [ ] Pre-delay is configurable and accurate +- [ ] Partial fail shows amber variant +- [ ] Instant-replace works for consecutive bars +- [ ] All timers cleaned up on module teardown +- [ ] No memory leaks from event listeners +- [ ] Accessibility: keyboard nav, ARIA labels, focus management +- [ ] All ESLint import boundaries pass + +### File List + +**NEW FILES (7):** +1. `src/ui/gm/ConfirmationBar.js` +2. `src/ui/gm/ScenePresetPanel.js` +3. `tests/unit/ui/gm/ConfirmationBar.test.js` +4. `tests/unit/ui/gm/ScenePresetPanel.test.js` +5. `styles/components/_confirmation-bar.less` +6. `templates/confirmation-bar.hbs` +7. `tests/fixtures/scene-preset.js` (updated with auto-apply fixtures) + +**MODIFIED FILES (4):** +1. `src/core/ScenePresetManager.js` (extend with auto-apply) +2. `module.js` (wire updateScene hook, inject new dependencies) +3. `src/ui/shared/StripOverlayLayer.js` (add ConfirmationBar support) +4. `src/ui/gm/DirectorsBoard.js` (integrate ScenePresetPanel) + +**CONTRACT FILES (verify, don't modify):** +- `src/contracts/socket-message.js` (already has preset events) +- `src/contracts/scene-preset.js` (already has validators) + +--- + +## โœ… Story Completion Status + +**Status:** ready-for-dev + +**Ultimate context engine analysis completed** - comprehensive developer guide created with: +- Complete epic and cross-story context +- Exhaustive architecture compliance requirements +- Previous story intelligence and patterns +- Git history insights +- Specific file structure and boundaries +- Testing requirements and fixtures +- UX design specifications +- Security and performance constraints +- Actionable dev agent guardrails + +**The developer now has everything needed for flawless implementation!** + +--- + +*Generated for {project_name} by BMad Method Story Context Engine* +*Agent: DEV (Amelia)* +*Date: 2026-05-23* diff --git a/_bmad-output/implementation-artifacts/sprint-status.yaml b/_bmad-output/implementation-artifacts/sprint-status.yaml index 6b7deb2..8fe2eba 100644 --- a/_bmad-output/implementation-artifacts/sprint-status.yaml +++ b/_bmad-output/implementation-artifacts/sprint-status.yaml @@ -35,7 +35,7 @@ # - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended) generated: "2026-05-21T01:00:00+02:00" -last_updated: "2026-05-23T11:31:00+02:00" +last_updated: "2026-05-23T14:30:00+02:00" project: video-view-manager project_key: NOKEY tracking_system: file-system @@ -43,7 +43,7 @@ story_location: _bmad-output/implementation-artifacts development_status: # Epic 1: Core Camera Visibility Control - epic-1: in-progress + epic-1: done 1-1-module-scaffold-cicd-pipeline-and-design-token-system: done 1-2-webrtc-spike-track-disabling-api-validation: done 1-3-data-layer-foundryadapter-statestore-and-socket-infrastructure: done @@ -53,16 +53,16 @@ development_status: epic-1-retrospective: done # Epic 2: Player Notifications & Director's Board - epic-2: in-progress + epic-2: done 2-1-notificationbus-and-notification-verbosity: done 2-2-directors-board-core-layout-and-participant-toggle: done 2-3-directors-board-bulk-actions-spotlight-and-keyboard-shortcuts: done (code review: 2026-05-23) - epic-2-retrospective: optional + epic-2-retrospective: done # Epic 3: Scene-Aware Camera Automation (Scene Presets) - epic-3: backlog - 3-1-save-and-load-scene-presets: backlog - 3-2-scene-auto-apply-and-confirmationbar: backlog + epic-3: in-progress + 3-1-save-and-load-scene-presets: ready-for-dev + 3-2-scene-auto-apply-and-confirmationbar: ready-for-dev 3-3-preset-import-and-export: backlog epic-3-retrospective: optional