8.9 KiB
8.9 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-foundation-dashboard | 01 | execute | 1 |
|
true |
|
|
Purpose: This infrastructure enables all subsequent dashboard features. Without these foundations, individual components cannot share data or communicate with the backend.
Output: Working store, API client, mode detection, and test setup that subsequent plans build upon.
<execution_context> @./.opencode/get-shit-done/workflows/execute-plan.md @./.opencode/get-shit-done/templates/summary.md </execution_context>
@.planning/phases/01-foundation-dashboard/01-CONTEXT.md @.planning/phases/01-foundation-dashboard/01-RESEARCH.md @.planning/ROADMAP.md @.planning/REQUIREMENTS.md @sample_interface/src/app/App.tsxKey Implementation Details
Mode Detection:
- Port 8080 → kiosk mode (fixed 1024x600)
- Port 9090 → remote mode (responsive Full HD)
- Use
window.location.portfor detection
Sensor Data Structure:
interface SensorData {
rainfall: {
today: number;
hourly: number;
monthlyAcc: number;
yearlyAcc: number;
};
voltage: {
solar: number;
battery: number;
batteryStatus: 'HIGH' | 'LOW';
};
station: {
id: string;
version: string;
};
communication: {
asu: number;
dBm: number;
percentage: number;
};
timestamp: string;
}
Polling Strategy:
- Default 5 second interval
- Configurable via settings
- Pause when document.hidden
- Use AbortController for cleanup
2. Create src/test/setup.ts:
- Import @testing-library/jest-dom matchers
- Configure cleanup after each test
- Add mock for window.matchMedia if needed
3. Update package.json scripts:
- "test": "vitest run"
- "test:watch": "vitest"
- Add devDependencies: vitest, @testing-library/react, @testing-library/jest-dom, jsdom
4. Run `pnpm install` to add dependencies
npm test -- --run 2>&1 | head -20
Test infrastructure ready, `npm test` runs successfully
task 2: Create Zustand sensor store
src/app/stores/sensorStore.ts, src/app/stores/__tests__/sensorStore.test.ts
- Store initializes with default/mock data
- setSensorData updates all fields
- Store can be subscribed to
- Selectors work for derived data
1. Install zustand: `pnpm add zustand`
2. Create src/app/stores/sensorStore.ts:
- Define SensorData interface per context
- Create store with initial state
- Export useSensorStore hook
- Add actions: setSensorData, updatePollingInterval
- Include selector for last update timestamp
3. Create tests verifying:
- Store initializes with defaults
- setSensorData updates state
- Subscribers receive updates
npm test -- --run stores/sensorStore 2>&1 | grep -E "(PASS|FAIL|✓|✗)"
Zustand store created with SensorData interface, tests pass
task 3: Create API client with mock fallback
src/app/api/client.ts, src/app/api/__tests__/client.test.ts
- fetchSensorData returns SensorData
- On API failure, returns mock data
- Uses AbortController for cancellation
- Logs errors but doesn't throw
1. Create src/app/api/client.ts:
- Define API endpoint URL (configurable)
- Create fetchSensorData function with AbortSignal
- Create mockSensorData generator with realistic values
- Implement fallback: try API → catch → return mock
- Add request timeout (5s)
2. Create tests verifying:
- Returns data on successful fetch
- Returns mock on network error
- Respects AbortController
- Mock data has valid structure
npm test -- --run api/client 2>&1 | grep -E "(PASS|FAIL|✓|✗)"
API client with mock fallback created, tests pass
task 4: Implement port-based mode detection
src/app/App.tsx, src/app/hooks/useDisplayMode.ts
- Port 8080 → returns 'kiosk'
- Port 9090 → returns 'remote'
- Other ports → defaults to 'kiosk'
- Mode available via hook
1. Create src/app/hooks/useDisplayMode.ts:
- Read window.location.port
- Return 'kiosk' for 8080, 'remote' for 9090
- Default to 'kiosk' for other ports
- Memoize result (port won't change)
2. Update src/app/App.tsx:
- Import useDisplayMode hook
- Pass mode to DashboardLayout
- Initialize data polling on mount
- Clean up polling on unmount (useEffect cleanup)
- Add data-attr or class based on mode for CSS targeting
grep -n "useDisplayMode\|window.location.port\|displayMode" src/app/App.tsx src/app/hooks/useDisplayMode.ts 2>/dev/null | head -20
Mode detection implemented, App.tsx uses display mode hook
task 5: Set up data polling with cleanup
src/app/App.tsx, src/app/hooks/useSensorPolling.ts
- Polls every 5 seconds by default
- Pauses when document.hidden
- Resumes when visible again
- Properly cleans up on unmount
1. Create src/app/hooks/useSensorPolling.ts:
- Accept polling interval (ms) parameter, default 5000
- Use setInterval for polling
- Listen for visibilitychange event
- Pause interval when document.hidden
- Resume when visible
- Use AbortController per fetch
- Return cleanup function
2. Update App.tsx:
- Call useSensorPolling in component
- Pass polling interval from settings (or default)
- Ensure cleanup happens on unmount
grep -n "useSensorPolling\|setInterval\|visibilitychange\|AbortController" src/app/App.tsx src/app/hooks/useSensorPolling.ts 2>/dev/null | head -20
Polling implemented with visibility awareness and cleanup
After completing all tasks:
1. Run `npm test` — all tests should pass
2. Check store exists: `ls src/app/stores/sensorStore.ts`
3. Check API client exists: `ls src/app/api/client.ts`
4. Check mode detection: `grep "useDisplayMode" src/app/App.tsx`
5. Verify no console errors on build: `npm run build 2>&1 | grep -i error || echo "Build clean"`
<success_criteria>
- Zustand store with SensorData interface exists and is tested
- API client with mock fallback exists and is tested
- Port-based mode detection works (8080=kiosk, 9090=remote)
- Data polling with cleanup and visibility awareness implemented
- Test infrastructure ready (
npm testruns) - All files committed </success_criteria>