feat(L+M): configurable dashboard widget system + test framework

Phase L: Dashboard widget system
- Migration 046: dashboard_configs table (user/tenant/role fallback cascade)
- DashboardConfig model + dashboard_service with get/upsert per-user and tenant-default
- API router: GET/PUT /api/dashboard/config, GET/PUT /api/dashboard/tenant-default
- Frontend: 5 widget components (ProductionStats, QueueStatus, RecentRenders, CostOverview, WorkerStatus)
- DashboardGrid with API-backed config, DashboardCustomizeModal (checkbox selection, save/cancel)
- Dashboard.tsx: widget grid + analytics section (privileged users)
- Admin.tsx: restructured with new section order and Maintenance 2-col grid

Phase M: Test framework
- Backend: pytest-asyncio + pytest-cov + factory-boy in pyproject.toml
- conftest.py: excel_dir fixtures + async DB fixtures + mock storage/celery stubs
- Domain tests: billing_service, cache_service, notifications_service, imports_sanity
- Integration: test_api_health.py smoke test (requires running backend)
- Frontend: vitest + @testing-library/react + msw added to package.json
- vite.config.ts: test block (jsdom + globals + setupFiles)
- tsconfig.json: exclude src/__tests__ from main tsc (test runner handles its own types)
- MSW handlers for /api/auth/me, Billing.test.tsx, formatters.test.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 21:50:07 +01:00
parent 19c15adbee
commit bfc0050580
38 changed files with 4210 additions and 13 deletions
+14 -3
View File
@@ -6,16 +6,20 @@
"scripts": {
"dev": "vite --host 0.0.0.0 --port 5173",
"build": "tsc && vite build",
"preview": "vite preview"
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage"
},
"dependencies": {
"@react-three/drei": "^9.102.3",
"@xyflow/react": "^12.0.0",
"@react-three/fiber": "^8.16.2",
"@tanstack/react-query": "^5.28.4",
"@tanstack/react-table": "^8.14.0",
"@xyflow/react": "^12.0.0",
"axios": "^1.6.8",
"clsx": "^2.1.0",
"get-stream": "^9.0.1",
"lucide-react": "^0.363.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@@ -28,14 +32,21 @@
"zustand": "^4.5.2"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/react": "^18.2.74",
"@types/react-dom": "^18.2.23",
"@types/three": "^0.163.0",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "^1.6.1",
"autoprefixer": "^10.4.19",
"jsdom": "^24.1.3",
"msw": "^2.12.10",
"postcss": "^8.4.38",
"tailwindcss": "^3.4.3",
"typescript": "^5.4.3",
"vite": "^5.2.6"
"vite": "^5.2.6",
"vitest": "^1.6.1"
}
}