From c3c2afd983fbe4018d995606ab9f29ee9614540c Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 10 Mar 2026 01:53:58 +0100 Subject: [PATCH] feat(dashboard): claude history dashboard --- .claude/dashboard/README.md | 92 + .claude/dashboard/architecture.md | 70 + .claude/dashboard/build.md | 148 + .claude/dashboard/components.md | 136 + .claude/dashboard/patterns.md | 241 ++ .claude/dashboard/routing.md | 183 + .claude/dashboard/stack.md | 100 + .claude/dashboard/state.md | 187 + .claude/dashboard/structure.md | 102 + .../001-assistant-personal-ai-master.md | 286 ++ .../002-assistant-phase1-detailed.md | 577 +++ .../assistant/003-assistant-phase2-roadmap.md | 612 +++ .../assistant/004-assistant-phase3-roadmap.md | 778 ++++ .../dashboard/001-sleep-recovery-dashboard.md | 160 + .../002-nutrition-hydration-logger.md | 198 + .../dashboard/003-mood-energy-tracker.md | 227 ++ .../004-spending-snapshot-dashboard.md | 267 ++ .../dashboard/005-accountability-network.md | 283 ++ .../ideas/dashboard/006-portfolio-showcase.md | 355 ++ .../dashboard/007-skill-leveling-system.md | 314 ++ .../dashboard/008-relationship-calendar.md | 347 ++ .../dashboard/009-investment-dashboard.md | 293 ++ .../dashboard/010-debt-snowball-tracker.md | 331 ++ .../ideas/dashboard/011-creative-metrics.md | 375 ++ .../dashboard/012-event-coordination-hub.md | 414 ++ .claude/plans/2026-01-10-Dashboard.md | 485 +++ .claude/plans/2026-01-13-badge-progress-ui.md | 67 + .claude/plans/2026-01-13-blocker-detector.md | 77 + .../2026-01-13-critical-path-visualizer.md | 71 + .claude/plans/2026-01-13-decision-log.md | 99 + .../plans/2026-01-13-distraction-tracker.md | 75 + .claude/plans/2026-01-13-energy-heatmap.md | 68 + .claude/plans/2026-01-13-escalation-alerts.md | 159 + .claude/plans/2026-01-13-handoff-compiler.md | 136 + .claude/plans/2026-01-13-kanban-board.md | 74 + .../plans/2026-01-13-micro-celebrations.md | 73 + .../2026-01-13-weekly-review-dashboard.md | 109 + CodeExamples.md | 466 +++ Useful.md | 23 +- findings.md | 152 + pnpm-lock.yaml | 297 +- progress.md | 156 + src/dashboard/.gitignore | 36 + src/dashboard/.npmrc | 1 + src/dashboard/README.md | 58 + src/dashboard/apps/docs/.gitignore | 34 + src/dashboard/apps/docs/README.md | 28 + src/dashboard/apps/docs/app/favicon.ico | Bin 0 -> 8267 bytes src/dashboard/apps/docs/app/globals.css | 26 + src/dashboard/apps/docs/app/layout.tsx | 19 + src/dashboard/apps/docs/app/page.tsx | 103 + src/dashboard/apps/docs/eslint.config.js | 4 + src/dashboard/apps/docs/next-env.d.ts | 6 + src/dashboard/apps/docs/next.config.ts | 9 + src/dashboard/apps/docs/package.json | 34 + src/dashboard/apps/docs/postcss.config.js | 3 + src/dashboard/apps/docs/public/circles.svg | 17 + src/dashboard/apps/docs/public/next.svg | 1 + src/dashboard/apps/docs/public/turborepo.svg | 32 + src/dashboard/apps/docs/public/vercel.svg | 1 + src/dashboard/apps/docs/tsconfig.json | 18 + src/dashboard/apps/server/.env.example | 11 + src/dashboard/apps/server/.gitignore | 8 + src/dashboard/apps/server/README.md | 3 + src/dashboard/apps/server/nitro.config.ts | 8 + src/dashboard/apps/server/package.json | 20 + .../apps/server/server/routes/_ws.ts | 91 + .../apps/server/server/routes/api/health.ts | 10 + .../server/server/routes/api/sync/upload.ts | 69 + .../server/server/routes/api/timers/[id].ts | 85 + .../server/server/routes/api/timers/index.ts | 56 + .../apps/server/server/routes/api/user.ts | 24 + .../apps/server/server/routes/index.ts | 11 + src/dashboard/apps/server/tsconfig.json | 32 + src/dashboard/apps/web-template/.cta.json | 30 + src/dashboard/apps/web-template/.cursorrules | 100 + src/dashboard/apps/web-template/.env.example | 4 + src/dashboard/apps/web-template/.gitignore | 14 + .../apps/web-template/.vscode/settings.json | 35 + src/dashboard/apps/web-template/README.md | 387 ++ .../apps/web-template/components.json | 21 + .../web-template/convex/_generated/api.d.ts | 26 + .../web-template/convex/_generated/api.js | 22 + .../convex/_generated/dataModel.d.ts | 56 + .../convex/_generated/server.d.ts | 142 + .../web-template/convex/_generated/server.js | 89 + .../apps/web-template/convex/schema.ts | 14 + .../apps/web-template/convex/todos.ts | 39 + .../apps/web-template/convex/tsconfig.json | 25 + src/dashboard/apps/web-template/db/init.sql | 14 + .../apps/web-template/neon-vite-plugin.ts | 10 + .../web-template/src/components/Header.tsx | 366 ++ .../src/components/demo.FormComponents.tsx | 153 + .../src/components/demo.chat-area.tsx | 67 + .../src/components/demo.messages.tsx | 51 + .../src/components/example-AIAssistant.tsx | 151 + .../example-GuitarRecommendation.tsx | 37 + .../web-template/src/components/ui/button.tsx | 60 + .../web-template/src/components/ui/input.tsx | 21 + .../web-template/src/components/ui/label.tsx | 21 + .../web-template/src/components/ui/select.tsx | 163 + .../web-template/src/components/ui/slider.tsx | 58 + .../web-template/src/components/ui/switch.tsx | 26 + .../src/components/ui/textarea.tsx | 18 + .../src/components/workos-user.tsx | 41 + .../web-template/src/data/demo-table-data.ts | 46 + .../web-template/src/data/demo.punk-songs.ts | 13 + .../web-template/src/data/example-guitars.ts | 91 + .../web-template/src/db-collections/index.ts | 17 + src/dashboard/apps/web-template/src/db.ts | 13 + src/dashboard/apps/web-template/src/env.ts | 39 + .../src/hooks/demo.form-context.ts | 3 + .../apps/web-template/src/hooks/demo.form.ts | 17 + .../web-template/src/hooks/demo.useChat.ts | 61 + .../src/hooks/useAudioRecorder.ts | 82 + .../apps/web-template/src/hooks/useTTS.ts | 78 + .../apps/web-template/src/hooks/useUser.tsx | 23 + .../src/integrations/convex/provider.tsx | 12 + .../integrations/tanstack-query/devtools.tsx | 6 + .../tanstack-query/root-provider.tsx | 51 + .../src/integrations/trpc/init.ts | 9 + .../src/integrations/trpc/react.ts | 4 + .../src/integrations/trpc/router.ts | 23 + .../src/integrations/workos/provider.tsx | 30 + .../apps/web-template/src/lib/ai-devtools.tsx | 3 + .../src/lib/demo-store-devtools.tsx | 58 + .../apps/web-template/src/lib/demo-store.ts | 13 + .../web-template/src/lib/example.ai-hook.ts | 18 + .../src/lib/example.guitar-tools.ts | 38 + .../web-template/src/lib/model-selection.ts | 80 + .../apps/web-template/src/lib/utils.ts | 6 + .../src/lib/vendor-capabilities.ts | 50 + src/dashboard/apps/web-template/src/logo.svg | 12 + .../apps/web-template/src/mcp-todos.ts | 51 + .../apps/web-template/src/routeTree.gen.ts | 784 ++++ .../apps/web-template/src/router.tsx | 24 + .../apps/web-template/src/routes/__root.tsx | 77 + .../web-template/src/routes/api.trpc.$.tsx | 20 + .../routes/demo/api.available-providers.ts | 35 + .../web-template/src/routes/demo/api.image.ts | 74 + .../src/routes/demo/api.mcp-todos.ts | 37 + .../web-template/src/routes/demo/api.names.ts | 10 + .../src/routes/demo/api.structured.ts | 164 + .../src/routes/demo/api.tanchat.ts | 85 + .../src/routes/demo/api.tq-todos.ts | 35 + .../src/routes/demo/api.transcription.ts | 89 + .../web-template/src/routes/demo/api.tts.ts | 75 + .../web-template/src/routes/demo/convex.tsx | 157 + .../src/routes/demo/db-chat-api.ts | 79 + .../web-template/src/routes/demo/db-chat.tsx | 15 + .../src/routes/demo/form.address.tsx | 191 + .../src/routes/demo/form.simple.tsx | 62 + .../web-template/src/routes/demo/image.tsx | 248 ++ .../src/routes/demo/mcp-todos.tsx | 77 + .../web-template/src/routes/demo/neon.tsx | 162 + .../src/routes/demo/start.api-request.tsx | 42 + .../src/routes/demo/start.server-funcs.tsx | 108 + .../src/routes/demo/start.ssr.data-only.tsx | 36 + .../src/routes/demo/start.ssr.full-ssr.tsx | 35 + .../src/routes/demo/start.ssr.index.tsx | 42 + .../src/routes/demo/start.ssr.spa-mode.tsx | 40 + .../web-template/src/routes/demo/store.tsx | 55 + .../src/routes/demo/structured.tsx | 428 ++ .../web-template/src/routes/demo/table.tsx | 328 ++ .../web-template/src/routes/demo/tanchat.css | 228 ++ .../web-template/src/routes/demo/tanchat.tsx | 366 ++ .../src/routes/demo/tanstack-query.tsx | 80 + .../src/routes/demo/trpc-todo.tsx | 73 + .../web-template/src/routes/demo/workos.tsx | 91 + .../src/routes/example.guitars/$guitarId.tsx | 41 + .../src/routes/example.guitars/index.tsx | 50 + .../apps/web-template/src/routes/index.tsx | 101 + .../apps/web-template/src/routes/mcp.ts | 51 + .../apps/web-template/src/styles.css | 138 + .../web-template/src/utils/mcp-handler.ts | 57 + src/dashboard/apps/web/.claude/CLAUDE.md | 122 + .../web/.claude/docs/patterns/type-sharing.md | 215 + .../apps/web/.claude/docs/systems/database.md | 163 + .../apps/web/.claude/docs/systems/events.md | 197 + src/dashboard/apps/web/.cta.json | 30 + src/dashboard/apps/web/.cursorrules | 100 + src/dashboard/apps/web/.env.example | 4 + src/dashboard/apps/web/.gitignore | 14 + src/dashboard/apps/web/.vscode/settings.json | 35 + src/dashboard/apps/web/README.md | 387 ++ src/dashboard/apps/web/components.json | 21 + .../apps/web/convex/_generated/api.d.ts | 26 + .../apps/web/convex/_generated/api.js | 22 + .../apps/web/convex/_generated/dataModel.d.ts | 56 + .../apps/web/convex/_generated/server.d.ts | 142 + .../apps/web/convex/_generated/server.js | 89 + src/dashboard/apps/web/convex/schema.ts | 14 + src/dashboard/apps/web/convex/todos.ts | 39 + src/dashboard/apps/web/convex/tsconfig.json | 25 + src/dashboard/apps/web/db/init.sql | 14 + src/dashboard/apps/web/drizzle.config.ts | 27 + src/dashboard/apps/web/neon-vite-plugin.ts | 10 + src/dashboard/apps/web/package.json | 116 + src/dashboard/apps/web/public/demo-neon.svg | 1 + .../web/public/example-guitar-flowers.jpg | Bin 0 -> 186992 bytes .../web/public/example-guitar-motherboard.jpg | Bin 0 -> 280973 bytes .../apps/web/public/example-guitar-racing.jpg | Bin 0 -> 119559 bytes .../public/example-guitar-steamer-trunk.jpg | Bin 0 -> 135326 bytes .../web/public/example-guitar-superhero.jpg | Bin 0 -> 135722 bytes .../web/public/example-guitar-traveling.jpg | Bin 0 -> 167944 bytes .../web/public/example-guitar-video-games.jpg | Bin 0 -> 96493 bytes .../web/public/example-ukelele-tanstack.jpg | Bin 0 -> 242288 bytes src/dashboard/apps/web/public/favicon.ico | Bin 0 -> 3870 bytes src/dashboard/apps/web/public/logo192.png | Bin 0 -> 5347 bytes src/dashboard/apps/web/public/logo512.png | Bin 0 -> 9664 bytes src/dashboard/apps/web/public/manifest.json | 25 + src/dashboard/apps/web/public/robots.txt | 3 + .../apps/web/public/tanstack-circle-logo.png | Bin 0 -> 265387 bytes .../web/public/tanstack-word-logo-white.svg | 1 + .../apps/web/server/routes/_ws-todo.ts | 86 + .../web/server/routes/api/-events.get.ts.old | 98 + .../apps/web/src/__tests__/api.test.ts | 657 +++ .../apps/web/src/__tests__/drizzle.test.ts | 292 ++ .../apps/web/src/__tests__/events.test.ts | 117 + .../web/src/components/auth/AuthLayout.tsx | 79 + .../web/src/components/auth/cyberpunk.css | 327 ++ .../apps/web/src/components/auth/index.ts | 2 + .../src/components/dashboard/app-sidebar.tsx | 321 ++ .../components/dashboard/dashboard-layout.tsx | 48 + .../web/src/components/dashboard/index.ts | 2 + .../apps/web/src/components/ui/avatar.tsx | 36 + .../apps/web/src/components/ui/badge.tsx | 36 + .../apps/web/src/components/ui/button.tsx | 60 + .../apps/web/src/components/ui/card.tsx | 59 + .../apps/web/src/components/ui/dialog.tsx | 109 + .../web/src/components/ui/dropdown-menu.tsx | 219 + .../web/src/components/ui/feature-card.tsx | 174 + .../apps/web/src/components/ui/input.tsx | 21 + .../apps/web/src/components/ui/label.tsx | 21 + .../web/src/components/ui/scroll-area.tsx | 48 + .../apps/web/src/components/ui/select.tsx | 163 + .../apps/web/src/components/ui/separator.tsx | 26 + .../apps/web/src/components/ui/sheet.tsx | 101 + .../apps/web/src/components/ui/sidebar.tsx | 677 ++++ .../apps/web/src/components/ui/skeleton.tsx | 7 + .../apps/web/src/components/ui/slider.tsx | 58 + .../apps/web/src/components/ui/switch.tsx | 26 + .../apps/web/src/components/ui/textarea.tsx | 18 + .../apps/web/src/components/ui/tooltip.tsx | 48 + .../apps/web/src/components/workos-user.tsx | 35 + .../apps/web/src/db-collections/index.ts | 17 + .../apps/web/src/db-collections/timers.ts | 198 + src/dashboard/apps/web/src/db.ts | 13 + src/dashboard/apps/web/src/drizzle/index.ts | 29 + .../drizzle/migrations/0000_slim_masque.sql | 50 + .../migrations/meta/0000_snapshot.json | 334 ++ .../src/drizzle/migrations/meta/_journal.json | 13 + .../web/src/drizzle/migrations/relations.ts | 0 .../apps/web/src/drizzle/migrations/schema.ts | 58 + src/dashboard/apps/web/src/drizzle/schema.ts | 593 +++ src/dashboard/apps/web/src/env.ts | 39 + .../web/src/integrations/convex/provider.tsx | 12 + .../integrations/tanstack-query/devtools.tsx | 6 + .../tanstack-query/root-provider.tsx | 51 + .../apps/web/src/integrations/trpc/init.ts | 9 + .../apps/web/src/integrations/trpc/react.ts | 4 + .../apps/web/src/integrations/trpc/router.ts | 23 + .../web/src/integrations/workos/provider.tsx | 5 + .../web/src/lib/ai-example/AIAssistant.tsx | 163 + .../web/src/lib/ai-example/ai-devtools.tsx | 3 + .../apps/web/src/lib/ai-example/ai-hook.ts | 18 + .../web/src/lib/ai-example/guitar-tools.ts | 38 + .../apps/web/src/lib/ai-example/index.ts | 9 + .../web/src/lib/ai-example/model-selection.ts | 80 + .../src/lib/ai-example/vendor-capabilities.ts | 50 + .../web/src/lib/assistant/assistant.server.ts | 1004 +++++ .../assistant/components/CelebrationModal.tsx | 289 ++ .../components/ContextParkingModal.tsx | 187 + .../src/lib/assistant/components/TaskCard.tsx | 371 ++ .../src/lib/assistant/components/TaskForm.tsx | 274 ++ .../web/src/lib/assistant/components/index.ts | 4 + .../apps/web/src/lib/assistant/hooks/index.ts | 89 + .../assistant/hooks/useAssistantQueries.ts | 780 ++++ .../lib/assistant/hooks/useBadgeProgress.ts | 290 ++ .../src/lib/assistant/hooks/useBlockers.ts | 466 +++ .../lib/assistant/hooks/useCelebrations.ts | 411 ++ .../assistant/hooks/useCommunicationLog.ts | 440 ++ .../lib/assistant/hooks/useContextParking.ts | 29 + .../lib/assistant/hooks/useDeadlineRisk.ts | 312 ++ .../src/lib/assistant/hooks/useDecisionLog.ts | 580 +++ .../lib/assistant/hooks/useDistractions.ts | 489 +++ .../src/lib/assistant/hooks/useEnergyData.ts | 505 +++ .../web/src/lib/assistant/hooks/useHandoff.ts | 453 +++ .../web/src/lib/assistant/hooks/useStreak.ts | 176 + .../src/lib/assistant/hooks/useTaskStore.ts | 839 ++++ .../lib/assistant/hooks/useWeeklyReview.ts | 485 +++ .../src/lib/assistant/lib/storage/config.ts | 20 + .../src/lib/assistant/lib/storage/index.ts | 34 + .../lib/storage/localstorage-adapter.ts | 2095 ++++++++++ .../src/lib/assistant/lib/storage/types.ts | 332 ++ .../apps/web/src/lib/assistant/types.ts | 1104 ++++++ .../apps/web/src/lib/auth-actions.ts | 255 ++ src/dashboard/apps/web/src/lib/auth-server.ts | 62 + .../apps/web/src/lib/db/clear-powersync.ts | 58 + src/dashboard/apps/web/src/lib/db/index.ts | 6 + .../web/src/lib/db/powersync-connector.ts | 103 + .../apps/web/src/lib/db/powersync.ts | 295 ++ .../apps/web/src/lib/demo-store-devtools.tsx | 58 + src/dashboard/apps/web/src/lib/env.ts | 17 + .../apps/web/src/lib/events/client.ts | 216 + .../apps/web/src/lib/events/server.ts | 80 + .../src/lib/example-todo/drizzle/schema.ts | 21 + .../src/lib/example-todo/todo-collection.ts | 131 + .../src/lib/example-todo/todo-sync.server.ts | 323 ++ .../apps/web/src/lib/forms/FormComponents.tsx | 153 + .../apps/web/src/lib/forms/form-context.ts | 3 + src/dashboard/apps/web/src/lib/forms/form.ts | 17 + src/dashboard/apps/web/src/lib/forms/index.ts | 6 + .../web/src/lib/hooks/ai/useAudioRecorder.ts | 82 + .../apps/web/src/lib/hooks/ai/useTTS.ts | 78 + .../apps/web/src/lib/hooks/use-mobile.ts | 19 + .../apps/web/src/lib/hooks/useSettings.ts | 106 + .../apps/web/src/lib/hooks/useUser.tsx | 21 + src/dashboard/apps/web/src/lib/server-db.ts | 202 + .../lib/timer/components/ActivityLogEntry.tsx | 245 ++ .../timer/components/ActivityLogSidebar.tsx | 324 ++ .../lib/timer/components/CountdownPicker.tsx | 93 + .../web/src/lib/timer/components/LapsList.tsx | 220 + .../lib/timer/components/PomodoroSteps.tsx | 153 + .../timer/components/ProductivityStats.tsx | 332 ++ .../src/lib/timer/components/TimeEditor.tsx | 217 + .../src/lib/timer/components/TimerCard.tsx | 326 ++ .../lib/timer/components/TimerControls.tsx | 167 + .../src/lib/timer/components/TimerDisplay.tsx | 119 + .../src/lib/timer/components/TimerHeader.tsx | 141 + .../lib/timer/components/TimerNameInput.tsx | 126 + .../timer/components/TimerTypeSelector.tsx | 69 + .../lib/timer/components/TotalTimeBadge.tsx | 105 + .../web/src/lib/timer/components/index.ts | 17 + .../apps/web/src/lib/timer/hooks/index.ts | 8 + .../web/src/lib/timer/hooks/useActivityLog.ts | 276 ++ .../src/lib/timer/hooks/useCrossTabSync.ts | 171 + .../apps/web/src/lib/timer/hooks/useTimer.ts | 265 ++ .../web/src/lib/timer/hooks/useTimerEngine.ts | 168 + .../web/src/lib/timer/hooks/useTimerStore.ts | 206 + src/dashboard/apps/web/src/lib/timer/index.ts | 7 + .../apps/web/src/lib/timer/storage/config.ts | 56 + .../apps/web/src/lib/timer/storage/index.ts | 66 + .../lib/timer/storage/localstorage-adapter.ts | 542 +++ .../lib/timer/storage/powersync-adapter.ts | 703 ++++ .../src/lib/timer/storage/simple-storage.ts | 124 + .../apps/web/src/lib/timer/storage/types.ts | 87 + .../web/src/lib/timer/timer-sync.server.ts | 390 ++ .../src/lib/timer/timer-sync.server.ts.old | 561 +++ src/dashboard/apps/web/src/lib/utils.ts | 6 + src/dashboard/apps/web/src/logo.svg | 12 + src/dashboard/apps/web/src/mcp-todos.ts | 51 + src/dashboard/apps/web/src/routeTree.gen.ts | 660 +++ src/dashboard/apps/web/src/router.tsx | 23 + .../apps/web/src/routes/-api.events.ts.old | 127 + .../web/src/routes/-api.sync.upload.ts.old | 178 + src/dashboard/apps/web/src/routes/__root.tsx | 84 + .../apps/web/src/routes/api.events.ts | 114 + .../apps/web/src/routes/api.trpc.$.tsx | 20 + .../-components/analytics/BadgesEarned.tsx | 205 + .../-components/analytics/CompletionTrend.tsx | 159 + .../analytics/DeadlinePerformance.tsx | 161 + .../-components/analytics/EnergyByDay.tsx | 178 + .../-components/analytics/EnergyHeatmap.tsx | 243 ++ .../-components/analytics/EnergyInsights.tsx | 324 ++ .../analytics/FocusRecommendation.tsx | 257 ++ .../-components/analytics/HeatmapCell.tsx | 187 + .../-components/analytics/LogEnergyButton.tsx | 353 ++ .../-components/analytics/ReviewExport.tsx | 270 ++ .../-components/analytics/WeekStats.tsx | 137 + .../-components/analytics/WeeklyInsights.tsx | 261 ++ .../-components/analytics/WeeklyReview.tsx | 264 ++ .../assistant/-components/analytics/index.ts | 16 + .../-components/badges/BadgeCard.tsx | 300 ++ .../-components/badges/BadgeProgress.tsx | 316 ++ .../-components/badges/BadgeShowcase.tsx | 186 + .../badges/BadgeUnlockAnimation.tsx | 400 ++ .../assistant/-components/badges/index.ts | 8 + .../-components/blockers/BlockerActions.tsx | 389 ++ .../-components/blockers/BlockerCard.tsx | 223 ++ .../-components/blockers/BlockerList.tsx | 361 ++ .../-components/blockers/BlockerModal.tsx | 223 ++ .../assistant/-components/blockers/index.ts | 4 + .../celebrations/BadgeCelebration.tsx | 380 ++ .../celebrations/CelebrationManager.tsx | 543 +++ .../celebrations/FocusSessionComplete.tsx | 48 + .../celebrations/MicroCelebration.tsx | 208 + .../celebrations/StreakMilestone.tsx | 135 + .../-components/celebrations/index.ts | 51 + .../-components/celebrations/particles.ts | 195 + .../-components/celebrations/types.ts | 138 + .../communication/CommunicationLog.tsx | 162 + .../-components/communication/LogEntry.tsx | 384 ++ .../-components/communication/LogFilters.tsx | 172 + .../-components/communication/LogForm.tsx | 512 +++ .../-components/communication/index.ts | 4 + .../critical-path/BottleneckAlert.tsx | 160 + .../critical-path/CriticalPathGraph.tsx | 361 ++ .../critical-path/DependencyNode.tsx | 295 ++ .../critical-path/DependencySelector.tsx | 300 ++ .../critical-path/PathAnalysis.tsx | 276 ++ .../-components/critical-path/graph-utils.ts | 444 +++ .../-components/critical-path/index.ts | 35 + .../-components/critical-path/types.ts | 79 + .../critical-path/useCriticalPath.ts | 190 + .../-components/decisions/DecisionCard.tsx | 350 ++ .../-components/decisions/DecisionForm.tsx | 389 ++ .../-components/decisions/DecisionLog.tsx | 579 +++ .../decisions/DecisionTimeline.tsx | 337 ++ .../-components/decisions/SupersededChain.tsx | 232 ++ .../assistant/-components/decisions/index.ts | 5 + .../distractions/DistractionInsights.tsx | 341 ++ .../distractions/DistractionLogModal.tsx | 253 ++ .../distractions/DistractionPatterns.tsx | 292 ++ .../distractions/DistractionStats.tsx | 298 ++ .../distractions/QuickLogButton.tsx | 104 + .../-components/distractions/index.ts | 7 + .../escalation/EscalationAlert.tsx | 228 ++ .../escalation/EscalationOptions.tsx | 393 ++ .../escalation/EscalationWidget.tsx | 222 ++ .../-components/escalation/RiskIndicator.tsx | 248 ++ .../assistant/-components/escalation/index.ts | 12 + .../-components/handoff/HandoffBanner.tsx | 292 ++ .../-components/handoff/HandoffDocument.tsx | 463 +++ .../-components/handoff/HandoffEditor.tsx | 511 +++ .../-components/handoff/HandoffHistory.tsx | 317 ++ .../-components/handoff/HandoffPreview.tsx | 288 ++ .../assistant/-components/handoff/index.ts | 5 + .../-components/kanban/KanbanBoard.tsx | 127 + .../-components/kanban/KanbanCard.tsx | 247 ++ .../-components/kanban/KanbanColumn.tsx | 152 + .../-components/kanban/KanbanHeader.tsx | 124 + .../assistant/-components/kanban/index.ts | 4 + .../web/src/routes/assistant/analytics.tsx | 291 ++ .../src/routes/assistant/communication.tsx | 207 + .../web/src/routes/assistant/decisions.tsx | 78 + .../apps/web/src/routes/assistant/index.tsx | 8 + .../apps/web/src/routes/assistant/next.tsx | 468 +++ .../apps/web/src/routes/assistant/parking.tsx | 368 ++ .../src/routes/assistant/tasks/$taskId.tsx | 1034 +++++ .../web/src/routes/assistant/tasks/index.tsx | 503 +++ .../apps/web/src/routes/auth/callback.tsx | 41 + .../apps/web/src/routes/auth/error.tsx | 86 + .../web/src/routes/auth/forgot-password.tsx | 132 + .../web/src/routes/auth/reset-password.tsx | 171 + .../apps/web/src/routes/auth/signin.tsx | 235 ++ .../apps/web/src/routes/auth/signup.tsx | 267 ++ .../apps/web/src/routes/dashboard/ai.tsx | 83 + .../web/src/routes/dashboard/bookmarks.tsx | 83 + .../apps/web/src/routes/dashboard/focus.tsx | 84 + .../apps/web/src/routes/dashboard/index.tsx | 214 + .../apps/web/src/routes/dashboard/notes.tsx | 80 + .../apps/web/src/routes/dashboard/planner.tsx | 85 + .../apps/web/src/routes/example/todo.tsx | 594 +++ src/dashboard/apps/web/src/routes/index.tsx | 30 + src/dashboard/apps/web/src/routes/mcp.ts | 51 + src/dashboard/apps/web/src/routes/profile.tsx | 318 ++ .../apps/web/src/routes/settings.tsx | 305 ++ .../apps/web/src/routes/timer.$timerId.tsx | 56 + .../apps/web/src/routes/timer/index.tsx | 213 + src/dashboard/apps/web/src/start.ts | 8 + src/dashboard/apps/web/src/styles.css | 380 ++ .../apps/web/src/utils/mcp-handler.ts | 57 + src/dashboard/apps/web/test-powersync.html | 88 + src/dashboard/apps/web/truncate-tables.ts | 19 + src/dashboard/apps/web/tsconfig.json | 32 + src/dashboard/apps/web/vite.config.ts | 67 + src/dashboard/bun.lock | 3527 +++++++++++++++++ src/dashboard/package.json | 24 + .../packages/eslint-config/README.md | 3 + src/dashboard/packages/eslint-config/base.js | 32 + src/dashboard/packages/eslint-config/next.js | 57 + .../packages/eslint-config/package.json | 24 + .../packages/eslint-config/react-internal.js | 39 + src/dashboard/packages/shared/package.json | 34 + .../packages/shared/src/constants/index.ts | 35 + src/dashboard/packages/shared/src/index.ts | 3 + .../packages/shared/src/types/activity-log.ts | 90 + .../packages/shared/src/types/index.ts | 2 + .../packages/shared/src/types/timer.ts | 116 + .../packages/shared/src/utils/index.ts | 1 + .../packages/shared/src/utils/time.ts | 42 + src/dashboard/packages/shared/tsconfig.json | 9 + .../packages/tailwind-config/package.json | 14 + .../tailwind-config/postcss.config.js | 6 + .../tailwind-config/shared-styles.css | 7 + .../packages/typescript-config/base.json | 19 + .../packages/typescript-config/nextjs.json | 12 + .../packages/typescript-config/package.json | 9 + .../typescript-config/react-library.json | 7 + src/dashboard/packages/ui/eslint.config.mjs | 4 + src/dashboard/packages/ui/package.json | 36 + src/dashboard/packages/ui/src/card.tsx | 20 + src/dashboard/packages/ui/src/gradient.tsx | 13 + src/dashboard/packages/ui/src/styles.css | 3 + .../packages/ui/src/turborepo-logo.tsx | 29 + src/dashboard/packages/ui/tsconfig.json | 8 + src/dashboard/packages/ui/turbo.json | 25 + src/dashboard/timer/index.static.html | 1434 +++++++ src/dashboard/turbo.json | 21 + task_plan.md | 138 + 501 files changed, 77830 insertions(+), 298 deletions(-) create mode 100644 .claude/dashboard/README.md create mode 100644 .claude/dashboard/architecture.md create mode 100644 .claude/dashboard/build.md create mode 100644 .claude/dashboard/components.md create mode 100644 .claude/dashboard/patterns.md create mode 100644 .claude/dashboard/routing.md create mode 100644 .claude/dashboard/stack.md create mode 100644 .claude/dashboard/state.md create mode 100644 .claude/dashboard/structure.md create mode 100644 .claude/ideas/assistant/001-assistant-personal-ai-master.md create mode 100644 .claude/ideas/assistant/002-assistant-phase1-detailed.md create mode 100644 .claude/ideas/assistant/003-assistant-phase2-roadmap.md create mode 100644 .claude/ideas/assistant/004-assistant-phase3-roadmap.md create mode 100644 .claude/ideas/dashboard/001-sleep-recovery-dashboard.md create mode 100644 .claude/ideas/dashboard/002-nutrition-hydration-logger.md create mode 100644 .claude/ideas/dashboard/003-mood-energy-tracker.md create mode 100644 .claude/ideas/dashboard/004-spending-snapshot-dashboard.md create mode 100644 .claude/ideas/dashboard/005-accountability-network.md create mode 100644 .claude/ideas/dashboard/006-portfolio-showcase.md create mode 100644 .claude/ideas/dashboard/007-skill-leveling-system.md create mode 100644 .claude/ideas/dashboard/008-relationship-calendar.md create mode 100644 .claude/ideas/dashboard/009-investment-dashboard.md create mode 100644 .claude/ideas/dashboard/010-debt-snowball-tracker.md create mode 100644 .claude/ideas/dashboard/011-creative-metrics.md create mode 100644 .claude/ideas/dashboard/012-event-coordination-hub.md create mode 100644 .claude/plans/2026-01-10-Dashboard.md create mode 100644 .claude/plans/2026-01-13-badge-progress-ui.md create mode 100644 .claude/plans/2026-01-13-blocker-detector.md create mode 100644 .claude/plans/2026-01-13-critical-path-visualizer.md create mode 100644 .claude/plans/2026-01-13-decision-log.md create mode 100644 .claude/plans/2026-01-13-distraction-tracker.md create mode 100644 .claude/plans/2026-01-13-energy-heatmap.md create mode 100644 .claude/plans/2026-01-13-escalation-alerts.md create mode 100644 .claude/plans/2026-01-13-handoff-compiler.md create mode 100644 .claude/plans/2026-01-13-kanban-board.md create mode 100644 .claude/plans/2026-01-13-micro-celebrations.md create mode 100644 .claude/plans/2026-01-13-weekly-review-dashboard.md create mode 100644 CodeExamples.md create mode 100644 findings.md create mode 100644 progress.md create mode 100644 src/dashboard/.gitignore create mode 100644 src/dashboard/.npmrc create mode 100644 src/dashboard/README.md create mode 100644 src/dashboard/apps/docs/.gitignore create mode 100644 src/dashboard/apps/docs/README.md create mode 100644 src/dashboard/apps/docs/app/favicon.ico create mode 100644 src/dashboard/apps/docs/app/globals.css create mode 100644 src/dashboard/apps/docs/app/layout.tsx create mode 100644 src/dashboard/apps/docs/app/page.tsx create mode 100644 src/dashboard/apps/docs/eslint.config.js create mode 100644 src/dashboard/apps/docs/next-env.d.ts create mode 100644 src/dashboard/apps/docs/next.config.ts create mode 100644 src/dashboard/apps/docs/package.json create mode 100644 src/dashboard/apps/docs/postcss.config.js create mode 100644 src/dashboard/apps/docs/public/circles.svg create mode 100644 src/dashboard/apps/docs/public/next.svg create mode 100644 src/dashboard/apps/docs/public/turborepo.svg create mode 100644 src/dashboard/apps/docs/public/vercel.svg create mode 100644 src/dashboard/apps/docs/tsconfig.json create mode 100644 src/dashboard/apps/server/.env.example create mode 100644 src/dashboard/apps/server/.gitignore create mode 100644 src/dashboard/apps/server/README.md create mode 100644 src/dashboard/apps/server/nitro.config.ts create mode 100644 src/dashboard/apps/server/package.json create mode 100644 src/dashboard/apps/server/server/routes/_ws.ts create mode 100644 src/dashboard/apps/server/server/routes/api/health.ts create mode 100644 src/dashboard/apps/server/server/routes/api/sync/upload.ts create mode 100644 src/dashboard/apps/server/server/routes/api/timers/[id].ts create mode 100644 src/dashboard/apps/server/server/routes/api/timers/index.ts create mode 100644 src/dashboard/apps/server/server/routes/api/user.ts create mode 100644 src/dashboard/apps/server/server/routes/index.ts create mode 100644 src/dashboard/apps/server/tsconfig.json create mode 100644 src/dashboard/apps/web-template/.cta.json create mode 100644 src/dashboard/apps/web-template/.cursorrules create mode 100644 src/dashboard/apps/web-template/.env.example create mode 100644 src/dashboard/apps/web-template/.gitignore create mode 100644 src/dashboard/apps/web-template/.vscode/settings.json create mode 100644 src/dashboard/apps/web-template/README.md create mode 100644 src/dashboard/apps/web-template/components.json create mode 100644 src/dashboard/apps/web-template/convex/_generated/api.d.ts create mode 100644 src/dashboard/apps/web-template/convex/_generated/api.js create mode 100644 src/dashboard/apps/web-template/convex/_generated/dataModel.d.ts create mode 100644 src/dashboard/apps/web-template/convex/_generated/server.d.ts create mode 100644 src/dashboard/apps/web-template/convex/_generated/server.js create mode 100644 src/dashboard/apps/web-template/convex/schema.ts create mode 100644 src/dashboard/apps/web-template/convex/todos.ts create mode 100644 src/dashboard/apps/web-template/convex/tsconfig.json create mode 100644 src/dashboard/apps/web-template/db/init.sql create mode 100644 src/dashboard/apps/web-template/neon-vite-plugin.ts create mode 100644 src/dashboard/apps/web-template/src/components/Header.tsx create mode 100644 src/dashboard/apps/web-template/src/components/demo.FormComponents.tsx create mode 100644 src/dashboard/apps/web-template/src/components/demo.chat-area.tsx create mode 100644 src/dashboard/apps/web-template/src/components/demo.messages.tsx create mode 100644 src/dashboard/apps/web-template/src/components/example-AIAssistant.tsx create mode 100644 src/dashboard/apps/web-template/src/components/example-GuitarRecommendation.tsx create mode 100644 src/dashboard/apps/web-template/src/components/ui/button.tsx create mode 100644 src/dashboard/apps/web-template/src/components/ui/input.tsx create mode 100644 src/dashboard/apps/web-template/src/components/ui/label.tsx create mode 100644 src/dashboard/apps/web-template/src/components/ui/select.tsx create mode 100644 src/dashboard/apps/web-template/src/components/ui/slider.tsx create mode 100644 src/dashboard/apps/web-template/src/components/ui/switch.tsx create mode 100644 src/dashboard/apps/web-template/src/components/ui/textarea.tsx create mode 100644 src/dashboard/apps/web-template/src/components/workos-user.tsx create mode 100644 src/dashboard/apps/web-template/src/data/demo-table-data.ts create mode 100644 src/dashboard/apps/web-template/src/data/demo.punk-songs.ts create mode 100644 src/dashboard/apps/web-template/src/data/example-guitars.ts create mode 100644 src/dashboard/apps/web-template/src/db-collections/index.ts create mode 100644 src/dashboard/apps/web-template/src/db.ts create mode 100644 src/dashboard/apps/web-template/src/env.ts create mode 100644 src/dashboard/apps/web-template/src/hooks/demo.form-context.ts create mode 100644 src/dashboard/apps/web-template/src/hooks/demo.form.ts create mode 100644 src/dashboard/apps/web-template/src/hooks/demo.useChat.ts create mode 100644 src/dashboard/apps/web-template/src/hooks/useAudioRecorder.ts create mode 100644 src/dashboard/apps/web-template/src/hooks/useTTS.ts create mode 100644 src/dashboard/apps/web-template/src/hooks/useUser.tsx create mode 100644 src/dashboard/apps/web-template/src/integrations/convex/provider.tsx create mode 100644 src/dashboard/apps/web-template/src/integrations/tanstack-query/devtools.tsx create mode 100644 src/dashboard/apps/web-template/src/integrations/tanstack-query/root-provider.tsx create mode 100644 src/dashboard/apps/web-template/src/integrations/trpc/init.ts create mode 100644 src/dashboard/apps/web-template/src/integrations/trpc/react.ts create mode 100644 src/dashboard/apps/web-template/src/integrations/trpc/router.ts create mode 100644 src/dashboard/apps/web-template/src/integrations/workos/provider.tsx create mode 100644 src/dashboard/apps/web-template/src/lib/ai-devtools.tsx create mode 100644 src/dashboard/apps/web-template/src/lib/demo-store-devtools.tsx create mode 100644 src/dashboard/apps/web-template/src/lib/demo-store.ts create mode 100644 src/dashboard/apps/web-template/src/lib/example.ai-hook.ts create mode 100644 src/dashboard/apps/web-template/src/lib/example.guitar-tools.ts create mode 100644 src/dashboard/apps/web-template/src/lib/model-selection.ts create mode 100644 src/dashboard/apps/web-template/src/lib/utils.ts create mode 100644 src/dashboard/apps/web-template/src/lib/vendor-capabilities.ts create mode 100644 src/dashboard/apps/web-template/src/logo.svg create mode 100644 src/dashboard/apps/web-template/src/mcp-todos.ts create mode 100644 src/dashboard/apps/web-template/src/routeTree.gen.ts create mode 100644 src/dashboard/apps/web-template/src/router.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/__root.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/api.trpc.$.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/api.available-providers.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/api.image.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/api.mcp-todos.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/api.names.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/api.structured.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/api.tanchat.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/api.tq-todos.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/api.transcription.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/api.tts.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/convex.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/db-chat-api.ts create mode 100644 src/dashboard/apps/web-template/src/routes/demo/db-chat.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/form.address.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/form.simple.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/image.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/mcp-todos.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/neon.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/start.api-request.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/start.server-funcs.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/start.ssr.data-only.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/start.ssr.full-ssr.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/start.ssr.index.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/start.ssr.spa-mode.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/store.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/structured.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/table.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/tanchat.css create mode 100644 src/dashboard/apps/web-template/src/routes/demo/tanchat.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/tanstack-query.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/trpc-todo.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/demo/workos.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/example.guitars/$guitarId.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/example.guitars/index.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/index.tsx create mode 100644 src/dashboard/apps/web-template/src/routes/mcp.ts create mode 100644 src/dashboard/apps/web-template/src/styles.css create mode 100644 src/dashboard/apps/web-template/src/utils/mcp-handler.ts create mode 100644 src/dashboard/apps/web/.claude/CLAUDE.md create mode 100644 src/dashboard/apps/web/.claude/docs/patterns/type-sharing.md create mode 100644 src/dashboard/apps/web/.claude/docs/systems/database.md create mode 100644 src/dashboard/apps/web/.claude/docs/systems/events.md create mode 100644 src/dashboard/apps/web/.cta.json create mode 100644 src/dashboard/apps/web/.cursorrules create mode 100644 src/dashboard/apps/web/.env.example create mode 100644 src/dashboard/apps/web/.gitignore create mode 100644 src/dashboard/apps/web/.vscode/settings.json create mode 100644 src/dashboard/apps/web/README.md create mode 100644 src/dashboard/apps/web/components.json create mode 100644 src/dashboard/apps/web/convex/_generated/api.d.ts create mode 100644 src/dashboard/apps/web/convex/_generated/api.js create mode 100644 src/dashboard/apps/web/convex/_generated/dataModel.d.ts create mode 100644 src/dashboard/apps/web/convex/_generated/server.d.ts create mode 100644 src/dashboard/apps/web/convex/_generated/server.js create mode 100644 src/dashboard/apps/web/convex/schema.ts create mode 100644 src/dashboard/apps/web/convex/todos.ts create mode 100644 src/dashboard/apps/web/convex/tsconfig.json create mode 100644 src/dashboard/apps/web/db/init.sql create mode 100644 src/dashboard/apps/web/drizzle.config.ts create mode 100644 src/dashboard/apps/web/neon-vite-plugin.ts create mode 100644 src/dashboard/apps/web/package.json create mode 100644 src/dashboard/apps/web/public/demo-neon.svg create mode 100644 src/dashboard/apps/web/public/example-guitar-flowers.jpg create mode 100644 src/dashboard/apps/web/public/example-guitar-motherboard.jpg create mode 100644 src/dashboard/apps/web/public/example-guitar-racing.jpg create mode 100644 src/dashboard/apps/web/public/example-guitar-steamer-trunk.jpg create mode 100644 src/dashboard/apps/web/public/example-guitar-superhero.jpg create mode 100644 src/dashboard/apps/web/public/example-guitar-traveling.jpg create mode 100644 src/dashboard/apps/web/public/example-guitar-video-games.jpg create mode 100644 src/dashboard/apps/web/public/example-ukelele-tanstack.jpg create mode 100644 src/dashboard/apps/web/public/favicon.ico create mode 100644 src/dashboard/apps/web/public/logo192.png create mode 100644 src/dashboard/apps/web/public/logo512.png create mode 100644 src/dashboard/apps/web/public/manifest.json create mode 100644 src/dashboard/apps/web/public/robots.txt create mode 100644 src/dashboard/apps/web/public/tanstack-circle-logo.png create mode 100644 src/dashboard/apps/web/public/tanstack-word-logo-white.svg create mode 100644 src/dashboard/apps/web/server/routes/_ws-todo.ts create mode 100644 src/dashboard/apps/web/server/routes/api/-events.get.ts.old create mode 100644 src/dashboard/apps/web/src/__tests__/api.test.ts create mode 100644 src/dashboard/apps/web/src/__tests__/drizzle.test.ts create mode 100644 src/dashboard/apps/web/src/__tests__/events.test.ts create mode 100644 src/dashboard/apps/web/src/components/auth/AuthLayout.tsx create mode 100644 src/dashboard/apps/web/src/components/auth/cyberpunk.css create mode 100644 src/dashboard/apps/web/src/components/auth/index.ts create mode 100644 src/dashboard/apps/web/src/components/dashboard/app-sidebar.tsx create mode 100644 src/dashboard/apps/web/src/components/dashboard/dashboard-layout.tsx create mode 100644 src/dashboard/apps/web/src/components/dashboard/index.ts create mode 100644 src/dashboard/apps/web/src/components/ui/avatar.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/badge.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/button.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/card.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/dialog.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/dropdown-menu.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/feature-card.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/input.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/label.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/scroll-area.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/select.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/separator.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/sheet.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/sidebar.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/skeleton.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/slider.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/switch.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/textarea.tsx create mode 100644 src/dashboard/apps/web/src/components/ui/tooltip.tsx create mode 100644 src/dashboard/apps/web/src/components/workos-user.tsx create mode 100644 src/dashboard/apps/web/src/db-collections/index.ts create mode 100644 src/dashboard/apps/web/src/db-collections/timers.ts create mode 100644 src/dashboard/apps/web/src/db.ts create mode 100644 src/dashboard/apps/web/src/drizzle/index.ts create mode 100644 src/dashboard/apps/web/src/drizzle/migrations/0000_slim_masque.sql create mode 100644 src/dashboard/apps/web/src/drizzle/migrations/meta/0000_snapshot.json create mode 100644 src/dashboard/apps/web/src/drizzle/migrations/meta/_journal.json create mode 100644 src/dashboard/apps/web/src/drizzle/migrations/relations.ts create mode 100644 src/dashboard/apps/web/src/drizzle/migrations/schema.ts create mode 100644 src/dashboard/apps/web/src/drizzle/schema.ts create mode 100644 src/dashboard/apps/web/src/env.ts create mode 100644 src/dashboard/apps/web/src/integrations/convex/provider.tsx create mode 100644 src/dashboard/apps/web/src/integrations/tanstack-query/devtools.tsx create mode 100644 src/dashboard/apps/web/src/integrations/tanstack-query/root-provider.tsx create mode 100644 src/dashboard/apps/web/src/integrations/trpc/init.ts create mode 100644 src/dashboard/apps/web/src/integrations/trpc/react.ts create mode 100644 src/dashboard/apps/web/src/integrations/trpc/router.ts create mode 100644 src/dashboard/apps/web/src/integrations/workos/provider.tsx create mode 100644 src/dashboard/apps/web/src/lib/ai-example/AIAssistant.tsx create mode 100644 src/dashboard/apps/web/src/lib/ai-example/ai-devtools.tsx create mode 100644 src/dashboard/apps/web/src/lib/ai-example/ai-hook.ts create mode 100644 src/dashboard/apps/web/src/lib/ai-example/guitar-tools.ts create mode 100644 src/dashboard/apps/web/src/lib/ai-example/index.ts create mode 100644 src/dashboard/apps/web/src/lib/ai-example/model-selection.ts create mode 100644 src/dashboard/apps/web/src/lib/ai-example/vendor-capabilities.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/assistant.server.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/components/CelebrationModal.tsx create mode 100644 src/dashboard/apps/web/src/lib/assistant/components/ContextParkingModal.tsx create mode 100644 src/dashboard/apps/web/src/lib/assistant/components/TaskCard.tsx create mode 100644 src/dashboard/apps/web/src/lib/assistant/components/TaskForm.tsx create mode 100644 src/dashboard/apps/web/src/lib/assistant/components/index.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/index.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useAssistantQueries.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useBadgeProgress.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useBlockers.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useCelebrations.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useCommunicationLog.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useContextParking.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useDeadlineRisk.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useDecisionLog.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useDistractions.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useEnergyData.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useHandoff.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useStreak.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useTaskStore.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/hooks/useWeeklyReview.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/lib/storage/config.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/lib/storage/index.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/lib/storage/localstorage-adapter.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/lib/storage/types.ts create mode 100644 src/dashboard/apps/web/src/lib/assistant/types.ts create mode 100644 src/dashboard/apps/web/src/lib/auth-actions.ts create mode 100644 src/dashboard/apps/web/src/lib/auth-server.ts create mode 100644 src/dashboard/apps/web/src/lib/db/clear-powersync.ts create mode 100644 src/dashboard/apps/web/src/lib/db/index.ts create mode 100644 src/dashboard/apps/web/src/lib/db/powersync-connector.ts create mode 100644 src/dashboard/apps/web/src/lib/db/powersync.ts create mode 100644 src/dashboard/apps/web/src/lib/demo-store-devtools.tsx create mode 100644 src/dashboard/apps/web/src/lib/env.ts create mode 100644 src/dashboard/apps/web/src/lib/events/client.ts create mode 100644 src/dashboard/apps/web/src/lib/events/server.ts create mode 100644 src/dashboard/apps/web/src/lib/example-todo/drizzle/schema.ts create mode 100644 src/dashboard/apps/web/src/lib/example-todo/todo-collection.ts create mode 100644 src/dashboard/apps/web/src/lib/example-todo/todo-sync.server.ts create mode 100644 src/dashboard/apps/web/src/lib/forms/FormComponents.tsx create mode 100644 src/dashboard/apps/web/src/lib/forms/form-context.ts create mode 100644 src/dashboard/apps/web/src/lib/forms/form.ts create mode 100644 src/dashboard/apps/web/src/lib/forms/index.ts create mode 100644 src/dashboard/apps/web/src/lib/hooks/ai/useAudioRecorder.ts create mode 100644 src/dashboard/apps/web/src/lib/hooks/ai/useTTS.ts create mode 100644 src/dashboard/apps/web/src/lib/hooks/use-mobile.ts create mode 100644 src/dashboard/apps/web/src/lib/hooks/useSettings.ts create mode 100644 src/dashboard/apps/web/src/lib/hooks/useUser.tsx create mode 100644 src/dashboard/apps/web/src/lib/server-db.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/components/ActivityLogEntry.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/ActivityLogSidebar.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/CountdownPicker.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/LapsList.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/PomodoroSteps.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/ProductivityStats.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/TimeEditor.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/TimerCard.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/TimerControls.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/TimerDisplay.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/TimerHeader.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/TimerNameInput.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/TimerTypeSelector.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/TotalTimeBadge.tsx create mode 100644 src/dashboard/apps/web/src/lib/timer/components/index.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/hooks/index.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/hooks/useActivityLog.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/hooks/useCrossTabSync.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/hooks/useTimer.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/hooks/useTimerEngine.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/hooks/useTimerStore.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/index.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/storage/config.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/storage/index.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/storage/localstorage-adapter.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/storage/powersync-adapter.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/storage/simple-storage.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/storage/types.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/timer-sync.server.ts create mode 100644 src/dashboard/apps/web/src/lib/timer/timer-sync.server.ts.old create mode 100644 src/dashboard/apps/web/src/lib/utils.ts create mode 100644 src/dashboard/apps/web/src/logo.svg create mode 100644 src/dashboard/apps/web/src/mcp-todos.ts create mode 100644 src/dashboard/apps/web/src/routeTree.gen.ts create mode 100644 src/dashboard/apps/web/src/router.tsx create mode 100644 src/dashboard/apps/web/src/routes/-api.events.ts.old create mode 100644 src/dashboard/apps/web/src/routes/-api.sync.upload.ts.old create mode 100644 src/dashboard/apps/web/src/routes/__root.tsx create mode 100644 src/dashboard/apps/web/src/routes/api.events.ts create mode 100644 src/dashboard/apps/web/src/routes/api.trpc.$.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/BadgesEarned.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/CompletionTrend.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/DeadlinePerformance.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/EnergyByDay.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/EnergyHeatmap.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/EnergyInsights.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/FocusRecommendation.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/HeatmapCell.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/LogEnergyButton.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/ReviewExport.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/WeekStats.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/WeeklyInsights.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/WeeklyReview.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/analytics/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/badges/BadgeCard.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/badges/BadgeProgress.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/badges/BadgeShowcase.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/badges/BadgeUnlockAnimation.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/badges/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/blockers/BlockerActions.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/blockers/BlockerCard.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/blockers/BlockerList.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/blockers/BlockerModal.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/blockers/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/celebrations/BadgeCelebration.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/celebrations/CelebrationManager.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/celebrations/FocusSessionComplete.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/celebrations/MicroCelebration.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/celebrations/StreakMilestone.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/celebrations/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/celebrations/particles.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/celebrations/types.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/communication/CommunicationLog.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/communication/LogEntry.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/communication/LogFilters.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/communication/LogForm.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/communication/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/critical-path/BottleneckAlert.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/critical-path/CriticalPathGraph.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/critical-path/DependencyNode.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/critical-path/DependencySelector.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/critical-path/PathAnalysis.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/critical-path/graph-utils.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/critical-path/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/critical-path/types.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/critical-path/useCriticalPath.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/decisions/DecisionCard.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/decisions/DecisionForm.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/decisions/DecisionLog.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/decisions/DecisionTimeline.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/decisions/SupersededChain.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/decisions/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/distractions/DistractionInsights.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/distractions/DistractionLogModal.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/distractions/DistractionPatterns.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/distractions/DistractionStats.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/distractions/QuickLogButton.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/distractions/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/escalation/EscalationAlert.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/escalation/EscalationOptions.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/escalation/EscalationWidget.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/escalation/RiskIndicator.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/escalation/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/handoff/HandoffBanner.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/handoff/HandoffDocument.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/handoff/HandoffEditor.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/handoff/HandoffHistory.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/handoff/HandoffPreview.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/handoff/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/kanban/KanbanBoard.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/kanban/KanbanCard.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/kanban/KanbanColumn.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/kanban/KanbanHeader.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/-components/kanban/index.ts create mode 100644 src/dashboard/apps/web/src/routes/assistant/analytics.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/communication.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/decisions.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/index.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/next.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/parking.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/tasks/$taskId.tsx create mode 100644 src/dashboard/apps/web/src/routes/assistant/tasks/index.tsx create mode 100644 src/dashboard/apps/web/src/routes/auth/callback.tsx create mode 100644 src/dashboard/apps/web/src/routes/auth/error.tsx create mode 100644 src/dashboard/apps/web/src/routes/auth/forgot-password.tsx create mode 100644 src/dashboard/apps/web/src/routes/auth/reset-password.tsx create mode 100644 src/dashboard/apps/web/src/routes/auth/signin.tsx create mode 100644 src/dashboard/apps/web/src/routes/auth/signup.tsx create mode 100644 src/dashboard/apps/web/src/routes/dashboard/ai.tsx create mode 100644 src/dashboard/apps/web/src/routes/dashboard/bookmarks.tsx create mode 100644 src/dashboard/apps/web/src/routes/dashboard/focus.tsx create mode 100644 src/dashboard/apps/web/src/routes/dashboard/index.tsx create mode 100644 src/dashboard/apps/web/src/routes/dashboard/notes.tsx create mode 100644 src/dashboard/apps/web/src/routes/dashboard/planner.tsx create mode 100644 src/dashboard/apps/web/src/routes/example/todo.tsx create mode 100644 src/dashboard/apps/web/src/routes/index.tsx create mode 100644 src/dashboard/apps/web/src/routes/mcp.ts create mode 100644 src/dashboard/apps/web/src/routes/profile.tsx create mode 100644 src/dashboard/apps/web/src/routes/settings.tsx create mode 100644 src/dashboard/apps/web/src/routes/timer.$timerId.tsx create mode 100644 src/dashboard/apps/web/src/routes/timer/index.tsx create mode 100644 src/dashboard/apps/web/src/start.ts create mode 100644 src/dashboard/apps/web/src/styles.css create mode 100644 src/dashboard/apps/web/src/utils/mcp-handler.ts create mode 100644 src/dashboard/apps/web/test-powersync.html create mode 100755 src/dashboard/apps/web/truncate-tables.ts create mode 100644 src/dashboard/apps/web/tsconfig.json create mode 100644 src/dashboard/apps/web/vite.config.ts create mode 100644 src/dashboard/bun.lock create mode 100644 src/dashboard/package.json create mode 100644 src/dashboard/packages/eslint-config/README.md create mode 100644 src/dashboard/packages/eslint-config/base.js create mode 100644 src/dashboard/packages/eslint-config/next.js create mode 100644 src/dashboard/packages/eslint-config/package.json create mode 100644 src/dashboard/packages/eslint-config/react-internal.js create mode 100644 src/dashboard/packages/shared/package.json create mode 100644 src/dashboard/packages/shared/src/constants/index.ts create mode 100644 src/dashboard/packages/shared/src/index.ts create mode 100644 src/dashboard/packages/shared/src/types/activity-log.ts create mode 100644 src/dashboard/packages/shared/src/types/index.ts create mode 100644 src/dashboard/packages/shared/src/types/timer.ts create mode 100644 src/dashboard/packages/shared/src/utils/index.ts create mode 100644 src/dashboard/packages/shared/src/utils/time.ts create mode 100644 src/dashboard/packages/shared/tsconfig.json create mode 100644 src/dashboard/packages/tailwind-config/package.json create mode 100644 src/dashboard/packages/tailwind-config/postcss.config.js create mode 100644 src/dashboard/packages/tailwind-config/shared-styles.css create mode 100644 src/dashboard/packages/typescript-config/base.json create mode 100644 src/dashboard/packages/typescript-config/nextjs.json create mode 100644 src/dashboard/packages/typescript-config/package.json create mode 100644 src/dashboard/packages/typescript-config/react-library.json create mode 100644 src/dashboard/packages/ui/eslint.config.mjs create mode 100644 src/dashboard/packages/ui/package.json create mode 100644 src/dashboard/packages/ui/src/card.tsx create mode 100644 src/dashboard/packages/ui/src/gradient.tsx create mode 100644 src/dashboard/packages/ui/src/styles.css create mode 100644 src/dashboard/packages/ui/src/turborepo-logo.tsx create mode 100644 src/dashboard/packages/ui/tsconfig.json create mode 100644 src/dashboard/packages/ui/turbo.json create mode 100644 src/dashboard/timer/index.static.html create mode 100644 src/dashboard/turbo.json create mode 100644 task_plan.md diff --git a/.claude/dashboard/README.md b/.claude/dashboard/README.md new file mode 100644 index 000000000..eeafd76ed --- /dev/null +++ b/.claude/dashboard/README.md @@ -0,0 +1,92 @@ +# Dashboard Documentation + +> Navigation index for the dashboard codebase (`src/dashboard/`) + +## Quick Start + +```bash +cd src/dashboard +bun install +bun run dev # http://localhost:3000 +``` + +## Documentation Index + +| Doc | Purpose | +|-----|---------| +| [architecture.md](./architecture.md) | Monorepo structure, stack overview | +| [stack.md](./stack.md) | All dependencies and their purposes | +| [structure.md](./structure.md) | Directory layout, file patterns | +| [components.md](./components.md) | UI components, shadcn/ui, theming | +| [routing.md](./routing.md) | TanStack Router, file-based routes | +| [state.md](./state.md) | State management patterns | +| [build.md](./build.md) | Build commands, Turborepo, Vite | +| [patterns.md](./patterns.md) | Code patterns and conventions | + +## Find It Fast + +| Looking for... | Go to | +|----------------|-------| +| Main web app | `src/dashboard/apps/web/` | +| Routes | `src/dashboard/apps/web/src/routes/` | +| UI components | `src/dashboard/apps/web/src/components/ui/` | +| Dashboard layout | `src/dashboard/apps/web/src/components/dashboard/` | +| Auth logic | `src/dashboard/apps/web/src/lib/auth-*.ts` | +| Timer feature | `src/dashboard/apps/web/src/routes/timer/` | +| Shared types | `src/dashboard/packages/shared/src/types/` | +| Root config | `src/dashboard/package.json`, `turbo.json` | +| Vite config | `src/dashboard/apps/web/vite.config.ts` | +| Styles | `src/dashboard/apps/web/src/styles.css` | + +## Key Facts + +- **Framework**: TanStack Start (React 19 + Vite + SSR) +- **Auth**: WorkOS AuthKit +- **Styling**: Tailwind CSS v4 + shadcn/ui +- **State**: TanStack Query + Store +- **Build**: Turborepo + Bun +- **React Compiler**: Do NOT use `useCallback`/`useMemo` + +## Context Triggers + + +**Load:** .claude/dashboard/architecture.md, .claude/dashboard/structure.md +**Files:** src/dashboard/apps/web/src/routes/, src/dashboard/apps/web/vite.config.ts +**Quick:** TanStack Start web app in Turborepo monorepo. File-based routing. + + + +**Load:** .claude/dashboard/components.md +**Files:** src/dashboard/apps/web/src/components/ui/, src/dashboard/apps/web/src/components/dashboard/ +**Quick:** shadcn/ui components with cyberpunk theme. Use cn() for class merging. + + + +**Load:** .claude/dashboard/patterns.md +**Files:** src/dashboard/apps/web/src/lib/auth-actions.ts, src/dashboard/apps/web/src/routes/auth/ +**Quick:** WorkOS AuthKit. useAuth() for client, createServerFn for server actions. + + + +**Load:** .claude/dashboard/routing.md +**Files:** src/dashboard/apps/web/src/routes/, src/dashboard/apps/web/src/router.tsx +**Quick:** TanStack Router file-based. createFileRoute(), Link, useNavigate. + + + +**Load:** .claude/dashboard/state.md +**Files:** src/dashboard/apps/web/src/hooks/, src/dashboard/apps/web/src/integrations/ +**Quick:** TanStack Query + Store. tRPC for type-safe API. useSettings() for prefs. + + + +**Load:** .claude/dashboard/patterns.md +**Files:** src/dashboard/apps/web/src/routes/timer/ +**Quick:** Timer feature module with hooks, components, storage adapters. + + + +**Load:** .claude/dashboard/build.md +**Files:** src/dashboard/package.json, src/dashboard/turbo.json, src/dashboard/apps/web/vite.config.ts +**Quick:** bun run dev starts web+server. Turborepo for monorepo builds. + diff --git a/.claude/dashboard/architecture.md b/.claude/dashboard/architecture.md new file mode 100644 index 000000000..04d7f84b2 --- /dev/null +++ b/.claude/dashboard/architecture.md @@ -0,0 +1,70 @@ +# Dashboard Architecture + +> Turborepo monorepo with TanStack Start web app + +## Find It Fast + +| Looking for... | Go to | +|----------------|-------| +| Web app | `src/dashboard/apps/web/` | +| Server (Nitro) | `src/dashboard/apps/server/` | +| Docs (unused) | `src/dashboard/apps/docs/` | +| Shared types/utils | `src/dashboard/packages/shared/` | +| UI components (pkg) | `src/dashboard/packages/ui/` | +| Root config | `src/dashboard/package.json`, `turbo.json` | + +## Monorepo Structure + +``` +src/dashboard/ +├── apps/ +│ ├── web/ # TanStack Start app (main) +│ └── server/ # Nitro server (API backend) +├── packages/ +│ ├── shared/ # @dashboard/shared - types, utils, constants +│ ├── ui/ # @dashboard/ui - turborepo example components +│ ├── eslint-config/ +│ ├── typescript-config/ +│ └── tailwind-config/ +└── turbo.json # Turborepo task config +``` + +## Stack Overview + +| Layer | Technology | +|-------|------------| +| Framework | TanStack Start (React 19, Vite, SSR) | +| Router | TanStack Router (file-based) | +| State | TanStack Store, React Query | +| Auth | WorkOS AuthKit | +| Styling | Tailwind CSS v4, shadcn/ui | +| DB Sync | PowerSync (SQLite, offline-first) | +| API | tRPC, Nitro server | +| Build | Turborepo, Vite, Bun | + +## Web App Entry Points + +| File | Purpose | +|------|---------| +| `vite.config.ts` | Vite + plugins config | +| `src/start.ts` | TanStack Start instance + middleware | +| `src/router.tsx` | Router creation + SSR query setup | +| `src/routes/__root.tsx` | Root layout, providers, devtools | +| `src/routes/index.tsx` | Home page (auth redirect) | + +## Key Integrations + +| Integration | Location | Purpose | +|-------------|----------|---------| +| WorkOS | `src/integrations/workos/` | Auth provider | +| TanStack Query | `src/integrations/tanstack-query/` | Data fetching | +| tRPC | `src/integrations/trpc/` | Type-safe API | +| Convex | `src/integrations/convex/`, `convex/` | Demo real-time DB | + +## Build Commands + +```bash +bun run dev # Start web + server in dev mode +bun run build # Build all apps +bun run lint # Lint all packages +``` diff --git a/.claude/dashboard/build.md b/.claude/dashboard/build.md new file mode 100644 index 000000000..046cc7f17 --- /dev/null +++ b/.claude/dashboard/build.md @@ -0,0 +1,148 @@ +# Build System + +> Turborepo + Vite + Bun + +## Commands + +From `src/dashboard/`: + +```bash +bun run dev # Start web + server in dev mode +bun run build # Build all apps +bun run lint # Lint all packages +bun run check-types # TypeScript checks +bun run format # Prettier format +``` + +## Turborepo Config + +From `turbo.json`: + +```json +{ + "tasks": { + "build": { + "dependsOn": ["^build"], + "outputs": ["dist/**", ".next/**", "!.next/cache/**"] + }, + "dev": { + "cache": false, + "persistent": true + }, + "lint": { "dependsOn": ["^lint"] }, + "check-types": { "dependsOn": ["^check-types"] } + } +} +``` + +## Package Scripts + +### Root (`package.json`) + +```json +{ + "scripts": { + "dev": "turbo run dev --filter=@dashboard/web --filter=@dashboard/server", + "build": "turbo run build", + "lint": "turbo run lint", + "check-types": "turbo run check-types" + } +} +``` + +### Web App (`apps/web/package.json`) + +```json +{ + "scripts": { + "dev": "vite dev --port 3000", + "build": "vite build", + "preview": "vite preview", + "test": "vitest run", + "lint": "biome lint", + "check": "biome check" + } +} +``` + +## Vite Configuration + +From `apps/web/vite.config.ts`: + +```ts +export default defineConfig({ + plugins: [ + devtools(), // TanStack devtools + nitro(), // Nitro server + neon, // Custom DB plugin + viteTsConfigPaths(), // Path aliases + tailwindcss(), // Tailwind v4 + tanstackStart(), // TanStack Start SSR + viteReact({ + babel: { plugins: ['babel-plugin-react-compiler'] } + }), + ], + resolve: { + alias: { + '@dashboard/shared': '../../packages/shared/src/index.ts', + '@dashboard/ui': '../../packages/ui/src/index.ts', + }, + }, + worker: { format: 'es' }, // For PowerSync workers + optimizeDeps: { + exclude: ['@journeyapps/wa-sqlite'], // PowerSync dep + }, +}) +``` + +## Workspaces + +Configured in root `package.json`: + +```json +{ + "workspaces": ["apps/*", "packages/*"] +} +``` + +## Package Structure + +| Package | Name | Exports | +|---------|------|---------| +| `apps/web` | `@dashboard/web` | - | +| `apps/server` | `@dashboard/server` | - | +| `packages/shared` | `@dashboard/shared` | types, utils, constants | +| `packages/ui` | `@dashboard/ui` | UI components | + +## Build Outputs + +- `apps/web/.output/` - TanStack Start production build +- `apps/server/dist/` - Nitro server build +- `packages/ui/dist/` - UI package build + +## Environment Files + +| File | Purpose | +|------|---------| +| `.env` | Shared environment | +| `.env.local` | Local overrides (gitignored) | +| `.env.example` | Template | + +## Dev Mode + +```bash +bun run dev +``` + +Starts: +- Web app on `http://localhost:3000` +- Nitro server (integrated) +- HMR enabled +- DevTools available + +## Production Build + +```bash +bun run build +bun run preview # Preview production build +``` diff --git a/.claude/dashboard/components.md b/.claude/dashboard/components.md new file mode 100644 index 000000000..b3055b42e --- /dev/null +++ b/.claude/dashboard/components.md @@ -0,0 +1,136 @@ +# UI Components + +> shadcn/ui + custom dashboard components + +## Component Locations + +| Category | Path | +|----------|------| +| shadcn/ui primitives | `src/components/ui/` | +| Dashboard layout | `src/components/dashboard/` | +| Auth forms | `src/components/auth/` | +| Feature-specific | `src/routes/[feature]/components/` | + +## shadcn/ui Components + +Available in `src/components/ui/`: + +| Component | Radix Base | Purpose | +|-----------|------------|---------| +| `button.tsx` | Slot | Styled button with variants | +| `card.tsx` | - | Container component | +| `feature-card.tsx` | - | Cyberpunk-styled feature cards | +| `input.tsx` | - | Text input | +| `textarea.tsx` | - | Multiline input | +| `label.tsx` | Label | Form label | +| `select.tsx` | Select | Dropdown select | +| `slider.tsx` | Slider | Range input | +| `switch.tsx` | Switch | Toggle switch | +| `avatar.tsx` | Avatar | User avatar | +| `badge.tsx` | - | Status badge | +| `dropdown-menu.tsx` | DropdownMenu | Context menus | +| `sheet.tsx` | Dialog | Side panel | +| `tooltip.tsx` | Tooltip | Hover hints | +| `separator.tsx` | Separator | Visual divider | +| `scroll-area.tsx` | ScrollArea | Scrollable container | +| `skeleton.tsx` | - | Loading placeholder | +| `sidebar.tsx` | - | Sidebar navigation | + +## Button Component + +```tsx +import { Button } from '@/components/ui/button' + +// Variants: default, destructive, outline, secondary, ghost, link +// Sizes: default, sm, lg, icon, icon-sm, icon-lg + + + +``` + +## FeatureCard Component + +Custom cyberpunk-styled card with colored borders: + +```tsx +import { + FeatureCard, + FeatureCardHeader, + FeatureCardContent, + type FeatureCardColor +} from '@/components/ui/feature-card' + +// Colors: cyan, purple, amber, emerald, rose, blue, primary + + + +

Title

+

Description

+
+ + {content} + +
+``` + +## Dashboard Layout Components + +From `src/components/dashboard/`: + +```tsx +import { DashboardLayout, AppSidebar } from '@/components/dashboard' + +// DashboardLayout wraps pages with sidebar + header + + {children} + +``` + +### DashboardLayout Props + +| Prop | Type | Purpose | +|------|------|---------| +| `title` | `string` | Page title in header | +| `description` | `string` | Subtitle in header | +| `children` | `ReactNode` | Page content | + +### AppSidebar + +Navigation sidebar with: +- Logo + branding +- Main nav (Dashboard, Timer) +- Tools nav (AI, Focus, Notes, etc.) +- System nav (Settings, Profile) +- User dropdown (profile, signout) + +## Styling Utilities + +From `src/lib/utils.ts`: + +```tsx +import { cn } from '@/lib/utils' + +// Merges Tailwind classes safely +
+``` + +## Theme System + +CSS variables defined in `src/styles.css`: + +| Variable | Purpose | +|----------|---------| +| `--primary` | Amber (main brand color) | +| `--secondary` | Cyan (accent) | +| `--background` | Deep dark blue-black | +| `--foreground` | Text color | +| `--muted` | Subdued text/bg | +| `--destructive` | Error/danger | +| `--sidebar-*` | Sidebar-specific colors | + +Custom utility classes: +- `.gradient-text` - Amber-to-cyan gradient +- `.neon-glow` - Neon text shadow +- `.cyber-border` - Gradient border +- `.animate-pulse-subtle` - Subtle pulsing +- `.animate-slide-up` - Slide in animation diff --git a/.claude/dashboard/patterns.md b/.claude/dashboard/patterns.md new file mode 100644 index 000000000..32ded6b14 --- /dev/null +++ b/.claude/dashboard/patterns.md @@ -0,0 +1,241 @@ +# Key Patterns + +> Common code patterns used throughout the dashboard + +## Server Functions + +TanStack Start server functions for server-side logic: + +```tsx +// src/lib/auth-actions.ts +import { createServerFn } from '@tanstack/react-start' +import { z } from 'zod' + +const signInSchema = z.object({ + email: z.string().email(), + password: z.string().min(1), +}) + +export const signInFn = createServerFn({ method: 'POST' }) + .inputValidator((data: unknown) => { + const parsed = signInSchema.safeParse(data) + if (!parsed.success) { + return { code: 'validation_error', message: parsed.error.issues[0]?.message } + } + return parsed.data + }) + .handler(async ({ data }) => { + // Server-side logic + const result = await workos.userManagement.authenticateWithPassword({...}) + return { success: true, session: encryptSession(result) } + }) + +// Usage in component +const result = await signInFn({ data: { email, password } }) +``` + +## Feature Module Pattern + +Organize complex features as self-contained modules: + +``` +routes/[feature]/ +├── index.tsx # Main route/page +├── components/ +│ ├── index.ts # Barrel export +│ └── [Feature]Card.tsx +├── hooks/ +│ ├── index.ts # Barrel export +│ ├── use[Feature].ts +│ └── use[Feature]Store.ts +└── lib/ + └── [domain]/ # Domain logic +``` + +Example from `/timer/`: +- `useTimerStore.ts` - Collection state +- `useTimer.ts` - Single item state +- `useTimerEngine.ts` - Tick loop +- `useCrossTabSync.ts` - Cross-tab state sync + +## Zod Schemas for Types + +Define types via Zod schemas for runtime validation: + +```tsx +// packages/shared/src/types/timer.ts +import { z } from 'zod' + +export const timerSchema = z.object({ + id: z.string(), + name: z.string(), + timerType: z.enum(['stopwatch', 'countdown', 'pomodoro']), + isRunning: z.boolean(), + elapsedTime: z.number(), + duration: z.number().optional(), + // ... +}) + +export type Timer = z.infer + +// Input schema (omit auto-generated fields) +export const timerInputSchema = timerSchema.omit({ + id: true, + userId: true, + createdAt: true, + updatedAt: true, +}) + +export type TimerInput = z.infer +``` + +## Auth Guard Pattern + +Redirect unauthenticated users: + +```tsx +// src/routes/index.tsx +import { useAuth } from '@workos/authkit-tanstack-react-start/client' +import { Navigate } from '@tanstack/react-router' + +function IndexPage() { + const { isLoading, user } = useAuth() + + if (isLoading) return + if (user) return + return +} +``` + +## Layout Components + +Wrap pages with consistent layout: + +```tsx +// src/routes/dashboard/index.tsx +import { DashboardLayout } from '@/components/dashboard' + +function DashboardPage() { + return ( + + {/* Page content */} + + ) +} +``` + +## Class Variance Authority (CVA) + +Button/component variants: + +```tsx +// src/components/ui/button.tsx +import { cva, type VariantProps } from 'class-variance-authority' + +const buttonVariants = cva( + 'inline-flex items-center justify-center rounded-md text-sm font-medium', + { + variants: { + variant: { + default: 'bg-primary text-primary-foreground hover:bg-primary/90', + destructive: 'bg-destructive text-white hover:bg-destructive/90', + outline: 'border bg-background hover:bg-accent', + ghost: 'hover:bg-accent hover:text-accent-foreground', + }, + size: { + default: 'h-9 px-4 py-2', + sm: 'h-8 px-3', + lg: 'h-10 px-6', + icon: 'size-9', + }, + }, + defaultVariants: { + variant: 'default', + size: 'default', + }, + } +) +``` + +## Settings Persistence + +Singleton pattern with localStorage: + +```tsx +// src/hooks/useSettings.ts +let globalSettings = loadSettings() +const listeners = new Set<() => void>() + +export function useSettings() { + const [settings, setSettingsState] = useState(globalSettings) + + useEffect(() => { + const listener = () => setSettingsState({ ...globalSettings }) + listeners.add(listener) + return () => listeners.delete(listener) + }, []) + + const updateSetting = (key: K, value: AppSettings[K]) => { + globalSettings = { ...globalSettings, [key]: value } + saveSettings(globalSettings) + listeners.forEach(l => l()) // Notify all subscribers + } + + return { settings, updateSetting } +} +``` + +## Animation Timing + +Staggered animations on lists: + +```tsx +{items.map((item, index) => ( +
+ +
+))} +``` + +## Error Handling Pattern + +Consistent error types: + +```tsx +export type AuthError = { + code: string + message: string + email?: string + pendingAuthenticationToken?: string +} + +// In handlers +try { + const result = await apiCall() + return { success: true, data: result } +} catch (error) { + return handleError(error) // Returns AuthError +} +``` + +## NO useCallback/useMemo + +React Compiler handles memoization automatically. Just write plain functions: + +```tsx +// DO THIS +function MyComponent() { + const handleClick = () => doSomething() + return +} + +// DON'T DO THIS (unnecessary with React Compiler) +function MyComponent() { + const handleClick = useCallback(() => doSomething(), []) + return +} +``` diff --git a/.claude/dashboard/routing.md b/.claude/dashboard/routing.md new file mode 100644 index 000000000..7ff4ea82c --- /dev/null +++ b/.claude/dashboard/routing.md @@ -0,0 +1,183 @@ +# Routing + +> TanStack Router with file-based routes + +## File-Based Routing + +Routes are in `src/routes/` and auto-generated in `src/routeTree.gen.ts`. + +## Route Tree + +``` +/ # index.tsx (auth redirect) +/auth/ + signin # auth/signin.tsx + signup # auth/signup.tsx + callback # auth/callback.tsx + forgot-password # auth/forgot-password.tsx + reset-password # auth/reset-password.tsx + error # auth/error.tsx +/dashboard/ + / # dashboard/index.tsx + ai # dashboard/ai.tsx + focus # dashboard/focus.tsx + notes # dashboard/notes.tsx + bookmarks # dashboard/bookmarks.tsx + planner # dashboard/planner.tsx +/timer/ + / # timer/index.tsx +/timer/$timerId # timer.$timerId.tsx (dynamic) +/profile # profile.tsx +/settings # settings.tsx +/api/trpc/* # api.trpc.$.tsx (tRPC handler) +/demo/* # demo pages (examples) +``` + +## Route Patterns + +### Basic Route + +```tsx +// src/routes/dashboard/index.tsx +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/dashboard/')({ + component: DashboardPage, +}) + +function DashboardPage() { + return
Dashboard
+} +``` + +### Dynamic Route + +```tsx +// src/routes/timer.$timerId.tsx +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/timer/$timerId')({ + component: TimerDetailPage, +}) + +function TimerDetailPage() { + const { timerId } = Route.useParams() + return
Timer: {timerId}
+} +``` + +### Search Params + +```tsx +import { createFileRoute, useSearch } from '@tanstack/react-router' + +export const Route = createFileRoute('/auth/signin')({ + component: SignInPage, + validateSearch: (search: Record) => ({ + reset: search.reset === 'success', + }), +}) + +function SignInPage() { + const { reset } = useSearch({ from: '/auth/signin' }) +} +``` + +### Root Layout + +```tsx +// src/routes/__root.tsx +import { createRootRouteWithContext } from '@tanstack/react-router' + +interface MyRouterContext { + queryClient: QueryClient + trpc: TRPCOptionsProxy +} + +export const Route = createRootRouteWithContext()({ + head: () => ({ + meta: [...], + links: [...], + }), + shellComponent: RootDocument, +}) + +function RootDocument({ children }: { children: ReactNode }) { + return ( + + + + + {children} + + + + + + + ) +} +``` + +## API Routes + +API routes use `api.*.ts` naming pattern: + +```tsx +// src/routes/demo/api.names.ts +import { createAPIFileRoute } from '@tanstack/react-start/api' + +export const APIRoute = createAPIFileRoute('/demo/api/names')({ + GET: async () => { + return Response.json(['John', 'Jane']) + }, +}) +``` + +## Navigation + +```tsx +import { Link, useNavigate } from '@tanstack/react-router' + +// Declarative +Go to Dashboard +Timer + +// Programmatic +const navigate = useNavigate() +await navigate({ to: '/dashboard' }) +``` + +## Router Setup + +From `src/router.tsx`: + +```tsx +import { createRouter } from '@tanstack/react-router' +import { setupRouterSsrQueryIntegration } from '@tanstack/react-router-ssr-query' +import { routeTree } from './routeTree.gen' + +export const getRouter = () => { + const rqContext = TanstackQuery.getContext() + const router = createRouter({ + routeTree, + context: { ...rqContext }, + defaultPreload: 'intent', // Preload on hover + }) + setupRouterSsrQueryIntegration({ router, queryClient: rqContext.queryClient }) + return router +} +``` + +## Auth Middleware + +From `src/start.ts`: + +```tsx +import { createStart } from '@tanstack/react-start' +import { authkitMiddleware } from '@workos/authkit-tanstack-react-start' + +export const startInstance = createStart(() => ({ + requestMiddleware: [authkitMiddleware()], +})) +``` diff --git a/.claude/dashboard/stack.md b/.claude/dashboard/stack.md new file mode 100644 index 000000000..a2c1c7192 --- /dev/null +++ b/.claude/dashboard/stack.md @@ -0,0 +1,100 @@ +# Technology Stack + +> Full-stack React with TanStack ecosystem + +## Core Dependencies + +### Framework & Build + +| Package | Version | Purpose | +|---------|---------|---------| +| `@tanstack/react-start` | ^1.132.0 | Full-stack React framework | +| `@tanstack/react-router` | ^1.132.0 | File-based routing | +| `vite` | ^7.1.7 | Build tool | +| `react` | ^19.2.0 | UI library | +| `turbo` | ^2.7.3 | Monorepo build system | +| `bun` | 1.3.5 | Package manager (via packageManager field) | + +### State & Data + +| Package | Purpose | +|---------|---------| +| `@tanstack/react-query` | Server state, caching | +| `@tanstack/react-store` | Client state management | +| `@tanstack/react-db` | DB collections | +| `@trpc/client` + `@trpc/server` | Type-safe API layer | +| `@powersync/web` | Offline-first SQLite sync | +| `convex` | Demo real-time database | + +### Auth + +| Package | Purpose | +|---------|---------| +| `@workos-inc/node` | WorkOS server SDK | +| `@workos/authkit-tanstack-react-start` | TanStack Start auth integration | +| `iron-session` | Session encryption | + +### AI + +| Package | Purpose | +|---------|---------| +| `@tanstack/ai` | AI abstractions | +| `@tanstack/ai-anthropic` | Claude provider | +| `@tanstack/ai-openai` | OpenAI provider | +| `@tanstack/ai-gemini` | Gemini provider | +| `@tanstack/ai-ollama` | Ollama provider | +| `@tanstack/ai-react` | React hooks for AI | + +### UI & Styling + +| Package | Purpose | +|---------|---------| +| `tailwindcss` | ^4.0.6 | Utility CSS | +| `@tailwindcss/vite` | Vite plugin | +| `class-variance-authority` | Variant styling | +| `clsx`, `tailwind-merge` | Class utilities | +| `@radix-ui/*` | Headless UI primitives | +| `lucide-react` | Icons | +| `sonner` | Toast notifications | + +### Forms & Validation + +| Package | Purpose | +|---------|---------| +| `@tanstack/react-form` | Form state | +| `zod` | ^4.1.11 | Schema validation | +| `@t3-oss/env-core` | Environment validation | + +### Dev Tools + +| Package | Purpose | +|---------|---------| +| `@tanstack/react-devtools` | Unified devtools panel | +| `@tanstack/react-query-devtools` | Query inspector | +| `@tanstack/react-router-devtools` | Router inspector | +| `@tanstack/react-ai-devtools` | AI debugging | +| `@biomejs/biome` | Linting/formatting | +| `vitest` | Testing | +| `babel-plugin-react-compiler` | Auto memoization | + +## Vite Plugins + +From `apps/web/vite.config.ts`: + +```ts +plugins: [ + devtools(), // TanStack devtools + nitro(), // Nitro server integration + neon, // Custom Neon DB plugin + viteTsConfigPaths(), // Path aliases + tailwindcss(), // Tailwind v4 + tanstackStart(), // TanStack Start SSR + viteReact({ // React with compiler + babel: { plugins: ['babel-plugin-react-compiler'] } + }), +] +``` + +## React Compiler Note + +The project uses React Compiler (babel-plugin-react-compiler). **Do NOT use `useCallback` or `useMemo`** - the compiler handles memoization automatically. diff --git a/.claude/dashboard/state.md b/.claude/dashboard/state.md new file mode 100644 index 000000000..a7b6b9b83 --- /dev/null +++ b/.claude/dashboard/state.md @@ -0,0 +1,187 @@ +# State Management + +> TanStack Store, Query, and local hooks + +## State Layers + +| Layer | Tool | Purpose | +|-------|------|---------| +| Server state | TanStack Query | API data, caching | +| Client state | TanStack Store | Global UI state | +| Local state | useState | Component state | +| Form state | TanStack Form | Form handling | +| Persisted | localStorage | Settings, preferences | + +## TanStack Store + +Simple reactive store for client state: + +```tsx +// src/lib/demo-store.ts +import { Store, Derived } from '@tanstack/store' + +export const store = new Store({ + firstName: 'Jane', + lastName: 'Smith', +}) + +// Derived values +export const fullName = new Derived({ + fn: () => `${store.state.firstName} ${store.state.lastName}`, + deps: [store], +}) +fullName.mount() + +// In components +import { useStore } from '@tanstack/react-store' + +function Component() { + const firstName = useStore(store, (s) => s.firstName) + const full = useStore(fullName) + + store.setState((s) => ({ ...s, firstName: 'John' })) +} +``` + +## TanStack Query + +Server state management with caching: + +```tsx +// Setup in src/integrations/tanstack-query/root-provider.tsx +import { QueryClient } from '@tanstack/react-query' +import superjson from 'superjson' + +const queryClient = new QueryClient({ + defaultOptions: { + dehydrate: { serializeData: superjson.serialize }, + hydrate: { deserializeData: superjson.deserialize }, + }, +}) + +// Usage +import { useQuery, useMutation } from '@tanstack/react-query' + +const { data, isLoading } = useQuery({ + queryKey: ['todos'], + queryFn: () => fetch('/api/todos').then(r => r.json()), +}) +``` + +## tRPC Integration + +Type-safe API with Query: + +```tsx +// Router: src/integrations/trpc/router.ts +import { createTRPCRouter, publicProcedure } from './init' + +export const trpcRouter = createTRPCRouter({ + todos: { + list: publicProcedure.query(() => todos), + add: publicProcedure + .input(z.object({ name: z.string() })) + .mutation(({ input }) => { + todos.push({ id: todos.length + 1, name: input.name }) + return todos[todos.length - 1] + }), + }, +}) + +// Usage in components +import { useTRPC } from '@/integrations/trpc/react' + +function Component() { + const trpc = useTRPC() + const { data } = trpc.todos.list.useQuery() + const addMutation = trpc.todos.add.useMutation() +} +``` + +## Settings Hook + +Custom hook with localStorage persistence: + +```tsx +// src/hooks/useSettings.ts +import { useSettings } from '@/hooks/useSettings' + +function Component() { + const { settings, updateSetting, updateSettings } = useSettings() + + // Read + console.log(settings.theme) // 'dark' | 'light' | 'system' + + // Update single + updateSetting('scanLinesEffect', false) + + // Update multiple + updateSettings({ theme: 'dark', soundEffects: true }) +} + +// Available settings +interface AppSettings { + theme: 'dark' | 'light' | 'system' + scanLinesEffect: boolean + gridBackground: boolean + reducedMotion: boolean + pushNotifications: boolean + soundEffects: boolean + timerCompleteAlert: boolean + cloudSync: boolean + localStorage: boolean + analytics: boolean + language: string + timeFormat: '12h' | '24h' +} +``` + +## WorkOS Auth State + +```tsx +import { useAuth } from '@workos/authkit-tanstack-react-start/client' + +function Component() { + const { user, isLoading, signOut } = useAuth() + + if (isLoading) return + if (!user) return + + return
Hello, {user.firstName}
+} +``` + +## Timer Feature State + +Example of feature-specific state management: + +```tsx +// src/routes/timer/hooks/useTimerStore.ts +// Manages collection of timers with localStorage + cross-tab sync + +// src/routes/timer/hooks/useTimer.ts +// Single timer state with start/stop/reset + +// src/routes/timer/hooks/useTimerEngine.ts +// Tick loop for running timers + +// src/routes/timer/hooks/useActivityLog.ts +// Activity history tracking +``` + +## PowerSync (Offline-First) + +For offline-capable data sync: + +```tsx +// src/db/powersync-connector.ts +import { DashboardConnector } from '@/db/powersync-connector' + +// Connector handles: +// - fetchCredentials: Exchange WorkOS session for PowerSync JWT +// - uploadData: Sync local changes to backend +``` + +## React Compiler Note + +Do NOT use `useCallback` or `useMemo` - the React Compiler handles memoization automatically via `babel-plugin-react-compiler`. diff --git a/.claude/dashboard/structure.md b/.claude/dashboard/structure.md new file mode 100644 index 000000000..69ce24429 --- /dev/null +++ b/.claude/dashboard/structure.md @@ -0,0 +1,102 @@ +# Code Organization + +> Web app directory structure and file patterns + +## apps/web/src/ Structure + +``` +src/ +├── routes/ # File-based routes (TanStack Router) +│ ├── __root.tsx # Root layout + providers +│ ├── index.tsx # Home (auth redirect) +│ ├── auth/ # Auth pages (signin, signup, etc.) +│ ├── dashboard/ # Dashboard pages +│ ├── timer/ # Timer feature (full module) +│ ├── demo/ # Demo/example pages +│ └── profile.tsx, settings.tsx +├── components/ +│ ├── ui/ # shadcn/ui components +│ ├── dashboard/ # Dashboard layout components +│ └── auth/ # Auth UI components +├── hooks/ # Global React hooks +├── integrations/ # Third-party integrations +│ ├── workos/ # Auth provider +│ ├── tanstack-query/ # Query provider + devtools +│ ├── trpc/ # tRPC client + router +│ └── convex/ # Convex provider (demo) +├── lib/ # Utilities and helpers +├── data/ # Demo/static data +├── db/ # Database connectors +├── db-collections/ # TanStack DB collections +├── styles.css # Global styles + Tailwind +├── router.tsx # Router creation +├── start.ts # TanStack Start instance +└── env.ts # Environment validation +``` + +## Route File Patterns + +| Pattern | Purpose | +|---------|---------| +| `__root.tsx` | Root layout (providers, devtools) | +| `index.tsx` | Index route for directory | +| `$param.tsx` | Dynamic route segment | +| `api.*.ts` | API routes (server functions) | +| `*.tsx` | Page components | + +## Feature Module Pattern + +Complex features use a module structure (see `/timer/`): + +``` +routes/timer/ +├── index.tsx # Main page component +├── components/ # Feature-specific components +│ ├── index.ts # Barrel export +│ ├── TimerCard.tsx +│ └── ... +├── hooks/ # Feature-specific hooks +│ ├── index.ts # Barrel export +│ ├── useTimer.ts +│ ├── useTimerStore.ts +│ └── ... +└── lib/ + └── storage/ # Storage adapters +``` + +## packages/shared/ Structure + +``` +packages/shared/src/ +├── index.ts # Barrel export +├── types/ +│ ├── index.ts +│ ├── timer.ts # Timer types + Zod schemas +│ └── activity-log.ts +├── utils/ +│ ├── index.ts +│ └── time.ts +└── constants/ + └── index.ts +``` + +## Import Aliases + +Configured in `tsconfig.json`: + +| Alias | Path | +|-------|------| +| `@/*` | `./src/*` | +| `@dashboard/shared` | `../../packages/shared/src/index.ts` | +| `@dashboard/ui` | `../../packages/ui/src/index.ts` | + +## Key Files + +| File | Purpose | +|------|---------| +| `src/routes/__root.tsx` | Root layout, providers, devtools setup | +| `src/start.ts` | TanStack Start with WorkOS middleware | +| `src/router.tsx` | Router creation with SSR Query | +| `src/styles.css` | CSS variables, Tailwind config, animations | +| `src/lib/auth-actions.ts` | Server functions for auth | +| `src/lib/auth-server.ts` | WorkOS server utilities | diff --git a/.claude/ideas/assistant/001-assistant-personal-ai-master.md b/.claude/ideas/assistant/001-assistant-personal-ai-master.md new file mode 100644 index 000000000..a40e40833 --- /dev/null +++ b/.claude/ideas/assistant/001-assistant-personal-ai-master.md @@ -0,0 +1,286 @@ +# 001 - Personal AI Assistant for Developers, PMs & ADHD Support + +## Vision + +A comprehensive personal assistant system built into the GenesisTools dashboard that helps developers, product managers, and ADHD-affected individuals manage context fragmentation, task paralysis, interruptions, and burnout. The system acts as an intelligent task manager, context preserver, deadline tracker, and motivation engine - working seamlessly within the web app, with optional browser extension and mobile app support in the future. + +**Core belief:** Knowledge workers lose productivity not from lack of work, but from: +- Context fragmentation (info scattered across Slack, GitHub, email, Jira) +- Task paralysis (too many options, can't decide what's next) +- Interruption overload (notifications, Slack, meetings destroy focus) +- Deadline anxiety (unclear which tasks are critical vs noise) +- Context switching cost (jumping between projects erases working memory) +- Motivation drain (ADHD brains need visible progress and celebration) + +This assistant solves these problems through intelligent task prioritization, context preservation, deadline management, and psychological reinforcement. + +## Target Users + +1. **Developers** - Context switching between projects/PRs, managing code review feedback, tracking technical debt +2. **Product Managers** - Juggling priorities across features/bugs/tech debt, communicating with teams, managing changing requirements +3. **ADHD professionals** - Executive dysfunction, decision fatigue, motivation deficits, attention regulation challenges +4. **Distributed/async teams** - Coordinating work across timezones, managing handoffs, preventing knowledge loss + +## Key Principles + +1. **Configurability over defaults** - User owns their UX. Want sidebar? Got it. Want popups? Got it. Want modals? Configurable. +2. **Non-intrusive** - Assistant helps without nagging. No forced notifications unless user enables them. +3. **Context preservation** - System remembers what you were doing, why, and what you discovered. +4. **Deadline clarity** - No ambiguity about what's critical vs nice-to-have. +5. **Dopamine-driven for ADHD** - Celebration, streaks, badges, progress visibility. +6. **Minimal friction** - Logging context takes <30 seconds. Prioritization is smart, not manual. +7. **Privacy-first** - All data stays on-device/in dashboard. No external sync without consent. + +## 14 Core Features + +### Communication & Knowledge Layer +1. **Communication Log** - Snapshot important decisions/messages into searchable dashboard +2. **Context Parking Lot** - Quick-save your thoughts when switching tasks, auto-recall later +3. **Decision Log** - Formal decision capture with reasoning and date +4. **Handoff Compiler** - Auto-generate "here is everything" docs for async handoffs + +### Deadline & Task Anxiety Layer +5. **Deadline Hierarchy** - Classify deadlines: critical/important/nice-to-have with visual urgency +6. **Critical Path Visualizer** - Show task dependencies and what blocks shipping +7. **Burndown Projection** - Given current velocity, predict deadline hit/miss +8. **Auto-Escalation Alerts** - When deadline approaches and progress lags, suggest solutions + +### Motivation & ADHD Support Layer +9. **Completion Celebrations** - Big satisfying feedback when tasks complete +10. **Micro-Celebrations** - Celebrate focus sessions, streaks, milestones +11. **Achievement Badges** - Unlock badges for consistency and achievement +12. **Weekly Review Dashboard** - Progress metrics, trend analysis, AI-generated suggestions + +### Deep Work & Focus Layer +14. **Blocker Detector** - Flag when task is blocked, suggest follow-up actions +16. **Energy/Focus Heatmap** - Understand circadian productivity patterns, optimize task timing +17. **Distraction Tracker** - Log interruptions, visualize patterns, suggest mitigation + +--- + +## Architecture Overview + +### Core Data Model + +```typescript +interface Task { + id: string + userId: string + title: string + description: string + projectId?: string + + // Deadline hierarchy + deadline?: DateTime + urgencyLevel: 'critical' | 'important' | 'nice-to-have' + isShippingBlocker: boolean + + // Task breakdown (for paralysis) + subtasks?: Task[] + + // Context management + contextParkingLot?: string // "I was debugging X, found clue in Y" + relatedDecisions?: string[] // decisionIds + relatedCommunications?: string[] // communicationLogIds + linkedGitHub?: string // PR/issue URL + + // Dependencies + blockedBy?: string[] // taskIds + blocks?: string[] // taskIds + + // Status & tracking + status: 'backlog' | 'in-progress' | 'blocked' | 'completed' + completedAt?: DateTime + focusTimeLogged: number // minutes + + // Energy/distraction + preferredTimeOfDay?: 'morning' | 'afternoon' | 'evening' + tasksInterruptedThis: string[] // taskIds that interrupted this one + + createdAt: DateTime + updatedAt: DateTime +} + +interface CommunicationLogEntry { + id: string + userId: string + source: 'slack' | 'github' | 'email' | 'manual' + title: string + content: string + relatedTaskIds?: string[] + tags?: string[] + timestamp: DateTime + createdAt: DateTime +} + +interface DecisionLogEntry { + id: string + userId: string + title: string // "Use React instead of Vue" + reasoning: string + alternatives?: string[] // Other options considered + decidedAt: DateTime + relatedTaskIds?: string[] + status: 'active' | 'superseded' | 'reversed' + createdAt: DateTime +} + +interface CompletionEvent { + id: string + userId: string + taskId: string + completedAt: DateTime + celebrationType: 'task-complete' | 'focus-session' | 'streak-milestone' | 'badge-earned' + metadata?: { + focusTimeSpent?: number // minutes + streakDays?: number + badgeName?: string + } +} +``` + +### System Architecture + +``` +Dashboard Web App +├── Task Management Module +│ ├── Task list/detail views +│ ├── Task prioritization engine +│ └── Task breakdown suggestions +├── Context Management Module +│ ├── Parking lot capture +│ ├── Communication log indexing +│ ├── Decision log storage +│ └── Search/recall system +├── Deadline & Urgency Module +│ ├── Hierarchy classification +│ ├── Critical path calculation +│ ├── Burndown projection +│ └── Auto-escalation logic +├── Motivation & Celebration Module +│ ├── Completion celebration system +│ ├── Badge/streak tracking +│ ├── Weekly review generation +│ └── Dopamine reinforcement UI +├── Focus & Energy Module +│ ├── Activity tracking +│ ├── Energy heatmap calculation +│ ├── Distraction logging +│ └── Focus pattern detection +└── Integration Layer + ├── GitHub API (read: PRs, issues, code context) + ├── Optional X Bot (write: thread saving/summarization) + ├── Chrome Extension (write: quick capture) + └── Future: Jira, Linear, Slack APIs + +``` + +### UX Configuration Tiers + +Users can configure their experience: + +**Tier 1: Dashboard-centric** (default) +- Primary view: task-focused sidebars +- Context parking lot, deadline info, celebrations in sidebars +- All interaction happens in dashboard + +**Tier 2: Integrated sidebars** (smart integration) +- User starts task in dashboard: system auto-shows relevant sidebars +- Contextual info appears as you work +- Minimal modal interruptions + +**Tier 3: Minimal modals** (non-intrusive) +- User works in code editor/design tool +- Small modals pop for: parking context, logging completion, deadline alerts +- Designed not to distract + +**Tier 4+: Chrome extension** (stretch/future) +- Browser extension for quick-capture of messages, decisions, context +- One-click "save this to assistant" +- Syncs to dashboard + +## Implementation Phases + +### Phase 1: MVP (Core Features - Solves Immediate Pain) +- Context Parking Lot (solve knowledge loss on task switching) +- Deadline Hierarchy (solve deadline anxiety) +- Completion Celebrations (solve ADHD motivation) +- Basic task management + prioritization +- **Goal:** User has clear "what's next", remembers context, gets motivated by progress +- **Estimated scope:** 3-4 weeks focused dev + +### Phase 2: Amplification (Complementary Features) +- Communication Log (solve context fragmentation) +- Decision Log (solve forgotten decisions) +- Critical Path Visualizer (understand shipping blockers) +- Blocker Detector (manage async work) +- Energy/Focus Heatmap (optimize personal productivity) +- **Goal:** User has complete visibility into work landscape and personal patterns +- **Estimated scope:** 2-3 weeks + +### Phase 3: Refinement (Polish Features) +- Handoff Compiler (async team support) +- Auto-Escalation Alerts (deadline management) +- Micro-Celebrations (momentum building) +- Achievement Badges (long-term motivation) +- Weekly Review Dashboard (meta-productivity) +- Distraction Tracker (focus protection) +- **Goal:** System is fully self-improving and team-aware +- **Estimated scope:** 2-3 weeks + +### Future: Expansion +- Jira/Linear integrations (deeper project tracking) +- Slack integration (communication auto-logging) +- Mobile app version +- Team collaboration features +- AI-powered coaching + +## Revenue Model (Optional, Decide Later) + +**Freemium approach:** +- **Free tier:** Core features (parking lot, deadline hierarchy, celebrations, basic prioritization) +- **Pro tier ($X/month):** + - AI-powered task breakdown (breaking large tasks into microtasks automatically) + - Smart priority weighting (energy + deadline + context automatically optimized) + - Advanced analytics (distraction patterns, weekly insights) + - GitHub integration (auto-pull PRs, code context) + - X bot integration (save and summarize threads) + - Advanced markdown notes (smart extraction for premium: extract blockers/dependencies/context from notes) + +## Success Metrics + +### Phase 1 +- Users complete 80%+ of planned daily tasks (up from ~50% baseline) +- 90% of users report "clear on what to do next" (vs. baseline decision fatigue) +- 85% of users report improved focus (fewer context-switching moments) +- ADHD users report 3x+ motivation from celebrations + +### Phase 2 +- Users can articulate why each deadline matters (deadline clarity) +- 80% of users report better communication/decision retention +- Average focus session duration increases 30% (fewer interruptions) + +### Phase 3 +- Users report 40%+ less burnout (from activity tracking + rest enforcement) +- Teams report 50%+ faster async handoffs (from handoff compiler) +- Overall: Users feel "in control" of their work, not controlled by it + +## Next Steps + +1. **Validate Phase 1 design** - Read 002-assistant-phase1-detailed.md +2. **Review Phase 2 roadmap** - Read 003-assistant-phase2-roadmap.md +3. **Review Phase 3 roadmap** - Read 004-assistant-phase3-roadmap.md +4. **Implementation planning** - Identify MVP scope, tech stack, timeline +5. **User research** - Test concepts with 3-5 developers/PMs/ADHD folks before full build + +--- + +## Design Philosophy Summary + +This isn't a tool that manages you. It's a tool you configure to match how you work. It remembers what you forget, clarifies what's murky, celebrates what you achieve, and protects what matters: your focus, your time, and your motivation. + +**For developers:** Less context switching, more deep work, clearer dependencies. + +**For PMs:** Less deadline anxiety, clearer priorities, better communication. + +**For ADHD folks:** Clear next step, celebration of progress, structure that supports (not judges) your executive function. diff --git a/.claude/ideas/assistant/002-assistant-phase1-detailed.md b/.claude/ideas/assistant/002-assistant-phase1-detailed.md new file mode 100644 index 000000000..f18ee35c6 --- /dev/null +++ b/.claude/ideas/assistant/002-assistant-phase1-detailed.md @@ -0,0 +1,577 @@ +# 002 - Assistant Phase 1: Detailed Design (Context, Deadlines, Celebrations) + +## Phase 1 Overview + +**Three core features that solve immediate pain:** + +1. **Context Parking Lot** - When switching tasks, quick-save your thinking. Auto-recall when you return. Solves knowledge loss from context switching. +2. **Deadline Hierarchy** - Classify tasks by urgency (critical/important/nice-to-have). Removes deadline anxiety and clarifies priorities. +3. **Completion Celebrations** - Big visual/audio feedback when you finish tasks. Builds motivation and streaks for ADHD brains. + +**Plus:** Intelligent task prioritization that considers all three factors, configurable UX tiers, and GitHub integration (read: PRs/issues). + +--- + +## Feature 1: Context Parking Lot + +### Purpose +When you context-switch (which happens constantly), your working memory is lost. "I was debugging X, found a clue in Y..." → switch to meetings → switch back → forgot what you found. + +The parking lot captures this micro-context so you can resume cleanly. + +### User Flow + +**Scenario: Developer working on Task A, gets interrupted** + +1. Task A is "Fix auth timeout bug" +2. Developer realizes: "I was debugging middleware.ts, found timeout is 5s, need to check worker pool size next" +3. Developer clicks "Park my context" (or keyboard shortcut Cmd+P) +4. Modal appears: + ``` + What were you working on? + [Auto-filled: "Fix auth timeout bug"] + + What did you discover? What's next? + [Text area] + > "Debugging middleware.ts line 47. Found timeout is 5s, need to check worker pool size next. Also check database connection pooling." + + [Park it] [Cancel] + ``` +5. Developer parks context and switches to urgent meeting +6. Later, developer returns to "Fix auth timeout bug" task +7. Task detail view shows: + ``` + ⏰ Last session: 2 hours ago + 📝 Where you left off: + "Debugging middleware.ts line 47. Found timeout is 5s, need to check worker pool size next. Also check database connection pooling." + + [Continue] [Edit] [Clear] + ``` +8. Developer clicks "Continue", resumes exactly where they left off + +### Data Model + +```typescript +interface ContextParking { + id: string + userId: string + taskId: string + content: string // User's notes on where they left off + codeContext?: { + filePath?: string // "middleware.ts" + lineNumber?: number // 47 + snippet?: string // Code snippet for reference + } + discoveryNotes?: string // What they found/learned + nextSteps?: string // What to do when resuming + timestamps: { + parkedAt: DateTime + resumedAt?: DateTime + createdAt: DateTime + } + status: 'active' | 'resumed' | 'archived' +} +``` + +### UX Implementation Tiers + +#### Tier 1: Dashboard Sidebar (Default) +``` +Main Dashboard (Task detail view) +├─ Left Sidebar: Context Parking +│ ├─ "Last parked: 2 hours ago" +│ ├─ Text display: "Debugging middleware.ts..." +│ ├─ [Edit] [Clear] buttons +│ └─ [Park new context] button +│ +├─ Center: Task details, description, checklist +│ +└─ Right Sidebar: (Deadline info, below) +``` + +Quick-park button: Always visible in task header +- Keyboard shortcut: `Cmd+P` or `Ctrl+P` +- Opens minimal modal for quick capture + +#### Tier 2: Smart Integration +``` +When user clicks "I'm working on Task X": +├─ System auto-shows relevant sidebars +├─ If previous parking exists, highlights it +├─ Auto-saves parking periodically (every 5 mins of inactivity) +│ └─ Gentle: "Want to park your context before switching?" (not forced) +└─ If user opens different task, prompts: "Save context from previous task?" +``` + +#### Tier 3: Minimal Modals +``` +User primarily works outside dashboard (code editor, etc.) +├─ Small modal when switching tasks (via dashboard): +│ ├─ "Switching from Task A to Task B. Park your context?" +│ ├─ Quick text input (single line or expand) +│ └─ [Park] [Skip] [Edit later] +│ +└─ Auto-opens parking log when resuming task + └─ Shows last context, option to clear or build on it +``` + +### Success Criteria + +- Users remember where they left off (no "what was I doing?" moments) +- Parking takes <30 seconds +- Context is auto-surfaced when resuming (no digging through notes) +- 80% of context parkings are actually useful when resumed (vs. forgotten immediately) +- Users report 20% faster resume time (vs. having to retrace steps) + +### Technical Implementation Notes + +- Parking modal appears via keyboard shortcut or button click +- Supports rich text (markdown) for code snippets +- Optional GitHub integration: auto-link to PR/issue if user mentions them +- Can include file path + line number suggestions (optional) +- Search parking logs: "Find all context from last week about auth" + +--- + +## Feature 2: Deadline Hierarchy + +### Purpose +"I have 12 urgent things due." Which one actually blocks shipping? Which one is nice-to-have? + +Deadline Hierarchy removes this ambiguity by classifying tasks into critical/important/nice-to-have with visual urgency indicators. + +### User Flow + +**Scenario: PM getting overwhelmed by deadline list** + +1. PM opens task list, sees 12 tasks with due dates +2. PM feels paralyzed: "What matters most?" +3. PM clicks on a task to edit it +4. Task edit view shows: + ``` + Task: "Update documentation for v2.0" + Due: Friday, Jan 17 + + How urgent is this? + + 🔴 CRITICAL - Blocks shipping + └─ If missed, product can't ship / customer is blocked / major incident + + 🟠 IMPORTANT - Should hit deadline + └─ If missed, causes downstream issues / rework needed / customer impact + + 🟡 NICE-TO-HAVE - Flexible deadline + └─ If slips, customer impact is minimal / can defer to next sprint + + [Classify as CRITICAL] [Classify as IMPORTANT] [Classify as NICE-TO-HAVE] + ``` +5. PM classifies it as IMPORTANT (documentation should ship with release, but product works without it) +6. Dashboard now shows tasks color-coded by urgency +7. Priority engine uses this to suggest "what's next" + +### Data Model + +```typescript +interface DeadlineHierarchy { + taskId: string + urgencyLevel: 'critical' | 'important' | 'nice-to-have' + classificationReasoning?: string + isShippingBlocker: boolean + relatedCriticalTasks?: string[] // taskIds that depend on this + updatedAt: DateTime +} +``` + +### UX Implementation Tiers + +#### Tier 1: Dashboard Sidebar (Default) +``` +Task Detail View +├─ Center: Task title, description +├─ Right Sidebar: Deadline & Urgency +│ ├─ Due date +│ ├─ Urgency classification (buttons or dropdown) +│ │ ├─ 🔴 CRITICAL +│ │ ├─ 🟠 IMPORTANT +│ │ └─ 🟡 NICE-TO-HAVE +│ ├─ Progress toward deadline (days remaining) +│ └─ "This task blocks: [list other tasks]" +│ +└─ Quick filter on task list: + ├─ [All] [🔴 Critical Only] [🔴+🟠 Critical+Important] + └─ Smart default: "CRITICAL tasks highlighted, others lowkey" +``` + +#### Tier 2: Smart Integration +``` +Task list view: +├─ Auto-sorts by urgency + deadline +├─ Color-codes rows: Red (critical), Orange (important), Yellow (nice) +├─ When user hovers task, shows: "This is CRITICAL. If missed, [reason]" +└─ Pinning: User can pin critical tasks to top +``` + +#### Tier 3: Minimal Modals +``` +When user marks task complete: +├─ Modal: "Great! You completed [task name]" +├─ Shows urgency: "This was CRITICAL. You're on track! 🔥" +└─ Auto-advances to next critical task if any remain +``` + +### Smart Prioritization + +The assistant uses deadline hierarchy to suggest next task: + +``` +Algorithm: NextTaskPriority = f(urgency, deadline, energy, context) + +1. Filter by urgency: + a. If any CRITICAL tasks exist: suggest highest-deadline CRITICAL + b. Else if IMPORTANT exist: suggest highest-deadline IMPORTANT + c. Else: suggest NICE-TO-HAVE by user's energy level + +2. Tie-breaker (if multiple same urgency): + a. User's configured preference: deadline < energy < context? + b. Days until deadline (sooner = higher priority) + c. Time already spent on task (long-stuck tasks get priority) + +3. Contextual factors (if enabled): + a. Same task as last session? (minimize switching) + b. User's peak energy time? (match task to energy) +``` + +### Success Criteria + +- PMs can classify 12 tasks' urgency in <5 minutes +- No paralysis: clear "do this first" recommendation +- 90% of classified tasks match team's actual priority +- Critical tasks never surprise with missed deadlines +- Users feel confident deadlines are set correctly + +### Technical Notes + +- Classification is quick: buttons, not text input +- Optional: Team-wide urgency standard (if async team feature exists) +- Search: "Show all critical tasks due this week" +- Reporting: "You hit 100% of critical deadlines this month" (motivation!) + +--- + +## Feature 3: Completion Celebrations + +### Purpose +ADHD brains need dopamine. Finishing a task should feel **rewarding**, not just another item crossed off. + +Completion Celebrations make finishing tasks satisfying through visual/audio feedback, streaks, and badges. + +### User Flow + +**Scenario: Developer finishes a task** + +1. Developer is working on "Fix auth timeout bug" +2. They mark task complete: [Mark complete] button +3. BOOM. Full-screen celebration: + ``` + 🎉 🎉 🎉 + + YOU DID IT! + "Fix auth timeout bug" ✅ + + 🔥 3-day focus streak! + 💪 You've completed 12 tasks this week + ⏱️ You spent 2h 34m focused + + [Next task →] [Rest now] [Back to dashboard] + ``` +4. Confetti animation, celebratory sound (if enabled) +5. Task disappears from active list +6. Streak counter increments + +### Micro-Celebrations + +Beyond full-screen completions, celebrate smaller wins: + +**Focus session milestone:** +``` +User logs 25-minute focused work → gentle celebration +"Nice focus! Keep it up. 🎯" +``` + +**Streak achievement:** +``` +User hits 7-day task completion streak +"🔥 7-DAY STREAK! You're on FIRE!" +``` + +**Badge earned:** +``` +User completes 100 tasks total +"🏆 TASK MASTER - You've completed 100 tasks!" +``` + +### Data Model + +```typescript +interface CompletionEvent { + id: string + userId: string + taskId: string + completionType: 'task-complete' | 'focus-session' | 'streak-milestone' | 'badge-earned' + completedAt: DateTime + celebrationShown: boolean + metadata: { + focusTimeSpent?: number // minutes + taskUrgency?: string // 'critical', 'important', etc. + currentStreak?: number // days + totalTasksCompleted?: number + } +} + +interface Streak { + userId: string + currentStreakDays: number + longestStreakDays: number + lastTaskCompletionDate: DateTime + streakResetDate?: DateTime // When current streak started +} + +interface Badge { + id: string + userId: string + badgeType: 'task-master-100' | 'focus-warrior-50' | 'streak-week' | 'streak-month' | 'consistency' + earnedAt: DateTime + displayName: string // "Task Master (100 tasks)" + rarity: 'common' | 'uncommon' | 'rare' | 'legendary' +} +``` + +### UX Implementation Tiers + +#### Tier 1: Dashboard Celebration (Default) +``` +Task List View +├─ User checks [✓] to mark complete +├─ Full-screen celebration overlay appears +│ ├─ Confetti animation (canvas-based, not annoying) +│ ├─ Sound effect (optional, configurable) +│ ├─ Text: "YOU DID IT!" +│ ├─ Stats: streak, focus time, tasks this week +│ ├─ Badges earned (if applicable) +│ └─ Buttons: [Next task] [Rest now] [Dashboard] +│ +└─ After celebration: Task removed from active, added to completed + └─ Weekly summary shows: "+1 task ✅ completed today" +``` + +#### Tier 2: Smart Integration +``` +Celebration context-aware: +├─ Critical task completed: "CRITICAL TASK DONE! You're shipping on time! 🚀" +├─ Long-stuck task completed: "You finally crushed that blocker! 💪" +├─ During focus session: "25-min focus complete. Next task?" (gentle, not full celebration) +└─ Streak milestone: Full celebration + special badge +``` + +#### Tier 3: Minimal Celebration (Non-intrusive) +``` +If user dislikes full-screen: +├─ Task disappears + subtle notification: "✅ Task completed! +1 day streak" +├─ Celebration info available in dashboard "Recent wins" section +└─ Streaks/badges visible in profile, not forced +``` + +### Celebration Customization + +Users configure celebration style: + +``` +Settings → Celebrations +├─ [🎉 FULL PARTY] Big celebration, confetti, sound +├─ [✨ SUBTLE] Toast notification + streak update +├─ [🤫 SILENT] Task marked complete, stats in dashboard only +├─ Sound effects: + ├─ Enabled / Disabled + ├─ If enabled: [Chime] [Fanfare] [Retro game] [Custom audio URL] +└─ Confetti: + ├─ Enabled / Disabled / Low-motion mode +``` + +### Weekly Review (Motivation) + +Every Friday, show a quick review: + +``` +Weekly Review +├─ Tasks completed: 12 / 15 (80%) +├─ Focus streak: 5 days active +├─ Total focus time: 16 hours +├─ Best day: Thursday (4 tasks) +├─ Trend: ↑ 20% vs last week (AWESOME!) +├─ Badges earned this week: 1 new badge +└─ AI insight: "Your focus is best 10am-12pm. Try scheduling deep work then." +``` + +### Success Criteria + +- 90%+ of users enjoy celebrations (vs. finding them annoying) +- ADHD users report 3x higher motivation to complete tasks +- Users develop consistent daily completion habit +- 30-day streak is achievable and motivating goal +- Celebrations don't distract from actually working + +### Technical Implementation Notes + +- Celebration animation via Canvas API (low-overhead) +- Sound effects: small audio files, user can upload custom +- Confetti respects prefers-reduced-motion accessibility setting +- Stats calculation: query completions for streak, count, dates +- Badge unlocking: rules-based system (100 tasks = badge, etc.) + +--- + +## Integration: Smart Task Prioritization + +Phase 1 features combine into intelligent "What should I do next?" system: + +``` +NextTaskRecommendation algorithm: + +1. Filter active tasks +2. Sort by: + a. Urgency (CRITICAL → IMPORTANT → NICE-TO-HAVE) + b. Days until deadline (sooner = higher) + c. Time spent (if stuck >4 hours, boost priority) +3. Adjust by: + a. Context switching cost (if previous task same project, favor it) + b. User's energy type & time of day (morning/afternoon/evening) + c. User's configured weight: deadline > energy > context? +4. Surface with: + a. Task context (parking lot info if resuming) + b. Urgency label ("CRITICAL: Blocks shipping") + c. Celebration motivation ("3-day streak going! Keep it up!") +``` + +### Dashboard "What Next?" Widget + +``` +Home Page Widget: + +What should you do right now? + +🔴 [Task title] - CRITICAL +Due tomorrow · ~2 hours · Blocks shipping + +📝 Where you left off: +"Debugging middleware.ts line 47. Found timeout is 5s..." + +🔥 3-day streak + +[Start working] [Not now] [Details] +``` + +--- + +## GitHub Integration (Phase 1) + +### Scope +- Read-only: Pull PRs and issues assigned to user +- Link tasks to PRs/issues +- Auto-populate task context from GitHub + +### User Flow + +1. User creates task in assistant +2. Optional: "Link to GitHub PR/issue" +3. Assistant fetches: + - PR title, description, comments + - Issue details, linked issues + - Code review requests + - CI status +4. Display in task context: + ``` + Task: Fix auth timeout bug + + Linked GitHub: #1234 - Fix auth timeout (PR) + Status: Awaiting review from @sarah + CI: ✅ Passing + ``` + +### Data Model + +```typescript +interface GitHubLink { + taskId: string + repoUrl: string + itemType: 'pull_request' | 'issue' + itemNumber: number + title: string + status: string // 'open', 'merged', 'closed' + lastSyncedAt: DateTime +} +``` + +### Technical Notes + +- Use GitHub API (requires OAuth or personal token) +- Read-only initially (no push back to GitHub) +- Scheduled sync: refresh every 1 hour (or on-demand) +- Graceful degradation: if GitHub API fails, show cached data + +--- + +## Phase 1 Implementation Roadmap + +### Week 1: Core Infrastructure +- [ ] Task management backend (create, update, delete, fetch) +- [ ] Context parking modal & storage +- [ ] Deadline hierarchy classification +- [ ] Data models & database schema + +### Week 2: UI & UX +- [ ] Task list view with urgency coloring +- [ ] Task detail sidebar with context + deadline info +- [ ] Completion celebration system (full-screen modal) +- [ ] Configurable celebration settings + +### Week 3: Smart Features +- [ ] Smart prioritization algorithm +- [ ] "What next?" recommendation widget +- [ ] Weekly review dashboard +- [ ] GitHub OAuth + read integration + +### Week 4: Polish & Testing +- [ ] Keyboard shortcuts (Cmd+P for parking, etc.) +- [ ] Accessibility audit (WCAG 2.1 AA) +- [ ] ADHD-friendly testing (user feedback loops) +- [ ] Mobile responsiveness +- [ ] Error handling & edge cases + +--- + +## Success Metrics (Phase 1) + +### Adoption +- 80%+ of users set deadline hierarchy on first 10 tasks +- 70%+ of users park context at least once per session +- 90%+ of users enjoy (vs. disable) celebrations + +### Productivity +- Users complete 80% of planned daily tasks (vs. 50% baseline) +- Average task completion time decreases 20% (from faster resumption) +- Users report "clear on what to do next" at 9/10 confidence + +### ADHD Support +- ADHD users report 3x higher task completion rate +- Motivation improvement: users want to maintain streaks +- Focus improvement: fewer "what was I doing?" moments + +--- + +## Open Questions for Phase 1 + +1. Should parking context auto-save periodically, or manual only? +2. Should celebration be customizable per task (mute a specific task's celebration)? +3. Should team members see each other's deadline urgencies? +4. Should GitHub linking be automatic (detect mentions) or manual? +5. Should parking lot have a character limit, or markdown support? diff --git a/.claude/ideas/assistant/003-assistant-phase2-roadmap.md b/.claude/ideas/assistant/003-assistant-phase2-roadmap.md new file mode 100644 index 000000000..2fc8caccc --- /dev/null +++ b/.claude/ideas/assistant/003-assistant-phase2-roadmap.md @@ -0,0 +1,612 @@ +# 003 - Assistant Phase 2: Roadmap (Communication, Context, Analytics) + +## Phase 2 Overview + +After Phase 1 establishes core task management with context preservation and deadline clarity, Phase 2 amplifies the assistant's intelligence through: + +1. **Communication Log** - Aggregate decisions/messages from scattered sources into searchable knowledge base +2. **Decision Log** - Formal capture of decisions to prevent re-debating +3. **Critical Path Visualizer** - Understand task dependencies and shipping blockers +4. **Blocker Detector** - Intelligently flag when tasks are blocked and suggest actions +5. **Energy/Focus Heatmap** - Understand personal circadian productivity patterns + +**Phase 2 adds:** Complete visibility into work landscape + personal productivity optimization + +**Timeline estimate:** 2-3 weeks after Phase 1 ships and stabilizes + +--- + +## Feature 1: Communication Log + +### Problem +Decisions are scattered: "We decided on React in a Slack thread", "Use Docker for deployment in code review comments", "Postpone refactoring in a standup". Finding or recalling these decisions is hard. + +### Solution +One unified log of important decisions/messages from Slack, GitHub, email, manual entry. Searchable, taggable, linked to tasks. + +### User Flow + +1. User encounters important message in Slack/GitHub +2. Options: + - **Manual entry:** Opens Communication Log, clicks "Add decision/message" + ``` + Title: Decided to use React hooks instead of classes + Source: Slack #architecture + Content: [paste or type] + Tags: [architecture, frontend, decision] + Related tasks: [link to tasks affected] + ``` + - **Quick capture (future):** Chrome extension context menu → "Save to Communication Log" + +3. User later searches: "What did we decide about state management?" + - Search results show decision entries + - Each shows: date, source, reasoning, related tasks + - Can click to expand full context + +### Data Model + +```typescript +interface CommunicationLogEntry { + id: string + userId: string + title: string + content: string + source: 'slack' | 'github' | 'email' | 'manual' | 'meeting_notes' + sourceUrl?: string // Link back to Slack thread, GitHub comment, etc. + + // Metadata + discussedAt: DateTime + loggedAt: DateTime + tags?: string[] // 'architecture', 'decision', 'blocker', 'urgent' + relatedTaskIds?: string[] // Links to affected tasks + sentiment?: 'decision' | 'discussion' | 'blocker' | 'context' + + // Search + searchableContent: string // Indexed for search + + updatedAt: DateTime +} + +// Search index (for fast queries) +interface CommunicationIndex { + userId: string + entries: CommunicationLogEntry[] + lastRebuilt: DateTime + // Elasticsearch or similar for production +} +``` + +### UX + +**Dashboard view:** +``` +Main nav: [Tasks] [Calendar] [Communication Log] [Decisions] [Analytics] + +Communication Log page: +├─ Search bar: "Search decisions, messages, context..." +├─ Filter tabs: [All] [Decisions] [Blockers] [Context] [Custom tags] +├─ Results list: +│ ├─ "Decided to use React hooks" - 2 weeks ago - #architecture +│ ├─ "Database migration postponed" - 3 days ago - #blocker +│ └─ "Use Docker for prod deployment" - 1 month ago - #infrastructure +│ +├─ Click entry to expand: +│ ├─ Full content +│ ├─ Source (Slack thread link, GitHub comment, etc.) +│ ├─ Related tasks: [Task A] [Task B] +│ ├─ Comments section (add follow-up context) +│ └─ Edit / Archive options +``` + +**Task integration:** +When viewing a task, related communication entries show in sidebar: +``` +Task: Implement state management + +📞 Related decisions: +"Decided to use React hooks instead of classes" (link to log entry) +"Use Redux or Context API?" (discussion thread link) +``` + +### Integration with Other Features + +**Decision Log (Feature 2):** Decisions can auto-populate decision log +**Task context:** Communication entries appear in task detail +**Search:** Global search includes communication log +**Teams (future):** Team members can access shared communication log + +### Success Criteria + +- Users can find any important decision from the last 6 months in <1 minute +- 80% of decisions are captured before being forgotten +- 0 re-debates of settled decisions (vs. "I thought we decided this differently") +- Search is fast and accurate (vs. scrolling through Slack) + +### Technical Notes + +- Search: Implement full-text search (Postgres `tsvector` or Elasticsearch) +- Import: Option to bulk-import from Slack API later +- Archive: Old entries archive after 1 year (manual or auto) +- Notifications: Can receive digest of new communication log entries + +--- + +## Feature 2: Decision Log + +### Problem +"Didn't we decide this already?" +Decisions are made, forgotten, and re-debated. Same 3-hour discussion happens quarterly. + +### Solution +Formal decision capture with reasoning, alternatives considered, date. When reconsidering a decision, system surfaces it. + +### User Flow + +1. Team makes decision: "Use Vue instead of React" +2. User opens Decision Log, clicks "Add decision" + ``` + Decision: Use Vue instead of React for new dashboard + + Reasoning: + - Smaller bundle size (important for mobile) + - Faster prototyping for tight deadline + - Team expertise with Vue higher + + Alternatives considered: + - React (full ecosystem, but heavier) + - Svelte (too new, less team familiarity) + - Angular (overkill for our needs) + + Status: ACTIVE + Decided at: [date] + By: [user] + ``` + +3. 6 months later, someone suggests "Should we use React instead?" +4. System surfaces: "We decided on Vue 6 months ago because [reasoning]. Alternatives: React, Svelte, Angular. Want to supersede this decision?" +5. If yes, mark old decision as SUPERSEDED, create new decision: "Switch to React" + +### Data Model + +```typescript +interface DecisionLogEntry { + id: string + userId: string + title: string + reasoning: string // Why this decision + alternativesConsidered?: string[] // Other options + decidedAt: DateTime + decidedBy: string // userId + status: 'active' | 'superseded' | 'reversed' | 'archived' + + // Tracking + relatedTaskIds?: string[] + impactArea?: string // 'frontend', 'backend', 'infrastructure', 'process' + reversedAt?: DateTime + reversalReason?: string + + updatedAt: DateTime +} + +// Decision recurrence detection +interface DecisionRecurrence { + originalDecisionId: string + timesReconsidered: number + lastReconsideredAt: DateTime +} +``` + +### UX + +**Dashboard:** +``` +Decisions page: +├─ Status tabs: [Active] [Superseded] [Reversed] [All] +├─ Filter by: [Frontend] [Backend] [Process] [Team] +├─ Timeline view (optional): +│ ├─ Most recent decisions first +│ └─ Shows reversals/supersessions +│ +├─ Each decision shows: +│ ├─ Title + reasoning (one-line summary) +│ ├─ Date decided +│ ├─ Status + context +│ └─ [View details] [Reverse decision] [Archive] +``` + +**Alert system:** +When user or system detects someone might be re-debating: +``` +❓ Wait, didn't we decide this? + +Decision: "Use Vue instead of React" +Decided: 6 months ago +Reasoning: Smaller bundle, faster prototype, team expertise + +Want to supersede this decision? +[Explore alternatives] [Stick with Vue] [Reverse decision] +``` + +### Integration + +**Task context:** Decision log entries link to related tasks +**Communication Log:** Important discussions reference decisions +**Team collaboration (future):** Team sees decision timeline + reasoning + +### Success Criteria + +- 0 repeated decision debates (same question not re-debated) +- 90% of decisions captured before being questioned +- Decision clarity: "Why did we choose Vue?" answered in <10 seconds +- Easy reversals: When reconsideration is warranted, system supports it smoothly + +--- + +## Feature 3: Critical Path Visualizer + +### Problem +With multiple tasks, it's unclear what blocks shipping. "Task A depends on B, B depends on C, so if C is delayed..." becomes too complex to think through. + +### Solution +Visual dependency graph showing task relationships and critical path to shipping. + +### User Flow + +1. User has project: "v2.0 release" with 15 tasks +2. Tasks have dependencies: + ``` + Design mockups → Frontend implementation → Code review + ↓ (both needed for) + Integration testing → Deployment → Release + + Backend API → Integration testing (above) + Database schema → Backend API + ``` + +3. User clicks "Show critical path" in project view +4. System visualizes: + ``` + [Design] →→→→→→ [Frontend] → [Code review] + ↓ + [Schema] → [API] ─────→→→→→ [Integration test] → [Deploy] → [Release] + ``` + +5. Critical path (longest chain) highlighted in RED: + ``` + Schema → API → Integration → Deploy → Release + (5 days to complete, currently at day 2) + ``` + +6. UI shows: + ``` + 🔴 Critical path to release: 5 days + ✅ Current progress: Schema complete, API 50% done + ⚠️ If API takes >3 more days, you'll miss deadline + ``` + +### Data Model + +```typescript +interface TaskDependency { + taskId: string + dependsOn: string[] // Array of taskIds this depends on + blocksShipping: boolean // Is this part of critical path? + estimatedDays: number // Estimated time to complete +} + +interface CriticalPath { + projectId: string + tasks: string[] // Ordered list of taskIds in critical path + totalDays: number + daysRemaining: number + isOnTrack: boolean // Will deadline be hit? + bottlenecks: string[] // taskIds that are slowing progress +} +``` + +### UX + +**Project view:** +``` +Project: v2.0 Release +├─ Dashboard card shows: "Critical path: 5 days | 2 days complete" +├─ Visual graph (interactive): +│ ├─ Click node to see task details +│ ├─ Drag to reorganize (if can move tasks) +│ ├─ Color coding: Red (critical path), Gray (non-blocking) +│ └─ Hover edge to see dependency reason +│ +└─ Analysis panel: + ├─ "Critical path: Schema → API → Testing → Deploy → Release" + ├─ "Bottleneck: API (50% done, blocking 3 other tasks)" + ├─ "Risk: If API takes >3 more days, deadline at risk" + └─ [Accelerate API] [Parallelize testing] [Extend deadline] +``` + +### Success Criteria + +- Users understand what blocks shipping in <30 seconds +- Critical path identifies true bottleneck (validated by team) +- On-time shipping: projects using critical path ship 90% on time +- Prevents surprises: "Didn't know this task blocked everything" + +### Technical Notes + +- Dependency graph calculation: topological sort to find critical path +- Visualization: D3.js or similar for interactive graph +- Estimates: Use task time-spent data + projections +- Recalculates: Daily or when tasks updated + +--- + +## Feature 4: Blocker Detector + +### Problem +Task is stuck: "Waiting on code review from Sarah", "Can't proceed without database schema", "Need design approval". +Without tracking this, blockers are invisible, and you waste time on tasks that can't be completed. + +### Solution +System detects when tasks are blocked and intelligently suggests follow-ups or context for next person. + +### User Flow + +1. User logs: "Task A blocked. Waiting on code review from @sarah" +2. System detects blocker: + ``` + Task A: Implement user auth + Status: BLOCKED + Reason: "Waiting on code review from @sarah" + Blocked since: 2 days ago + ``` + +3. Assistant suggests: + - "Remind Sarah about pending review?" (auto-draft message) + - "Switch to Task B while waiting?" (show non-blocked tasks) + - "Follow up with Sarah in 24h if no response?" (set reminder) + +4. When Task A becomes unblocked (review arrives), system notifies: + ``` + ✅ Your blocker is resolved! + Task A: Code review approved by @sarah + Ready to merge and move forward + ``` + +### Data Model + +```typescript +interface TaskBlocker { + taskId: string + status: 'blocked' | 'unblocked' + reason: string // "Waiting on code review", "Awaiting design approval" + blockedSince: DateTime + unblockedAt?: DateTime + blockerOwner?: string // Person/team blocking (if applicable) + followUpAction?: string // "Remind in 24h", "Switch to Task B" + relatedTaskIds?: string[] // Other tasks blocked by same issue +} +``` + +### UX + +**Task detail view:** +``` +Task: Implement user auth + +Status: 🔴 BLOCKED +├─ Reason: "Waiting on code review from @sarah" +├─ Blocked since: 2 days ago +├─ Quick actions: +│ ├─ [Remind @sarah] "Hey Sarah, when you get a moment..." +│ ├─ [Switch to Task B] (show available non-blocked tasks) +│ ├─ [Set reminder] (remind you in 24h to follow up) +│ └─ [Mark unblocked] (manually if blocker resolved) +``` + +**Dashboard blocker list:** +``` +Your blockers: +├─ Task A (blocked 2 days) +├─ Task B (blocked 5 hours) +└─ Task C (blocked 1 day) + +Recommendations: +├─ "Remind @sarah about Task A review" +├─ "Follow up on Task C (design approval)" +└─ "Task B should be unblocked soon, check status" +``` + +### Integration with Async Features (Future) + +When task is handed off to teammate: +``` +Handoff package includes: +├─ Task description +├─ Blocker status (if any): "Waiting on Sarah's code review" +└─ Suggested follow-up: "Remind Sarah in 24h if not reviewed" +``` + +### Success Criteria + +- 0 forgotten blockers (all visible in dashboard) +- Users spend 50% less time on blocked tasks (switch to unblocked work) +- Blockers are resolved 30% faster (reminders + visibility) +- No surprises when tasks are supposed to ship + +### Technical Notes + +- Detection: Can be manual (user tags task as blocked) or AI-assisted (detect "waiting on", "blocked by" in notes) +- Reminders: Optional scheduled notifications +- Analytics: Track blocker patterns (what blocks most work?) + +--- + +## Feature 5: Energy/Focus Heatmap + +### Problem +"When am I most productive?" isn't obvious. Some people code best 6am-9am, others 10pm-midnight. +Matching task types to peak energy = more productive work, fewer context switches. + +### Solution +Analyze task completion times + focus quality throughout week. Show when user is most productive, recommend optimal task timing. + +### User Flow + +1. System collects data over 2-3 weeks: + - When user completes tasks (task done timestamps) + - How many context switches per hour + - Focus session quality (how long uninterrupted) + - User-reported energy at task completion + +2. After sufficient data, Energy Heatmap appears: + ``` + Your productivity patterns: + + ┌─────────────────────────────────────────┐ + │ Mon Tue Wed Thu Fri Sat Sun │ + │ │ + │ 9am 🔴 🟠 🟠 🟠 🟠 ⬜ ⬜ │ Best focus + │ 12pm 🟡 🟡 🟡 🟡 🟡 🟡 🟡 │ Medium focus + │ 3pm 🔵 🔵 🔵 🔵 🔵 🟡 🟡 │ Interrupted/low + │ 6pm ⬜ ⬜ ⬜ ⬜ ⬜ 🔵 🔵 │ Low energy + │ │ + └─────────────────────────────────────────┘ + + Insights: + ├─ "Your peak focus: Monday-Friday 9am-12pm (RED zone)" + ├─ "Afternoon slump: 3pm-5pm consistent pattern" + ├─ "Weekend: Lower energy but good for admin tasks" + └─ "Task recommendation: Schedule deep work 9am-12pm, meetings 3pm-5pm" + ``` + +3. System uses this for task recommendations: + - It's 9am Monday: "Perfect time for deep coding work. Task A (complex)?" + - It's 3pm Friday: "Energy dip time. Try Task B (administrative)?" + +### Data Model + +```typescript +interface EnergySnapshot { + userId: string + timestamp: DateTime + focusQuality: 1 | 2 | 3 | 4 | 5 // Self-reported or calculated + contextSwitches: number // # of task switches in last hour + tasksCompleted: number + typeOfWork?: 'deep-work' | 'communication' | 'admin' | 'meeting' +} + +interface EnergyHeatmap { + userId: string + pattern: { + [dayOfWeek: string]: { + [hour: number]: { + avgFocusQuality: number + avgContextSwitches: number + suggestedTaskType: string + } + } + } + peakHours: string[] // ["Monday 9-12", "Friday 2-4"] + lowEnergyHours: string[] + calculatedAt: DateTime +} +``` + +### UX + +**Dashboard Analytics page:** +``` +Energy & Productivity Analytics +├─ Heatmap grid (interactive): +│ ├─ Hover cell to see detail: "Mon 10am: 4.5/5 focus, 1 switch, 3 tasks done" +│ ├─ Darker color = higher focus/productivity +│ └─ Click to see tasks completed at that time +│ +├─ Insights section: +│ ├─ "Peak focus: Mon-Fri 9am-12pm" +│ ├─ "Afternoon slump: 2pm-4pm (do admin tasks)" +│ ├─ "Context switches highest: Tuesday 2-3pm" +│ └─ "Recommendation: Block calendar 9-11am for deep work" +│ +└─ Task recommendation banner: + ├─ "It's 9:15am Monday (your peak time)" + ├─ "Best for: Deep technical work" + └─ [Work on Task A (complex)] [See all options] +``` + +### Integration + +**Task prioritization:** Energy considered in "What next?" algorithm +**Focus protection:** "Block 2-hour deep work at your peak time?" suggestion +**Team insights (future):** Understand team's collective productivity patterns + +### Success Criteria + +- Users identify their peak 4 hours/week within 2 weeks +- Deep work scheduled during peak hours: 80% of deep work +- Productivity increases 20% by matching task type to energy +- Users report better work-life balance (no forced late nights) + +### Technical Notes + +- Data collection: Automatic based on task completion + user logging +- Privacy: All analysis client-side (no external ML) +- Calculation: Aggregation over rolling 3-week window +- Visualization: Heatmap using Canvas or SVG + +--- + +## Phase 2 Timeline + +### Week 1: Communication & Decision Logs +- [ ] Communication Log storage & search +- [ ] Decision Log data model +- [ ] UI for adding/viewing entries +- [ ] Search indexing (Postgres tsvector) + +### Week 2: Dependencies & Visualization +- [ ] Task dependency linking +- [ ] Critical Path algorithm (topological sort) +- [ ] Interactive dependency visualization (D3.js) +- [ ] Blocker detection logic + +### Week 3: Analytics & Energy +- [ ] Energy snapshot collection +- [ ] Heatmap calculation algorithm +- [ ] Analytics dashboard UI +- [ ] Task recommendation integration + +### Week 4: Polish & Integration +- [ ] Cross-feature integration testing +- [ ] Performance optimization (large task graphs) +- [ ] Mobile responsiveness +- [ ] Documentation & user onboarding + +--- + +## Phase 2 Success Metrics + +- Users save 30 minutes/week searching for decisions (vs. scrolling Slack) +- 0 repeated decision debates +- Critical path catches 90% of shipping blockers before deadline slip +- Blockers resolved 30% faster +- Users identify peak productivity hours and shift work accordingly + +--- + +## Known Constraints / Future Considerations + +1. **Team collaboration:** Phase 2 focuses on individual. Shared communication log comes in Phase 3. +2. **AI detection:** Blocker detection is mostly manual initially. ML detection (surface-level NLP) in future. +3. **Slack import:** Communication Log can pull from Slack API later (after Phase 2 launch). +4. **Time estimation:** Critical path uses rough estimates. Refine with historical data over time. + +--- + +## Transition to Phase 3 + +Phase 2 provides complete visibility into work landscape. Phase 3 adds: +- Handoff automation (async team support) +- Auto-escalation (deadline warnings before crisis) +- Advanced celebrations (badges, achievements) +- Weekly/monthly reviews +- Distraction pattern analysis diff --git a/.claude/ideas/assistant/004-assistant-phase3-roadmap.md b/.claude/ideas/assistant/004-assistant-phase3-roadmap.md new file mode 100644 index 000000000..ef60172a8 --- /dev/null +++ b/.claude/ideas/assistant/004-assistant-phase3-roadmap.md @@ -0,0 +1,778 @@ +# 004 - Assistant Phase 3: Roadmap (Automation, Gamification, Reviews) + +## Phase 3 Overview + +After Phase 1 & 2 establish individual productivity and work visibility, Phase 3 adds: + +1. **Handoff Compiler** - Auto-generate context documents when tasks move to teammates +2. **Auto-Escalation Alerts** - Smart deadline management before crisis hits +3. **Micro-Celebrations** - Build momentum through smaller wins +4. **Achievement Badges** - Long-term motivation system +5. **Weekly Review Dashboard** - Meta-productivity analysis +6. **Distraction Tracker** - Visualize interrupt patterns and suggest fixes + +**Phase 3 adds:** Async team support + long-term behavioral change + burnout prevention + +**Timeline estimate:** 2-3 weeks after Phase 2 stabilizes + +--- + +## Feature 1: Handoff Compiler + +### Problem +Async teams lose context in handoffs. Person A finishes work, hands to Person B. Person B spends 2 hours re-learning context that Person A knew in their sleep. + +### Solution +When task moves to new owner, auto-compile: notes, decisions, GitHub context, blockers, next steps into "here's everything you need to know" document. + +### User Flow + +1. Developer A completes code review on Task: "Implement user auth" +2. Task owner changes from Dev A to Dev B +3. System auto-generates: + ``` + 📋 HANDOFF DOCUMENT: Implement user auth + + 🎯 SUMMARY + Implement OAuth2 authentication for user login. Mostly done, needs final review and deployment. + + 📝 CONTEXT + Original context notes from Dev A: + "Built OAuth flow using Google provider. Used middleware.ts for token validation. + Found: token refresh was timing out at 5s, extended to 10s in config. + Next step: Final code review, merge to main, deploy to staging." + + 🔗 DECISIONS MADE + - Use Google OAuth (vs. GitHub, Okta) - decided because: user base is mostly on Google + - Token refresh timeout: 10 seconds (was 5s, too short for slow connections) + - Store refresh token in HttpOnly cookie (security best practice) + + 🔍 CODE CONTEXT + Main files: + - middleware.ts (line 47-89): Token validation logic + - auth/oauth.ts (line 12-156): OAuth provider setup + - database/schema (line 234): Auth table structure + + GitHub PR: #1234 - Implement user auth + Status: Awaiting final review from @sarah + CI: ✅ Passing + Code review: Sarah requested changes on 3 comments (resolved) + + ⚠️ BLOCKERS + - Awaiting @sarah's final review (1 day) [EXPECTED TO RESOLVE TODAY] + + ✅ NEXT STEPS + 1. Final review from @sarah + 2. Merge to main when approved + 3. Deploy to staging for QA + 4. Deploy to production (if QA passes) + + 📞 QUESTIONS / GOTCHAS + Dev A's notes: "If you need to change the Google provider credentials, they're in AWS Secrets Manager. Let me know if you hit any OAuth flow weirdness." + + Contact: @dev-a (Slack) for questions + ``` + +4. Dev B opens task, sees handoff document, understands everything in 5 minutes instead of 2 hours + +### Data Model + +```typescript +interface HandoffDocument { + id: string + taskId: string + handedOffFrom: string // userId + handedOffTo: string // userId + handoffAt: DateTime + + // Auto-compiled sections + summary: string // 1-2 paragraph overview + contextNotes: string // Parking lot + task notes + decisions: DecisionLogEntry[] // Related decisions + codeContext?: { + files: Array<{ path: string; lines: string; description: string }> + githubPR?: { number: string; title: string; status: string } + } + blockers: TaskBlocker[] + nextSteps: string[] // Ordered list + gotchas?: string // "Watch out for..." section + contact: string // Original owner's contact info + + // Status + reviewed: boolean // Did new owner acknowledge? + reviewedAt?: DateTime +} +``` + +### UX + +**Task receiving handoff:** +``` +Task detail view: +├─ Alert banner: "This task is being handed off to you from @dev-a" +├─ [View handoff document] button +│ ├─ Opens modal/sidebar with compiled document +│ ├─ All sections searchable +│ ├─ Can add notes: "I'll reach out if confused" +│ └─ [Acknowledge] button (marks as reviewed) +│ +├─ Related context auto-surfaces: +│ ├─ Decision log entries +│ ├─ Communication log entries +│ ├─ GitHub PR details +│ └─ Parking lot notes +``` + +**Task giver:** +``` +When reassigning task: +├─ Modal: "Ready to hand off Task A to @dev-b?" +├─ Preview handoff document +├─ [Customize notes] (add extra context) +├─ [Send handoff] → Notifies new owner +``` + +### Integration + +**Async team management (Phase 3):** Handoff is primary mechanism for task transitions +**Communication Log:** Related decisions pull automatically +**GitHub:** PR/issue context auto-included +**Notifications:** New owner gets notification + handoff document link + +### Success Criteria + +- New task owner understands 90% of context in first 10 minutes +- Onboarding time per task reduced from 2 hours to 20 minutes +- 0 "I didn't know about..." surprises +- Async teams report 50% faster task transitions + +### Technical Notes + +- Auto-compilation: Query related decisions, GitHub data, blockers, and format into document +- Template: Use markdown template for consistency +- Versioning: Keep handoff history (in case work bounces back) + +--- + +## Feature 2: Auto-Escalation Alerts + +### Problem +Deadline is Friday. It's Thursday, task is 50% done. Do we miss it? Extend? Cut scope? +Without proactive alerts, you discover this at 4:59pm Friday. + +### Solution +System monitors progress vs. deadline. When it detects risk, proactively suggests: extend deadline, add help, or cut scope. + +### User Flow + +1. Task: "Deploy v2.0" due Friday, estimated 3 days of work +2. Current progress: 1.5 days done (50%) +3. System calculates: "At current pace, completion = Sunday" +4. Wednesday afternoon, system escalates: + ``` + ⚠️ DEADLINE RISK DETECTED + + Task: Deploy v2.0 + Deadline: Friday (2 days remaining) + Current progress: 50% (1.5 of 3 days done) + Projected completion: Sunday (+2 days late) + + OPTIONS: + 1️⃣ EXTEND DEADLINE + Extend to Sunday? + [Pro: Realistic] [Con: Blocks downstream work] + + 2️⃣ ADD HELP + Need 1.5 more days of work. Who can help? + [@dev-a: free Monday-Wednesday] [@dev-b: free today] + [Assign @dev-a to subtask X] + + 3️⃣ CUT SCOPE + What's not critical for v2.0? + - Feature A: "Nice to have" (can defer to v2.1) + - Bug B: "Critical" (must ship) + [Remove feature A from scope? Saves ~0.5 days] + + 4️⃣ ACCEPT DELAY + Proceed with current plan, miss Friday deadline + [Acknowledge risk] → Notifies stakeholders + + [Recommended: Cut Feature A + Extend 1 day → deliver Saturday] + ``` + +5. PM selects option, system updates task + notifies stakeholders + +### Data Model + +```typescript +interface DeadlineRisk { + taskId: string + riskLevel: 'green' | 'yellow' | 'red' // On track, at risk, critical + projectedCompletionDate: DateTime + daysLate: number + daysRemaining: number + percentComplete: number + velocity: number // tasks/day completed + + // Recommendations + options: { + extendDeadline?: { newDate: DateTime; reason: string } + addHelp?: { workAvailable: number; suggestedAssignees: string[] } + cutScope?: { itemsToCut: string[]; timeSavedDays: number } + acceptDelay?: { daysLate: number; notifyStakeholders: boolean } + } + recommendedOption: string // 'extend' | 'help' | 'scope' | 'accept' + + alertedAt: DateTime + resolvedAt?: DateTime + resolutionChoice?: string +} +``` + +### UX + +**Alert system:** +``` +Dashboard widget: "⚠️ 1 deadline at risk" +├─ Task list shows risk indicators: 🟡 (at risk) 🔴 (critical) +├─ Click to expand escalation alert +├─ Quick actions: [Extend] [Add help] [Cut scope] +└─ [Resolve risk] → system updates task +``` + +**Stakeholder notification (optional):** +``` +When risk escalated: +├─ Notifies project manager +├─ Suggests communication: "Task at risk. Recommending scope cut. Need approval?" +└─ Tracks decision for historical analysis +``` + +### Integration + +**Deadline Hierarchy (Phase 1):** CRITICAL tasks get earlier alerts +**Critical Path (Phase 2):** Shows cascading impact if deadline missed +**Team collaboration (Phase 3):** Notifies stakeholders/team members + +### Success Criteria + +- 0 deadline surprises (risks identified 2+ days before) +- Escalation email is read within 1 hour +- 95% of escalations resolved within 4 hours +- Shipping delays reduced 50% (issues caught earlier) + +### Technical Notes + +- Calculation: velocity = tasks_completed / time_spent +- Alert threshold: If projected_completion > deadline + 1 day +- Frequency: Check daily, alert only when risk changes + +--- + +## Feature 3: Micro-Celebrations & Feature 4: Achievement Badges + +### Problem (Micro-Celebrations) +Celebrating every task completion is good for ADHD motivation, but can feel exhausting if every single thing gets a "WELL DONE!" celebration. + +Smaller wins need lighter, contextual celebrations. + +### Solution +Graduated celebration system: +- **Micro-celebrations:** Light, quick feedback for 25-min focus sessions, small tasks +- **Regular celebrations:** Full celebration for substantial tasks +- **Milestone celebrations:** Major badges for long-term achievements + +### User Flow + +**Micro-celebration examples:** + +``` +Focus Session Complete: +"Nice! 25-minute deep work session completed. Keep that focus! 🎯" +(Toast notification, no full-screen interruption) + +Small Task Complete: +"One more done! You're building momentum. 💪" +(Brief notification, adds to daily count) + +Streak Milestone: +"🔥 5-day task completion streak!" +(Slightly more prominent, celebrates consistency) + +Badge Earned: +"🏆 TASK MASTER (100 tasks completed)" +(Full celebration modal, confetti, badge unlock animation) +``` + +### Achievement Badge System + +**Badge types:** +``` +🏆 Consistency Badges: +├─ "Week Warrior" (7-day task streak) +├─ "Month Master" (30-day task streak) +├─ "Consistency King" (100 days total, any gaps ok) + +📊 Productivity Badges: +├─ "Century Club" (100 tasks completed) +├─ "Magnificent Fifty" (50 tasks completed) +├─ "Decade Done" (10 tasks completed) + +⚡ Speed Badges: +├─ "Speedrunner" (Complete 5 tasks in one day) +├─ "Blitz Mode" (Complete 3 tasks before noon) + +🎯 Focus Badges: +├─ "Deep Diver" (5 hours uninterrupted focus) +├─ "Undistracted" (Full day with <3 context switches) + +🚀 Milestone Badges: +├─ "Blocker Buster" (Resolved 10 blockers) +├─ "On Time" (Ship 10 deadlines on time) + +Rarity levels: +├─ Common (easy to earn) +├─ Uncommon (requires effort) +├─ Rare (challenging) +├─ Legendary (very hard) +``` + +### Data Model + +```typescript +interface Microcelebration { + id: string + userId: string + type: 'focus-session' | 'small-task' | 'streak' | 'milestone' + message: string + displayType: 'toast' | 'badge' | 'full-screen' + metadata: { + focusMinutes?: number + streakDays?: number + tasksCompletedToday?: number + } + earnedAt: DateTime +} + +interface AchievementBadge { + id: string + badgeType: string // "century-club", "week-warrior", etc. + userId: string + displayName: string // "Century Club (100 tasks)" + description: string + rarity: 'common' | 'uncommon' | 'rare' | 'legendary' + earnedAt: DateTime + shareable: boolean // Can share to social? +} + +interface BadgeProgress { + userId: string + badges: Array<{ + badgeType: string + progress: number // Current value + target: number // Target value + percentComplete: number + earnedAt?: DateTime + }> +} +``` + +### UX + +**Dashboard badges section:** +``` +Achievements & Badges + +Earned Badges: +├─ 🏆 Century Club (100 tasks) - LEGENDARY +├─ 🏆 Week Warrior (7-day streak) - UNCOMMON +└─ 🏆 Task Master (50 tasks) - UNCOMMON + +Badges in Progress: +├─ ⚡ Speedrunner: 3 of 5 tasks in one day (60%) +├─ 📊 Month Master: 12 of 30 days active (40%) +└─ 🎯 Deep Diver: 2 of 5 hours focus (40%) + +[Share badges] [View all] +``` + +**Micro-celebration notifications:** +``` +Toast (bottom right): +✅ Nice focus session! 25 minutes of deep work. +🔥 5-day streak maintained! +💪 You're on a roll. Keep it up! +``` + +### Success Criteria + +- ADHD users maintain 50% higher completion rate (vs. no celebrations) +- Badges motivate long-term behavior change +- Users voluntarily share badges (social motivation) +- Celebration fatigue: 0 users report "too many celebrations" + +### Technical Notes + +- Micro-celebrations: Low overhead (CSS toast notifications) +- Badge logic: Rules-based system, calculated daily +- Progress: Track incrementally, show progress bars +- Sharing: Generate shareable badge images, links + +--- + +## Feature 5: Weekly Review Dashboard + +### Problem +You shipped 5 things this week, but you don't notice. You also worked 60 hours, but that gets overlooked. +Weekly reviews provide perspective and insight. + +### Solution +Every Friday, show: completed tasks, deadline performance, focus quality, energy trends, AI-generated suggestions. + +### User Flow + +1. Friday afternoon (or user-configured day), system generates weekly review: + ``` + 📊 YOUR WEEK IN REVIEW (Jan 6-12) + + ✅ COMPLETED + └─ 11 tasks completed (vs. 8 tasks last week) ↑ 38%! + + ⏱️ TIME INVESTMENT + ├─ Total work time: 45 hours (healthy!) + ├─ Deep focus: 18 hours (40% of time) + ├─ Meetings: 12 hours + └─ Administrative: 15 hours + + 🎯 DEADLINE PERFORMANCE + ├─ Deadlines hit: 9 of 10 (90%) + ├─ On-time shipping: 100% + └─ Blocker incidents: 2 (resolved same-day) + + ⚡ ENERGY TRENDS + ├─ Monday: High energy, peak focus (4.5/5) + ├─ Tuesday-Wednesday: Medium energy (3.5/5) + ├─ Thursday: Energy dip (2.8/5) + ├─ Friday: Recovering (3.2/5) + └─ Recommendation: Thursday is your slump. Schedule easier tasks or take a real break. + + 🔍 INSIGHTS FROM THE DATA + ├─ Context switches: 3 per day average (healthy!) + ├─ Focus session length: 90 minutes (good!) + ├─ Best focus: Monday 9-11am and Wednesday 2-4pm + ├─ Worst focus: Thursday 3-5pm (do admin tasks then) + └─ Blocker pattern: 60% of blockers are code review approvals. Consider pair review? + + 🚀 RECOMMENDATIONS + ├─ "You're crushing it! 38% more tasks this week." + ├─ "Thursday afternoon is your weak spot. Try a 30-min walk or lighter tasks." + ├─ "Deep work is concentrated Mon/Wed. Protect those times from meetings." + ├─ "Consider checking in with code review team about bottleneck." + + 💾 THIS WEEK'S ACHIEVEMENTS + ├─ 🏆 Streak: 7 consecutive days with task completions + ├─ 🏆 Speedrunner: Completed 5 tasks on Wednesday + └─ New badge earned: "Week Warrior" + + [Archive review] [Share with team] [Print] [Next week] + ``` + +2. User can download/print/share review +3. Reviews archive for historical analysis + +### Data Model + +```typescript +interface WeeklyReview { + userId: string + weekStart: DateTime + weekEnd: DateTime + + // Metrics + tasksCompleted: number + tasksCompletedLastWeek: number + deadlinesHit: number + deadlinesTotal: number + + // Time + totalHours: number + deepFocusHours: number + meetingHours: number + adminHours: number + + // Energy analysis + averageEnergy: number + energyByDay: Map + peakFocusTime: string // "Monday 9-11am" + lowEnergyTime: string // "Thursday 3-5pm" + + // Insights + insights: string[] // AI-generated insights + recommendations: string[] // Suggestions + blockersResolved: number + contextSwitchesPerDay: number + + // Achievements + badgesEarned: string[] // Badge IDs + streakContinued: boolean + streakDays: number + + generatedAt: DateTime +} +``` + +### UX + +**Weekly Review page:** +``` +Dashboard nav: [Tasks] [Calendar] [Communication] [Analytics] [Weekly Reviews] + +Weekly Reviews page: +├─ Dropdown: [This week] [Last week] [2 weeks ago] [Custom date range] +├─ Review content (as above) +├─ Charts: +│ ├─ Task completion trend (last 8 weeks) +│ ├─ Energy heatmap (last 4 weeks) +│ ├─ Deadline performance (% on-time) +│ └─ Focus quality trend +│ +└─ Actions: + ├─ [Share with manager] + ├─ [Share with team] + ├─ [Export PDF] + └─ [Archive] +``` + +**Email notification (optional):** +``` +Subject: Your Week in Review - You completed 11 tasks! 🚀 + +(Email version of weekly review) + +[View full review] +[Share with team] +``` + +### Integration + +**Previous features feed in:** +- Completed tasks (Phase 1) +- Energy heatmap (Phase 2) +- Critical path performance (Phase 2) +- Badges & streaks (Phase 3) + +### Success Criteria + +- 85% of users read their weekly review +- Users understand their work patterns (when they're most productive) +- Recommendations are actionable (not generic) +- Users report increased confidence in their productivity + +### Technical Notes + +- Generation: Scheduled job (Friday 5pm or user-configured) +- Analytics: Pull data from all previous features +- Insights: Template-based + data-driven +- Storage: Archive reviews for historical analysis + +--- + +## Feature 6: Distraction Tracker + +### Problem +You get interrupted constantly, but you don't track what's interrupting you. "Slack", "meetings", "hunger"—invisible patterns. + +### Solution +Log what interrupts you. System shows patterns: "You get Slack-interrupted 20x/day on Tuesday" → suggest fixes. + +### User Flow + +1. User is focused on Task A +2. Gets pulled away to Slack, email, meeting, hunger +3. Resumes Task A after distraction +4. System logs: "Switched from A → Slack → back to A (5-minute distraction)" +5. Over a week, patterns emerge: + ``` + Your distractions this week: + + 📱 Slack notifications: 47 (42%) + └─ Peak: Tuesday 2-4pm (11 interruptions) + + 📧 Email: 18 (16%) + 💬 Meetings: 15 (13%) + 🍽️ Hunger/body: 12 (11%) + 🤔 Internal context switch: 10 (9%) + 📞 Coworker walk-by: 8 (7%) + 🔊 Other: 4 (4%) + + Pattern analysis: + ├─ "Tuesday is your distraction peak (15 total). Team syncs happening?" + ├─ "Slack is your #1 distraction. Would muting Slack 9-11am help?" + └─ "Hunger interrupts you at 12:30pm. Suggest eating lunch at 12:00pm instead?" + + Recommendations: + ├─ "Set Slack to 'do not disturb' during focus hours" + ├─ "Schedule lunch at 12:00 to prevent hunger interruptions" + ├─ "Review Tuesday calendar: 3 meetings back-to-back might be causing stress" + └─ "Consider 'no meeting hours' 9-11am for focused work" + ``` + +### Data Model + +```typescript +interface Distraction { + id: string + userId: string + timestamp: DateTime + source: 'slack' | 'email' | 'meeting' | 'coworker' | 'hunger' | 'other' + description?: string // "Sarah on Slack about PR review" + duration?: number // minutes away from focused work + taskInterrupted?: string // Which task were you on? + resumedTask?: boolean // Did you return to same task? +} + +interface DistractionPattern { + userId: string + period: DateTime + patterns: Array<{ + source: string + count: number + percentage: number + peakTime?: string // "Tuesday 2-4pm" + impact: number // Context switches caused + }> + insights: string[] + recommendations: string[] + analyzedAt: DateTime +} +``` + +### UX + +**Distraction Analytics page:** +``` +Distractions & Focus Analysis + +This week's distractions: + +📊 Distribution: +├─ 📱 Slack: 47 (42%) +├─ 📧 Email: 18 (16%) +├─ 💬 Meetings: 15 (13%) +├─ 🍽️ Hunger: 12 (11%) +└─ Other: 16 (18%) + +Timeline: +├─ Monday: 12 distractions (low) +├─ Tuesday: 28 distractions (HIGH) 🔴 +├─ Wednesday: 18 distractions +├─ Thursday: 22 distractions +└─ Friday: 10 distractions + +Patterns & Insights: +├─ "Slack is your #1 distraction. 47 interruptions this week." +├─ "Tuesday 2-4pm is your chaos window (11 Slack messages alone)" +└─ "You're most distracted right after lunch (12:30-1:30pm)" + +Recommendations: +├─ [Mute Slack 9-11am] +├─ [Schedule lunch earlier (12:00pm)] +├─ [Block Tuesday 2-4pm as focus time] +├─ [Turn on 'do not disturb' for deep work] + +Experiment: +Try one recommendation for 1 week, track results. +[Start experiment] [View previous experiments] +``` + +### Integration + +**Focus time (Phase 1):** Tracks time spent, distractions are logged +**Energy heatmap (Phase 2):** Correlate distractions with low-energy times +**Focus protection:** Suggest blocking distraction sources during peak hours + +### Success Criteria + +- Users identify top 3 distraction sources +- Distraction frequency reduced 30% after applying recommendations +- Users report better focus quality + +### Technical Notes + +- Logging: Can be manual ("I got Slack-interrupted") or auto-detected (window focus change) +- Pattern analysis: Weekly aggregation + trend detection +- Experiments: Track before/after for recommendation effectiveness + +--- + +## Phase 3 Timeline + +### Week 1: Handoff & Escalation +- [ ] Handoff document compilation & templating +- [ ] Auto-escalation detection algorithm +- [ ] UI for handoff workflow +- [ ] Risk notification system + +### Week 2: Gamification System +- [ ] Micro-celebration logic & UI +- [ ] Badge unlock system +- [ ] Progress tracking +- [ ] Badge sharing/social + +### Week 3: Reviews & Distraction +- [ ] Weekly review generation +- [ ] Distraction tracking & logging +- [ ] Pattern analysis algorithm +- [ ] Analytics dashboards + +### Week 4: Polish & Integration +- [ ] Cross-feature testing +- [ ] Performance optimization +- [ ] User onboarding for Phase 3 +- [ ] Documentation + +--- + +## Phase 3 Success Metrics + +- Async team handoff time: 2 hours → 20 minutes +- Deadline surprises: 0 (all risks escalated with time to respond) +- ADHD motivation: Users report 2x+ motivation to complete tasks +- Distraction frequency: Reduced 30% after applying recommendations +- Users understand their personal productivity patterns + +--- + +## Future Expansion (Post-Phase 3) + +### Phase 4: Team Collaboration +- Shared decision logs +- Team communication feeds +- Collective productivity insights +- Workload balancing across team + +### Phase 5: AI Coaching +- ML-powered task breakdown (large tasks → microtasks) +- Predictive deadline risks +- Personalized daily recommendations +- Habit pattern detection & suggestions + +### Phase 6: Integrations +- Jira/Linear API deep integration +- Slack bot integration +- Calendar integration (Outlook, Google Calendar) +- Time tracking (Toggl, Clockify) + +--- + +## Final Notes + +This 3-phase roadmap transforms the GenesisTools dashboard into a comprehensive personal assistant for knowledge workers: + +- **Phase 1:** Foundation (task management + context + deadline clarity) +- **Phase 2:** Intelligence (work visibility + pattern detection) +- **Phase 3:** Automation + Motivation (async support + behavioral change) + +Each phase is independently valuable, can be launched separately, and builds on previous work. + +**North star:** Users feel in control of their work, not controlled by it. diff --git a/.claude/ideas/dashboard/001-sleep-recovery-dashboard.md b/.claude/ideas/dashboard/001-sleep-recovery-dashboard.md new file mode 100644 index 000000000..571367e70 --- /dev/null +++ b/.claude/ideas/dashboard/001-sleep-recovery-dashboard.md @@ -0,0 +1,160 @@ +# 001 - Sleep & Recovery Dashboard + +## Overview +A comprehensive sleep tracking and recovery analytics system that logs sleep sessions, analyzes patterns, and correlates sleep quality with energy, mood, and performance metrics. Integrates seamlessly with the existing Timer to record sleep durations and provides data-driven insights about optimal sleep windows and recovery needs. + +## Purpose & Goals +- Enable users to understand their sleep patterns and how sleep impacts daily performance +- Identify optimal sleep duration and timing for individual users +- Detect correlation between sleep and other tracked metrics (mood, energy, productivity) +- Provide actionable insights: "You perform best after 7+ hours" or "Weekend sleep debt affects Monday mood" +- Help users establish consistent sleep routines through pattern recognition + +## Key User Flows + +### 1. Logging Sleep Session +- User goes to sleep, starts Timer with "Sleep" mode +- Timer records duration automatically +- Upon waking, user logs quality rating (1-5 scale or emoji) + optional notes ("Woke up 3x", "Vivid dreams") +- System stores: date, start time, end time, duration, quality rating, notes +- Optional: manually input historical sleep data + +### 2. Viewing Sleep Analytics +- Weekly/monthly sleep dashboard showing: + - Sleep duration trend line (avg hours per night) + - Quality distribution (pie chart of 1-5 ratings) + - Sleep schedule heatmap (when you typically sleep) + - Calendar view with sleep dots color-coded by quality +- Insights panel showing patterns detected + +### 3. Correlation Analysis +- Cross-tab with mood tracker: "Days after 6-hour sleep, mood is 2.1/5 lower" +- Cross-tab with energy: "You report highest energy after 7-8 hour sleeps" +- Cross-tab with productivity: "Focus time is 40% longer after quality sleep" +- Suggests causation: "Try aiming for 7.5 hours tonight to improve tomorrow's mood" + +### 4. Sleep Goals +- Set target sleep duration (e.g., "7 hours per night") +- Goal progress bar showing weekly average vs. target +- "You've hit your sleep goal 4/7 nights this week" +- Alerts for sleep debt: "You're 3 hours short this week" + +## Data Model + +```typescript +interface SleepSession { + id: string + userId: string + date: Date // Date of sleep (night it was) + startTime: DateTime // When fell asleep + endTime: DateTime // When woke up + duration: number // In minutes + quality: 1 | 2 | 3 | 4 | 5 // Quality rating + notes?: string // "Woke up 3x", "Took melatonin", etc. + sleepStages?: { + // Optional: if integrating with device data later + light: number + deep: number + rem: number + } + tags?: string[] // ["late-night", "stressful-day", "exercise"] + createdAt: DateTime + updatedAt: DateTime +} + +interface SleepGoal { + id: string + userId: string + targetHours: number // e.g., 7.5 + createdAt: DateTime +} +``` + +## UI Components + +### Sleep Log Card +- Date selector (calendar or date picker) +- Duration input (uses Timer data if available) +- Quality slider (1-5 emoji or numeric) +- Notes textarea +- Save button + +### Sleep Dashboard Page +- Header: "Sleep & Recovery" with quick stats (avg this week, last night quality) +- Tabs: Overview | Analytics | Goals | Insights +- Overview tab: + - Large trend line chart (7-day rolling average) + - Sleep schedule heatmap (24-hour view showing when user typically sleeps) + - Last 7 nights calendar with quality indicators +- Analytics tab: + - Quality distribution pie chart + - Duration histogram (how many nights at 6h, 7h, 8h, etc.) + - Best/worst sleep nights highlighted +- Goals tab: + - Current goal display with weekly progress bar + - Goal history (past goals set) + - Suggestion engine: "Based on your data, 7.5 hours gives best mood next day" + +### Insights Panel +- "This week, 3/7 nights above target" +- "Quality improved 15% since goal was set" +- "Your ideal sleep time: 7:00 PM - 6:00 AM" +- "Monday mornings: 20% lower mood after weekend sleep debt" + +## Integration Points + +**Timer Integration:** +- Timer has "Sleep" mode that auto-records to sleep tracker +- After timer stops, prompts for quality rating +- Seamless workflow: Timer → Sleep Quality → Auto-logged + +**Mood Tracker Integration:** +- Can view mood graph overlaid on sleep graph +- Shows "Correlation: High sleep quality → High mood next day" +- Recommendation: "Aim for quality sleep tonight to improve mood tomorrow" + +**Activity Log Integration:** +- Sleep sessions appear in activity timeline +- Can correlate previous day's activities with that night's sleep +- "Heavy exercise yesterday → Deeper sleep, better quality" + +**Dashboard Home Integration:** +- Sleep widget on main dashboard: "Last night: 6.5h, Quality: 4/5" +- Weekly sleep goal progress ring +- "1 more hour this week to hit your goal" + +## Success Criteria + +- Users can log sleep in <30 seconds (quick quality rating) +- System identifies 2-3 actionable patterns within 2 weeks of data +- Insights correlate sleep with other metrics correctly +- Weekly sleep trend clearly visible +- Users can set and track sleep goals effectively + +## Technical Considerations + +- LocalStorage for session data (user preference for privacy) +- Indexed DB for larger datasets (months of sleep data) +- Correlation calculations should be debounced (weekly updates) +- Sleep schedule heatmap requires date math and visualization library (chart.js or recharts) +- Quality insights require statistical analysis of trends + +## Error Handling + +- Invalid dates handled gracefully +- Future sleep dates prevented +- Duplicate entries on same night: allow override with confirmation +- Missing quality ratings: allow logging duration alone, quality optional +- Timezone awareness for accurate date boundaries + +## Related Features + +- This feeds into Mood & Energy Tracker for correlation +- Integrates with Health Dashboard concept +- Could connect to Accountability Network (shared sleep goals with partners) + +## Open Questions + +1. Should we collect sleep stages (light/deep/REM) data from wearables later? +2. Should there be sleep debt tracking across multiple weeks? +3. How granular should correlation insights be? diff --git a/.claude/ideas/dashboard/002-nutrition-hydration-logger.md b/.claude/ideas/dashboard/002-nutrition-hydration-logger.md new file mode 100644 index 000000000..755a140ba --- /dev/null +++ b/.claude/ideas/dashboard/002-nutrition-hydration-logger.md @@ -0,0 +1,198 @@ +# 002 - Nutrition & Hydration Logger + +## Overview +An event-based nutrition and hydration tracking system that logs meals, snacks, and drinks throughout the day. Provides nutritional analytics, pattern detection, and correlations with sleep quality, energy levels, and mood. Emphasizes quick logging without strict calorie counting, focused on behavioral patterns and health insights. + +## Purpose & Goals +- Track eating and drinking patterns without friction or strict dietary restrictions +- Identify behavioral patterns: breakfast frequency, caffeine timing, hydration levels +- Detect correlations: "Caffeine after 2pm ruins your sleep" or "Skipping breakfast 3x/week but perform better when you eat early" +- Provide nutritional awareness through visualization and insights +- Support health goals through data-driven recommendations + +## Key User Flows + +### 1. Quick Food/Drink Logging +- User sees floating action button or quick-add from any page +- Minimal entry: Photo or name of food + optional notes +- Optional: Add nutritional data (calories, macros) if user wants to track +- Auto-complete for common items (coffee, water, lunch, etc.) +- Timestamp auto-set to current time +- Confirm with 1-2 taps + +### 2. Viewing Nutrition Dashboard +- Daily view: timeline of all meals/drinks today +- Weekly view: which days did you skip breakfast? How much water? +- Monthly view: trends in meal frequency, eating windows +- Heatmap: when do you typically eat? (breakfast at 7am vs 9am patterns) +- Category breakdown: how many meals, snacks, drinks per day? + +### 3. Detailed Nutrition Insights +- "You skip breakfast 3x/week" +- "Average caffeine consumed: 2 cups/day at 8am and 2pm" +- "Typical eating window: 7am-9pm" +- "You eat dinner latest on weekends (9:30pm average)" +- "On days you drink <1L water, energy drops 20%" + +### 4. Correlation Analysis +- "Caffeine after 2pm correlates with 1.5-hour longer sleep latency" +- "High protein breakfast days: 40% more focus in morning" +- "Skipped lunch days: mood drops 15% in afternoon" +- Suggests experiments: "Try eating breakfast tomorrow to see if mood improves" + +### 5. Nutritional Tracking (Optional) +- Users can optionally log calories/macros +- Daily target vs. actual (pie chart) +- Macro breakdown (protein/carbs/fat percentages) +- Not required—food photography and name logging works without nutrition data + +## Data Model + +```typescript +interface MealLog { + id: string + userId: string + dateTime: DateTime + mealType: "breakfast" | "lunch" | "dinner" | "snack" | "drink" + name: string // "Coffee", "Chicken sandwich", "Water" + quantity?: string // "2 cups", "1 plate", etc. + notes?: string // "Black coffee no sugar", "Felt hungry after" + + // Optional nutrition data + nutrition?: { + calories?: number + protein?: number // grams + carbs?: number // grams + fat?: number // grams + fiber?: number // grams + caffeine?: number // mg (for drinks) + } + + // Optional + photo?: string // image URL + moodBefore?: number // 1-5 scale + energyBefore?: number // 1-5 scale + + tags?: string[] // "organic", "homemade", "restaurant" + createdAt: DateTime + updatedAt: DateTime +} + +interface NutritionGoal { + id: string + userId: string + goalType: "calorie" | "protein" | "water" | "meals-per-day" + targetValue: number + createdAt: DateTime +} +``` + +## UI Components + +### Quick Log Card +- Floating action button with "+" icon +- Modal/sheet that opens with minimal fields: + - Meal type selector (breakfast/lunch/dinner/snack/drink) + - Food name input with autocomplete + - Optional quantity field + - Optional notes + - Optional nutrition data (collapsible section) + - Submit button +- Takes <15 seconds to log basic entry + +### Nutrition Dashboard Page +- Tabs: Daily | Weekly | Monthly | Insights | Goals +- Daily tab: + - Time-ordered list of today's meals/drinks + - Quick stats: Total meals (3), Total drinks (5), Estimated calories (if tracked) + - Quick add button always visible + - Timeline view with meal types color-coded (breakfast=orange, lunch=green, etc.) +- Weekly tab: + - 7-day calendar showing meal patterns + - Heatmap of eating windows (when do meals typically occur?) + - Days with/without breakfast highlighted + - Meals per day comparison +- Monthly tab: + - 30-day heatmap showing frequency + - Trend lines for meal frequency, drinking patterns + - Best/worst eating weeks highlighted +- Insights tab: + - Pattern cards: "You skip breakfast 3x/week" + - Correlation cards: "Caffeine after 2pm affects sleep" + - Suggestions: "Try eating within 1 hour of waking for energy boost" +- Goals tab: + - Current goals with progress (if user tracks calories/macros) + - Water intake tracker (simple: 8 glasses/day target) + - Meal frequency goal: "Aim for 3 meals + 1 snack daily" + +### Nutrition Stats Widget +- Daily: meal count, total calories (optional), caffeine total +- Weekly: average meals/day, most common meal times +- Monthly: trends, patterns, correlations + +## Integration Points + +**Sleep Tracker Integration:** +- Show "Caffeine timeline vs. Sleep quality" graph +- Alert: "You logged caffeine at 4pm. Last 3 times you did this, sleep quality was lower" +- Recommendation: "Avoid caffeine after 2pm to improve sleep" + +**Mood & Energy Tracker Integration:** +- Overlay nutrition timeline with mood/energy dips +- "On days you skip breakfast, afternoon mood is 2 points lower" +- Suggest correlation experiments + +**Activity Log Integration:** +- Show meals in timeline alongside other activities +- "Heavy workout → Ate larger lunch → Energy stayed high all afternoon" + +**Accountability Network Integration:** +- Share nutrition goals with accountability partner +- "We both committed to drinking 2L water daily" +- Shared progress tracking + +## Success Criteria + +- Quick logging: <20 seconds for typical entry +- System identifies 2-3 eating patterns within 1 week of data +- Correlations between nutrition and mood/sleep are detectable after 2 weeks +- Users understand their typical eating windows and meal frequency +- Optional nutrition tracking doesn't interfere with basic event logging + +## Technical Considerations + +- Auto-complete database of common foods +- Fast search for meal logging +- Photo analysis optional (if adding image recognition later) +- Correlation calculations similar to sleep tracking (statistical analysis) +- Heatmap visualization for eating windows (24-hour day view) +- Timezone awareness for daily boundaries + +## Error Handling + +- Invalid dates prevented +- Future dates not allowed (but allow backdating for accuracy) +- Auto-complete prevents typos +- Nutrition fields optional (user can ignore them) +- Duplicate entries on same day: allowed (multiple meals expected) + +## Privacy Considerations + +- Photos stored locally or with user consent only +- Nutrition data never shared unless explicitly enabled in goals +- No AI-based analysis of meals without explicit opt-in +- All data owned by user, exportable + +## Related Features + +- Feeds into Health Dashboard (sleep + nutrition + energy overview) +- Correlates with Mood & Energy Tracker +- Could integrate with Portfolio/Skills (nutrition for athletes/performers) +- Supports Accountability Network (shared nutrition goals) + +## Open Questions + +1. Should we integrate with food databases (USDA, MyFitnessPal) for auto-nutrition data? +2. How granular should portion tracking be? +3. Should we allow barcode scanning for packaged foods? +4. How to handle eating at restaurants without full nutrition info? diff --git a/.claude/ideas/dashboard/003-mood-energy-tracker.md b/.claude/ideas/dashboard/003-mood-energy-tracker.md new file mode 100644 index 000000000..b4199f854 --- /dev/null +++ b/.claude/ideas/dashboard/003-mood-energy-tracker.md @@ -0,0 +1,227 @@ +# 003 - Mood & Energy Tracker + +## Overview +A lightweight mood and energy check-in system that allows users to quickly log their emotional state and energy levels throughout the day. Provides pattern recognition, identifies optimal times of day, detects mood/energy triggers, and correlates with other tracked data (sleep, nutrition, activity). Emphasizes quick, frequent check-ins without friction. + +## Purpose & Goals +- Establish awareness of mood and energy patterns throughout the day +- Identify optimal times for different types of work (creative, analytical, social) +- Detect triggers: "Social time energizes you" or "Afternoon slumps are consistent" +- Correlate mood/energy with other health metrics +- Support mental health through pattern visibility and exportable data for therapists/coaches +- Enable accountability partners to share emotional check-ins + +## Key User Flows + +### 1. Quick Mood/Energy Check-In +- User taps check-in button (can be from any page via floating action) +- Quick entry modal appears: + - Mood scale: 5-point emoji scale (😢 to 😄) or 1-10 numeric + - Energy scale: 5-point scale (🔋 depleted to 🔋🔋🔋 energized) + - Optional note: What's affecting this? ("Hungry", "Slept well", "Social time") + - Optional context tags: location, activity, social setting +- Submit in 20 seconds +- Gentle reminder notifications (3x daily at configurable times) + +### 2. Daily Mood/Energy Timeline +- View all check-ins for today as timeline +- Graph showing mood and energy curves throughout day +- Each check-in shows timestamp, score, optional note +- Patterns visible: mood dipped at 3pm both days, energy rose after lunch + +### 3. Weekly Patterns Dashboard +- 7-day grid showing mood and energy for each time checked in +- Heatmap: which times of day are you most energized? Mood peaks? +- Average mood/energy by hour of day +- "You check in at: 7am (avg mood: 3.2), 12pm (avg mood: 4.1), 5pm (avg mood: 3.8)" +- Best/worst mood times highlighted + +### 4. Mood/Energy Insights +- "Your mornings are best: avg mood 4.2/5 before noon" +- "Afternoon slump detected: 2-4pm mood averages 2.8/5" +- "Social interactions energize you: +1.5 energy after social events" +- "You're most creative on high-energy mornings" +- "Monday mornings: 30% lower mood than other days" +- Correlation with sleep: "After 6-hour sleep nights, mood is 1.2 points lower" + +### 5. Mood History & Export +- 30/90 day mood overview (see trends over weeks) +- Exportable mood data for therapists or personal tracking +- Annotation support: "Started new medication", "Big project deadline" +- Mood trend line: improving, declining, stable? + +## Data Model + +```typescript +interface MoodEnergyCheckIn { + id: string + userId: string + dateTime: DateTime + mood: 1 | 2 | 3 | 4 | 5 // Or 1-10 if using numeric + energy: 1 | 2 | 3 | 4 | 5 // Or 1-10 + notes?: string // "Slept well", "Hungry", "Social time was great" + + context?: { + location?: string // "home", "office", "gym", "coffee shop" + activity?: string // "working", "exercising", "socializing", "resting" + socialSetting?: string // "alone", "with partner", "with friends", "group" + triggers?: string[] // Tags for what influenced mood + } + + // For shared check-ins + sharedWith?: string[] // userId array if shared with accountability partners + + createdAt: DateTime + updatedAt: DateTime +} + +interface MoodGoal { + id: string + userId: string + targetMood: number // Aim for average mood of 3.5+ per day + createdAt: DateTime +} + +interface MoodExport { + userId: string + startDate: Date + endDate: Date + checkIns: MoodEnergyCheckIn[] + summary: { + averageMood: number + averageEnergy: number + moodTrend: "improving" | "declining" | "stable" + bestTime: string // "7am-9am" + worstTime: string // "2pm-4pm" + } +} +``` + +## UI Components + +### Quick Check-In Card +- Floating action button with emoji or heart icon +- Modal that slides up with: + - Mood scale with visual emojis (😢 😞 😐 🙂 😄) + - Energy scale with battery icons (🔴 🟡 🟢 🔋 🔋🔋) + - Optional text input: "What's affecting this?" + - Optional context selector (dropdown or tags) + - Submit button +- Can be dismissed quickly without logging (optional reminder later) + +### Mood Dashboard Page +- Tabs: Daily | Weekly | Monthly | Patterns | Export +- Daily tab: + - Large mood/energy gauges showing current state + - Timeline of all check-ins today + - Each check-in shows score and note + - Quick add button for next check-in + - Estimated best time for focus work based on today's pattern +- Weekly tab: + - 7-day grid with mood/energy scores + - Heatmap colors (red=low mood, green=high mood) + - Time-of-day patterns: which hours have best mood? + - Average scores by time slot + - Mood/energy curves overlaid as line graphs +- Monthly tab: + - 30-day calendar heatmap (green days vs red days) + - Trend line showing if improving/declining + - Week-over-week comparison + - Best/worst weeks +- Patterns tab: + - "Your best times": 7-9am, 10am-12pm (mood 4.1, energy 4.3) + - "Your tough times": 2-4pm (mood 2.8, energy 2.4) + - "Triggers": "Social interactions boost energy +1.5" + - "Days of week": "Mondays are 20% lower mood" + - Correlation cards with other metrics (sleep impact, exercise boost, etc.) +- Export tab: + - Date range selector + - Download as PDF, CSV, or JSON + - Summary statistics + - Mood trends over selected period + +### Mood Widget +- Dashboard home shows "Current mood: 😊 4/5 energy: 🔋🔋 4/5" +- Weekly trend mini-chart +- "Your best time today: 10am" + +### Shared Check-In Card (for Accountability Network) +- Shows partner's current mood if shared +- Both can see each other's mood trends +- Encourages: "Your partner just checked in—want to say hi?" + +## Integration Points + +**Sleep Tracker Integration:** +- Show sleep quality vs. mood/energy next day +- "After 7+ hour sleep: avg mood 4.1/5" +- "After <6 hour sleep: avg mood 2.8/5" +- Recommendation: "Better sleep → Better mood" + +**Nutrition Tracker Integration:** +- "Caffeine after 2pm correlates with lower evening mood" +- "Skipping breakfast days: afternoon mood -1.5 points" +- "High protein breakfast: morning mood +0.8 points" + +**Activity Log Integration:** +- Exercise correlation: "Exercise days: mood +0.9" +- "Rest days: mood -0.5" +- Social activity: "Days with social time: energy +1.2" + +**Accountability Network:** +- Share mood check-ins with partner +- Partner can see trends, offer support +- Shared goal: "Let's both maintain 3.5+ mood average" +- Check-in reminders from partner + +**Therapist/Coach Export:** +- Provide mood history for mental health professionals +- Helps identify patterns with professional guidance + +## Success Criteria + +- Users can check in mood/energy in <20 seconds +- System identifies 2-3 clear daily mood patterns within 1 week +- Correlations with sleep/nutrition visible after 2 weeks +- Mood trends clearly show improvement/decline over time +- Exportable data useful for therapists or personal analysis + +## Technical Considerations + +- Background notifications for reminder check-ins (configurable frequency) +- Quick check-in should not require navigation +- Mood data visualization (line graphs, heatmaps) +- Correlation calculations with statistical significance testing +- Time-of-day analysis using hour-based bucketing +- Timezone-aware timestamps + +## Error Handling + +- Missing check-ins: no penalty, just data gaps +- Future check-ins: prevent with validation +- Out of range scores: validate 1-5 or 1-10 range +- Duplicate same-minute check-ins: allow (user might be refining entry) +- Missing context: optional, don't require + +## Privacy & Sharing + +- Mood data highly private by default +- Sharing only with explicit consent +- Shared data limited (can control what partner sees) +- Export requires confirmation of intended recipient +- No AI analysis of mood without opt-in + +## Related Features + +- Central hub for all health metrics (sleep, nutrition, activity, mood) +- Correlations drive insights in other features +- Feeds Accountability Network shared goals +- Supports Relationship Calendar (check-in with people when your mood is good) + +## Open Questions + +1. Should we integrate with wearables (Apple Health, Fitbit) for heart rate/sleep data? +2. How granular should context options be? (Free text vs. preset tags) +3. Should we offer guided mood reflection prompts? +4. What's the optimal frequency for reminders? (Too many = annoying) +5. Should mood data be shareable with healthcare providers? diff --git a/.claude/ideas/dashboard/004-spending-snapshot-dashboard.md b/.claude/ideas/dashboard/004-spending-snapshot-dashboard.md new file mode 100644 index 000000000..143e9e8a8 --- /dev/null +++ b/.claude/ideas/dashboard/004-spending-snapshot-dashboard.md @@ -0,0 +1,267 @@ +# 004 - Spending Snapshot Dashboard + +## Overview +A spending awareness system that logs daily purchases without strict budgeting constraints. Emphasizes quick event-based logging and pattern discovery through visualization. Shows trends, category breakdowns, spending heatmaps by time/day, anomaly detection, and progress toward savings goals. Designed for financial awareness, not restrictive budgeting. + +## Purpose & Goals +- Track where money goes without strict budgets or guilt +- Identify spending patterns and trends over time +- Detect anomalies: "That $200 grocery run is unusual" +- Show spending distribution by category and time +- Support savings goals by showing progress, not restrictions +- Provide spending insights: "You spend 15% more on weekends" or "Coffee costs average $13, 3x/week" +- Enable smarter spending decisions through visibility + +## Key User Flows + +### 1. Quick Spending Log +- User sees floating action or quick-add from any page +- Minimal entry: Amount + description + - Dollar amount field (auto-focus) + - Short description ("$12 coffee", "$45 groceries", "$8 lunch") + - Auto-detect category from description (ML-optional) + - Timestamp auto-set + - Optional receipt photo + - Optional notes ("Organic salad", "Splurge", "Bulk buy") +- Submit in 10-15 seconds +- Optional: recurring expenses (weekly groceries, monthly subscription) + +### 2. Daily Spending View +- Today's total spending prominently displayed +- Timeline of all purchases today with times +- Category breakdown as pie chart +- Average spend per day this week +- "You've spent $47 today vs. $52 daily average" + +### 3. Weekly Spending Dashboard +- 7-day spending trend (bar chart) +- Weekly total vs. previous weeks +- Category breakdown with spending per category +- Days sorted by spending (highest to lowest) +- "This week: $384 (avg $55/day) vs. last week: $418" + +### 4. Monthly Spending Analytics +- Monthly total spending over multiple months (trend line) +- Category breakdown with percentages (housing, food, entertainment, etc.) +- Spending by day of week (Mon-Sun comparison) +- Spending by time of day heatmap (when do you spend most?) +- Best/worst spending days highlighted +- "You spend 15% more on weekends" + +### 5. Anomaly Detection & Insights +- "That $200 grocery run is unusual (normal: $45-60)" +- "Coffee spending: avg $13 per visit, 3x/week = ~$156/month" +- "Friday nights: 40% higher spending than weekday evenings" +- "You spent more this week than the last 4 weeks" +- "Restaurant category up 25% this month" + +### 6. Savings Goals +- Set goal: "Save $500 this month for vacation" +- Track spending vs. savings target +- "You've spent $380. Budget remaining: $120 for 10 days" +- Goal progress ring showing progress toward savings target +- Multi-goal support (vacation, emergency fund, investment) + +### 7. Recurring/Subscription Tracking +- Add recurring expenses (monthly rent, weekly groceries) +- Auto-populate as "expected spending" +- Track: "Netflix: $15/mo, Gym: $50/mo, Groceries: ~$200/mo" +- Notification when recurring expense comes due +- Spot new subscriptions that appeared without manual addition + +## Data Model + +```typescript +interface SpendingLog { + id: string + userId: string + dateTime: DateTime + amount: number // in dollars + description: string // "Coffee", "Groceries", "Gas" + category: SpendingCategory + notes?: string // Optional details + receiptPhoto?: string // Optional receipt image URL + isRecurring?: boolean + tags?: string[] // "splurge", "necessity", "gift" + createdAt: DateTime + updatedAt: DateTime +} + +type SpendingCategory = + | "food" + | "groceries" + | "entertainment" + | "transportation" + | "subscriptions" + | "shopping" + | "utilities" + | "other" + +interface SavingsGoal { + id: string + userId: string + name: string // "Vacation fund" + targetAmount: number + currentAmount: number // Money saved toward goal + deadline?: DateTime + category?: SpendingCategory // Track spending in specific category toward goal + createdAt: DateTime +} + +interface RecurringExpense { + id: string + userId: string + description: string + amount: number + frequency: "daily" | "weekly" | "monthly" | "yearly" + nextDueDate: DateTime + category: SpendingCategory + createdAt: DateTime +} + +interface SpendingInsight { + type: "anomaly" | "pattern" | "trend" + message: string // "That $200 is unusual for groceries" + severity: "low" | "medium" | "high" + date: DateTime +} +``` + +## UI Components + +### Quick Spending Card +- Floating action button with dollar sign or receipt icon +- Modal with minimal fields: + - Large dollar amount input (auto-focus) + - Description field with autocomplete + - Category selector (optional, auto-detects from description) + - Notes textarea (optional) + - Receipt photo button (optional) + - Submit button +- Keyboard opens automatically for quick number entry +- Submit closes modal immediately + +### Spending Dashboard Page +- Tabs: Daily | Weekly | Monthly | Goals | Recurring | Insights +- Daily tab: + - Large display of "Today's spending: $47" + - Small sparkline showing last 7 days + - Timeline list of all purchases today with times + - Category pie chart for today + - Quick add button + - "Daily average this week: $52" +- Weekly tab: + - Bar chart: 7 days with amounts + - Weekly total prominently displayed + - Category breakdown as horizontal bar chart + - "This week vs. last week: +$32 (+8%)" + - Best/worst days highlighted +- Monthly tab: + - Line chart: spending over last 6 months + - Category pie chart for current month + - Spending by day of week (heatmap or bar chart) + - Time of day heatmap (when do you spend most?) + - "This month on track" or "30% over last month" +- Goals tab: + - List of active savings goals + - Each goal shows progress ring with % complete + - "Vacation: $420/$500 (84%) by July 15" + - Time remaining and daily savings needed + - Option to add new goal + - Completed goals archive +- Recurring tab: + - List of recurring/subscription expenses + - Total monthly recurring: $XXX + - Next due dates highlighted + - "Netflix: $15/mo, Gym: $50/mo, Groceries: ~$200/mo" + - Alert for new subscriptions detected +- Insights tab: + - Anomaly cards: "That $200 grocery is unusual" + - Pattern cards: "You spend 15% more weekends" + - Trend cards: "Coffee cost rising (avg $12 → $14/month)" + - Actionable suggestions: "Consider bulk grocery shopping" + +### Spending Widget +- Dashboard home shows "This month: $1,247" with trend indicator +- Quick add button +- Current goals progress + +## Integration Points + +**Accountability Network:** +- Share spending goals with accountability partner +- "We both committed to saving $500 for trip" +- Partner can see progress (motivational) +- Shared budget challenges: "Save $100 this week together" + +**Savings Goals Integration:** +- Set savings target and track progress +- System shows: "You need to spend $X less to hit goal" +- Positive framing: "You're on track" vs. "You overspent" + +**Activity Log Integration:** +- Purchases appear in activity timeline +- "Spent $47 on lunch at restaurant" + "Timed 30-min focus session" +- Correlations: "Lunch time: when you take breaks" + +**Calendar Integration (Relationship Calendar):** +- Track spending for events/dates +- "Birthday gifts", "Anniversary dinner" +- Remember spending patterns around important dates + +## Success Criteria + +- Users can log spending in <15 seconds +- System identifies 2-3 spending patterns within 1 week +- Anomalies detected correctly (outliers flagged) +- Savings goals track progress intuitively +- No guilt-based language; positive framing only +- Insights are actionable and accurate + +## Technical Considerations + +- Fast category detection using keyword matching +- Anomaly detection: statistical analysis of category averages +- Heatmap visualization (spending by time/day) +- Recurring expense scheduler (cron-like) +- Timezone-aware timestamps +- LocalStorage for quick access to recent spending +- Optional: receipt OCR for amount extraction + +## Error Handling + +- Invalid amounts prevented (negative/non-numeric) +- Future dates prevented +- Duplicate entries on same second: allowed (multiple purchases possible) +- Missing category: auto-assign "Other" with suggestion +- Orphaned goals: warn if deleting goal with progress +- Subscription detection: confirm before auto-adding + +## Privacy Considerations + +- All spending data private by default +- Goal sharing optional (amount visible, not itemized purchases) +- No integration with banks (manual entry only) +- No advertisement based on spending habits +- Exportable data for user's tax/finance tracking + +## Privacy/Security Notes + +- If receipt photos stored, encrypted and accessible only to user +- No cloud sync without explicit opt-in +- Data ownership remains with user + +## Related Features + +- Integrates with Accountability Network (shared goals) +- Part of larger Financial Dashboard (investments, debt, savings) +- Could feed into Portfolio (track freelance income vs. spending) +- Supports financial goal-setting in Accountability Network + +## Open Questions + +1. Should we integrate with bank APIs for automatic transaction import? +2. How should we handle credit card categories vs. cash purchases? +3. Should we offer budgeting recommendations based on patterns? +4. How granular should categories be? (Current: 8 broad categories) +5. Should we support multiple currencies for travelers? diff --git a/.claude/ideas/dashboard/005-accountability-network.md b/.claude/ideas/dashboard/005-accountability-network.md new file mode 100644 index 000000000..1d052a0dd --- /dev/null +++ b/.claude/ideas/dashboard/005-accountability-network.md @@ -0,0 +1,283 @@ +# 005 - Accountability Network + +## Overview +A collaborative goal-tracking system that enables users to share goals with friends and accountability partners. Provides shared progress visibility, check-in messaging, milestone celebrations, and cross-goal insights. This is the connective tissue that links Health, Finance, Career, and Creative goals across multiple users in a supportive community. + +## Purpose & Goals +- Create accountability partnerships for shared commitments +- Enable transparent progress tracking without judgment +- Foster supportive community around personal growth +- Allow flexible goal types: fitness, savings, creative, career, health +- Celebrate milestones and achievements together +- Automate progress syncing from other dashboard features (sleep goals, savings goals, etc.) + +## Key User Flows + +### 1. Create & Share Goal +- User creates goal: "Run 20 miles this week" or "Save $500 for vacation" +- Selects goal type (fitness, savings, creative, career, health, custom) +- Adds target and deadline +- Invites accountability partner (by email or username) +- Partner receives invitation and accepts/declines +- Both see real-time progress once partner accepts + +### 2. Auto-Sync from Other Features +- Savings goal created in Spending Tracker automatically appears in Accountability Network +- Sleep goal from Sleep Tracker shared with partner +- Creative output goals from Creative Metrics synced +- Skill goals from Skill Leveling synced +- Partner sees progress without user manually updating + +### 3. Check-In & Messaging +- Partner sends check-in message: "How's the project going?" +- User replies with progress update +- Messages visible only to partners on that goal +- Ability to set check-in frequency (daily, weekly, etc.) +- Optional: video/voice message support + +### 4. Progress Dashboard +- View all shared goals and partners +- See partner's current progress on each goal +- Timeline of goal achievements and milestones +- Partner goals and your progress on them (if shared) +- Celebration notifications when milestones hit + +### 5. Goal Challenges +- Create 2-week or monthly challenges with friends +- "Let's all exercise 3x/week for the next month" +- Group leaderboard showing who's leading +- Friendly competition with praise, not criticism +- Group chat for encouragement + +### 6. Milestone Celebrations +- Automatic celebration when goals hit 25%, 50%, 75%, 100% +- Confetti animations, achievement badges +- Ability to share milestone with other friends +- "I just saved $500 for my vacation!" - Share button +- Monthly achievements digest email + +## Data Model + +```typescript +interface SharedGoal { + id: string + ownerId: string // User who created goal + partnerId: string // Partner user + goalType: "fitness" | "savings" | "creative" | "career" | "health" | "custom" + title: string // "Run 20 miles this week" + description?: string + targetValue: number // Miles, dollars, count, etc. + currentValue: number // Auto-synced from other features when possible + unit: string // "miles", "dollars", "pages written" + deadline: DateTime + status: "active" | "completed" | "failed" | "abandoned" + sourceFeature?: string // "sleep_tracker", "spending_tracker", etc. + + createdAt: DateTime + completedAt?: DateTime +} + +interface GoalCheckIn { + id: string + goalId: string + fromUserId: string // Who sent this check-in + message: string + progress?: number // Optional updated progress + confidence?: 1 | 2 | 3 | 4 | 5 // How confident are they in achieving goal + createdAt: DateTime +} + +interface GoalChallenge { + id: string + creatorId: string + title: string // "Exercise 3x/week Challenge" + description: string + durationDays: number // 14 or 30 days + metric: string // "exercise_sessions", "words_written", etc. + targetPerPerson: number // Each person needs 3 sessions + participants: string[] // Array of userIds + leaderboard: { + userId: string + currentValue: number + rank: number + }[] + status: "active" | "completed" + createdAt: DateTime + endsAt: DateTime +} + +interface AccountabilityPartnership { + id: string + users: [string, string] // Pair of userIds + goals: string[] // Array of goalIds they share + totalGoalsCompleted: number + totalCheckIns: number + isActive: boolean + createdAt: DateTime +} +``` + +## UI Components + +### Goal Creation Modal +- Minimal form to create shared goal +- Fields: + - Goal title and description + - Goal type selector (dropdown) + - Target value and unit + - Deadline (date picker) + - Partner selector (autocomplete from contacts) + - Auto-sync option (if syncing from another feature) + - Create button + +### Accountability Dashboard Page +- Tabs: My Goals | Partnerships | Challenges | Milestones +- My Goals tab: + - List of all shared goals + - Each goal shows: + - Title, deadline, and progress bar + - Current value vs. target ("47/50 miles") + - Partner name and avatar + - Latest check-in message + - "Check in" button + - Grouped by status (active, completed, in-progress) +- Partnerships tab: + - List of accountability partners + - Each shows: + - Partner name/avatar + - Number of shared goals + - Total milestones hit together + - Total check-ins + - "View all goals" button + - "Send message" button + - Action to invite new partner +- Challenges tab: + - Active challenges user is in + - Leaderboard showing current standings + - User's position and progress + - Remaining time + - Group chat for challenge + - Option to create new challenge +- Milestones tab: + - Recent goal completions (yours and partners') + - Celebration cards with confetti animation + - Shareable milestone (can share with other friends) + - Archive of past achievements + +### Goal Check-In Modal +- Simple message composer +- Optional confidence slider (1-5) +- Optional progress update input +- Send button +- Shows conversation history with partner below + +### Shared Goal Card +- Goal title and partner name +- Large progress bar with percentage +- Current value / Target value +- Days remaining +- Latest message preview +- Quick action buttons: Check-in, Message, View details + +### Milestone Celebration +- Full-screen celebration modal when goal hits milestone +- Confetti animation +- Achievement badge +- "Share this milestone" button +- Partner notification: "Your partner hit 50%! 🎉" + +### Leaderboard (for Challenges) +- Ranked list of challenge participants +- Current value per person +- Leader highlighted with medal 🥇 +- Green arrows showing who moved up since yesterday +- Bottom shows: "You're 3rd place, 5 miles behind the leader!" + +## Integration Points + +**Sleep Tracker:** +- Sleep goal syncs automatically to Accountability Network +- Partner sees your sleep progress weekly +- Check-in: "How'd you sleep? On track for your goal?" + +**Spending Tracker:** +- Savings goals automatically appear in shared goals +- Partner sees progress: "Saved $420/$500" +- Group challenge: "Save $100 together this week" + +**Mood Tracker:** +- Optional: Share mood check-in frequency goal with partner +- "Let's both do daily mood check-ins for a month" +- See partner's mood trends (if they share) + +**Creative Metrics:** +- Creative output goals synced +- "We both committed to writing 10k words this month" +- Leaderboard: who's hitting targets faster? + +**Skill Leveling System:** +- Share skill development goals +- "Let's both reach Intermediate in Python" +- Partner sees your progress + +**Relationship Calendar:** +- Accountability partner appears on calendar +- Auto-sync check-in dates +- Celebration reminders for partner achievements + +## Success Criteria + +- Goal creation: <1 minute including partner invitation +- Progress auto-syncs from other features seamlessly +- Check-in process is lightweight and encouraging +- Milestones feel celebratory, not pressuring +- Partnerships motivate without creating stress +- Users see partner progress in near real-time + +## Technical Considerations + +- Real-time progress updates (WebSocket or polling) +- Notification system for check-in requests and milestones +- Leaderboard ranking calculations (efficient sorting) +- Auto-sync from other features via shared user ID +- Messaging system with optional encryption +- Activity feed for partnership activity + +## Error Handling + +- Partner invitation already exists: warn user +- Partner declines invitation: graceful notification +- Goal achieved but partner absent: still celebrate +- Partner data unavailable (offline): show last-known value +- Invalid progress values: sanitize and warn user + +## Privacy Considerations + +- Only shared goal data visible to partner (other data private) +- Shared data limited to goal progress only +- Can unshare goal at any time +- Partner cannot see raw data unless explicitly shared +- Achievements can be kept private or shared publicly +- All partnerships start with explicit acceptance + +## Feedback & Encouragement System + +- Messages are supportive, never judgmental +- UI emphasizes "you're doing great" not "you're behind" +- Leaderboard shows progress, not failure +- Failed goals archived but not highlighted negatively +- Celebrate effort, not just results + +## Related Features + +- Connective feature linking Sleep, Nutrition, Mood, Spending, Creative, Skills +- Each feature can create/sync goals to Accountability Network +- Enables cross-feature insights: "Social time + sleep → Better mood next day" + +## Open Questions + +1. Should partners have asymmetric access (one sees all, one private)? +2. How to handle goal failure gracefully? +3. Should we gamify with badges/achievements? +4. Video/voice message support or text-only initially? +5. Public vs. private challenge leaderboards? diff --git a/.claude/ideas/dashboard/006-portfolio-showcase.md b/.claude/ideas/dashboard/006-portfolio-showcase.md new file mode 100644 index 000000000..782fa00d8 --- /dev/null +++ b/.claude/ideas/dashboard/006-portfolio-showcase.md @@ -0,0 +1,355 @@ +# 006 - Portfolio & Showcase + +## Overview +A professional portfolio builder that enables users to showcase creative work, career achievements, and completed projects. Provides automatic portfolio page generation, portfolio statistics tracking, work gallery with filtering, timeline of accomplishments, and shareable public profile. Integrates with freelance tracking to show earned income per project. + +## Purpose & Goals +- Easily upload and organize creative work and professional achievements +- Generate professional portfolio pages automatically (no design skills needed) +- Track portfolio metrics: total projects, skills demonstrated, hours invested +- Show work evolution over time through timeline view +- Create shareable portfolio link for job applications, client pitches, or social sharing +- Connect projects to income earned (for freelancers) +- Showcase impact: users served, products shipped, downloads, etc. + +## Key User Flows + +### 1. Add Project to Portfolio +- User navigates to Portfolio section +- Clicks "Add Project" button +- Form with fields: + - Project title ("E-commerce redesign", "Mobile app launch") + - Description (optional short description) + - Project category (design, code, writing, music, video, photography, etc.) + - Cover image/gallery (multiple images) + - URL/link to live project or demo + - Tools/technologies used (tags) + - Start and end date + - Impact/stats (users, revenue, downloads, etc.) + - Skill tags demonstrated +- Auto-generates portfolio preview +- Mark as "active work" or "completed" + +### 2. Browse Portfolio Gallery +- Gallery view with thumbnails of all projects +- Filter by category (design, development, writing, etc.) +- Filter by skills demonstrated (React, Python, Figma, etc.) +- Sort by date, popularity, or impact +- Search by keyword +- Click project to see full details + +### 3. Portfolio Statistics +- Total projects: 24 +- Total hours invested: 480 hours +- Skills demonstrated: React, Node.js, Design, Python, etc. +- Impact total: "Helped 50+ clients, 100k+ users" +- Most common skill category +- Project timeline (visual history of work) + +### 4. Public Portfolio Page +- Auto-generated shareable portfolio URL: myportfolio.genesistools.com/username +- Professional landing page with: + - Intro/bio section + - Featured projects (user selects 3-5 best) + - Full gallery grid + - About section + - Stats/metrics + - Skills section (bars showing proficiency) + - Contact/social links + - Download resume button (optional) +- Beautiful, mobile-responsive design +- No coding required + +### 5. Work Timeline +- Chronological view of all completed projects +- Shows project names, dates, and brief descriptions +- Visual timeline with project cards +- Grouped by year or quarter +- Shows evolution of skills over time + +### 6. Work-in-Progress (WIP) Tracking +- Separate section for active projects +- Shows progress toward completion +- Can be hidden from public portfolio +- Track time spent on current projects +- Estimate completion date + +### 7. Skills Profile +- Visual skill matrix showing: + - Skill name + - Proficiency level (beginner/intermediate/advanced/expert) + - Times used (how many projects used this skill) + - Last used date +- Skills ranked by frequency and recent use +- Endorsed by others (if part of social network) + +## Data Model + +```typescript +interface PortfolioProject { + id: string + userId: string + title: string + description?: string + category: ProjectCategory // "design", "code", "writing", "music", "video", "photography", "other" + images: string[] // Array of image URLs + coverImage: string // Primary image + url?: string // Link to live project or demo + repositoryUrl?: string // GitHub or similar + startDate: DateTime + endDate: DateTime + hoursSpent?: number + technologies: string[] // ["React", "Node.js", "Figma"] + skills: string[] // Skills demonstrated + impact?: { + description: string // "Helped 10 clients" + metric?: string // "10 clients", "50k users", "100k downloads" + } + status: "completed" | "wip" | "archived" + isFeatured: boolean // Shown on public portfolio + incomeGenerated?: number // For freelancers + collaborators?: string[] // Other userIds + isPublic: boolean // Visible on public portfolio + createdAt: DateTime + updatedAt: DateTime +} + +type ProjectCategory = "design" | "code" | "writing" | "music" | "video" | "photography" | "other" + +interface PortfolioSkill { + id: string + userId: string + skillName: string + proficiencyLevel: "beginner" | "intermediate" | "advanced" | "expert" + timesUsed: number // In how many projects + lastUsedDate: DateTime + endorsements?: number // From network + createdAt: DateTime +} + +interface PublicPortfolioProfile { + userId: string + username: string + bio?: string + avatar?: string + socialLinks?: { + twitter?: string + linkedin?: string + github?: string + website?: string + } + featuredProjects: string[] // Array of projectIds + skills: PortfolioSkill[] + statistics: { + totalProjects: number + totalHours: number + totalIncomeGenerated?: number + dateJoined: DateTime + } +} + +interface ResumeData { + userId: string + summary?: string + experience?: Array<{ + company: string + position: string + startDate: DateTime + endDate?: DateTime + description: string + }> + education?: Array<{ + school: string + degree: string + field: string + graduationDate: DateTime + }> + projects: string[] // References projectIds + skills: string[] +} +``` + +## UI Components + +### Add Project Form +- Multi-step form or single scrolling form +- Step 1: Title, description, category +- Step 2: Images and gallery upload +- Step 3: Details (date, URL, technologies) +- Step 4: Impact and skills +- Preview updates as you fill form +- Save as draft or publish immediately + +### Portfolio Gallery Page +- Top navigation with filter tabs: + - "All Projects", "Design", "Development", "Writing", etc. +- Search bar for keyword search +- Skill filter chips (click to show projects using skill) +- Grid of project thumbnails: + - Thumbnail image + - Project title + - Technologies/skills used + - Date or completion status + - Click to view full details +- Detailed project view modal/page: + - Large gallery of images + - Title, description, dates + - Technologies and skills + - Impact metrics + - Links to live project/demo + - Related projects suggestions + +### Portfolio Statistics Widget +- Dashboard home shows portfolio health +- "Portfolio: 24 projects | 480 hours | React, Python, Design..." +- Growth indicator: "+3 projects this quarter" +- Link to expand full portfolio + +### Portfolio Statistics Dashboard +- Header cards: + - Total projects (24) + - Total hours (480) + - Average project duration (20 days) + - Total income (if freelance) +- Skills matrix: + - Bar chart showing skill frequency + - "React: 8 projects, Figma: 5 projects" +- Project timeline: + - Visual timeline of all work chronologically + - Grouped by year +- Project breakdown: + - Pie chart by category + - Bar chart by quarter/year showing project count + +### Skills Profile Section +- Table showing skills with: + - Skill name + - Proficiency level (colored bars) + - Number of projects using skill + - Last used date + - Trending indicator (↑ if recently active) +- Add new skill button +- Endorse others' skills (if social network) + +### Public Portfolio Page +- Beautiful, auto-designed landing page +- Customizable but no-code +- Mobile-responsive +- Includes: + - Hero section with name/title/bio + - Featured projects section (3-5 highlighted) + - Full gallery grid + - Skills section with visual representation + - Stats: "24 projects | 480 hours | 50+ clients" + - Contact/social links + - About section + - Download resume option + +### Work-in-Progress (WIP) Section +- Separate area for active projects +- Shows: + - Project name + - Estimated completion date + - Hours logged so far + - Progress bar (if estimated hours available) + - Hidden from public portfolio by default +- Quick time-logging button + +### Timeline View +- Chronological list of all projects +- Grouped by year or quarter +- Each project shows: + - Title and brief description + - Date range + - Status (completed/wip) + - Technologies/skills + - Small thumbnail +- Can be filtered by time period +- Shows work evolution + +## Integration Points + +**Activity Log:** +- Completed projects appear as major milestones in timeline +- "Shipped project: E-commerce redesign" + +**Freelance Tracking Integration:** +- Project shows income earned: "$2,000 for this project" +- Portfolio total: "$45,000 total earned" +- Client name linked (if making freelance feature) + +**Skill Leveling System:** +- Skills in portfolio feed into skill levels +- "React: 8 projects → Advanced level" +- Proficiency levels updated based on project frequency + +**Accountability Network:** +- Share project completion as milestone achievement +- Partner sees: "They just shipped a new project!" + +**Social Network (Future):** +- Portfolio can be shared publicly +- Other users can endorse your skills +- Collaboration connections through portfolio viewing + +## Success Criteria + +- Project creation: <5 minutes including images +- Portfolio page looks professional without design work +- Portfolio stats accurately reflect project data +- Public portfolio link shareable and mobile-friendly +- Search and filtering work intuitively +- Portfolio impacts job prospects or freelance opportunities + +## Technical Considerations + +- Image upload and optimization +- Portfolio page generation (template system) +- Statistics calculations (hours, project count, income) +- Timeline visualization +- Public URL generation and custom domains (future) +- Responsive design for all screen sizes +- SEO optimization for public portfolio pages + +## Error Handling + +- Missing images: provide placeholder +- Incomplete projects: allow WIP status +- Date validation: end date must be after start date +- Image size limits: compress or reject oversized files +- URL validation: check link is accessible +- Character limits: descriptions, skills, etc. + +## Privacy Considerations + +- Portfolio visibility toggle: public/private +- Can hide specific projects from public view +- Income data only visible to user, not public +- WIP projects hidden from public by default +- Collaborators only visible if they've given permission +- Can opt out of being findable/endorsable + +## Portfolio Customization (Future) + +- Theme selection (color schemes) +- Custom domain support +- Custom sections (testimonials, awards, etc.) +- Embedded media (videos, sound clips) +- Blog/articles section +- Case study templates + +## Related Features + +- Skill Leveling System: tracks skills from portfolio +- Freelance Tracking: shows income per project +- Creative Metrics: complements for creative output +- Accountability Network: share project completions +- Activity Log: major milestones appear here + +## Open Questions + +1. Should we support video embedding (demo videos, tutorials)? +2. Should collaborators be able to edit shared projects? +3. Should we offer portfolio templates vs. completely custom? +4. Should we integrate with GitHub to auto-populate code projects? +5. Should testimonials/recommendations be supported early? diff --git a/.claude/ideas/dashboard/007-skill-leveling-system.md b/.claude/ideas/dashboard/007-skill-leveling-system.md new file mode 100644 index 000000000..0ca585254 --- /dev/null +++ b/.claude/ideas/dashboard/007-skill-leveling-system.md @@ -0,0 +1,314 @@ +# 007 - Skill Leveling System + +## Overview +A gamified skill development tracker that visualizes competency growth across technical and soft skills. Users level up skills through consistent practice, tracked project use, deliberate practice logging, and completion of skill-building activities. Provides visual progression, skill trees, proficiency assessments, and integration with portfolio and accountability network for motivated learning. + +## Purpose & Goals +- Make skill development visible and rewarding +- Provide clear progression paths: Beginner → Intermediate → Advanced → Expert +- Enable sharing of skill goals with accountability partners +- Integrate with portfolio (projects demonstrate skill levels) +- Recognize and celebrate skill mastery +- Support skill-building goals and milestones +- Show skill evolution over time + +## Key User Flows + +### 1. Add Skill to Track +- User selects or creates a skill to track +- Optionally sets proficiency goal level +- System assigns starting level based on assessment or self-rating +- Skill appears in "My Skills" list with visual progress + +### 2. Log Skill Usage +- Log deliberate practice: "Spent 2 hours on React components" +- Log project work: "Used Python in e-commerce project" +- Log learning: "Completed React hooks course" +- Each activity contributes to skill level progression +- Frequency matters: consistent practice advances faster + +### 3. Skill Levels & Assessment +- 5-level system: + - Beginner (0-25%): Learning fundamentals + - Novice (25-50%): Practical experience, small projects + - Intermediate (50-75%): Comfortable with most tasks, leading small work + - Advanced (75-90%): Expert-level work, mentoring others + - Expert (90-100%): Mastery, recognized authority +- Users can take assessments to verify level +- Portfolio projects automatically update skill levels +- Skill insights: "React: Advanced (8 projects, 200 hours)" + +### 4. Skill Dependencies & Trees +- Some skills build on others: "Python → Data Science → Machine Learning" +- Visual dependency tree showing skill relationships +- "Unlock" skills by reaching certain levels in prerequisites +- Suggested progression paths + +### 5. Skill Goals & Milestones +- Set goal: "Reach Advanced in React by December" +- System calculates: "5 more projects at current pace" +- Milestone celebrations when leveling up +- Share skill goal with accountability partner +- "We're both learning React—let's level up together!" + +### 6. Practice Streaks & Badges +- Practice streak tracking: "React: 15-day streak" +- Skill badges: earned at level milestones + - "🏆 React Novice" at 25% + - "🏆 React Intermediate" at 50% + - etc. +- Annual skill review: "Your top 3 skills this year" +- Yearly achievements: "Mastered 5 new skills in 2024" + +## Data Model + +```typescript +interface Skill { + id: string + userId: string + name: string + category: SkillCategory // "technical", "soft", "creative", "business" + currentLevel: "beginner" | "novice" | "intermediate" | "advanced" | "expert" + proficiencyScore: number // 0-100 + targetLevel?: string // Desired level + targetDate?: DateTime + + // Progression data + totalHours: number + projectsUsed: number + lastPracticedDate: DateTime + streakDays: number + streakStartDate: DateTime + + // Proficiency data + selfAssessmentScore?: number // User's self-assessment + assessmentResults?: Array<{ + date: DateTime + score: number + questions: number + }> + + // Dependencies + prerequisiteSkills?: string[] // skillIds + relatedSkills?: string[] + + createdAt: DateTime + updatedAt: DateTime +} + +type SkillCategory = "technical" | "soft" | "creative" | "business" | "language" + +interface SkillActivity { + id: string + userId: string + skillId: string + activityType: "practice" | "project" | "learning" | "teaching" | "assessment" + title: string // "Built React component library" + hoursLogged: number + description?: string + sourceFeature?: string // "portfolio", "activity_log", etc. + proficiencyGain: number // Calculated by system + createdAt: DateTime +} + +interface SkillBadge { + id: string + skillId: string + userId: string + badgeType: "level_reached" | "streak" | "annual" | "mastery" + level: string // "beginner", "novice", "intermediate", "advanced", "expert" + earnedAt: DateTime +} + +interface SkillAssessment { + id: string + skillId: string + userId: string + score: number // 0-100 + questions: number + correctAnswers: number + estimatedLevel: string + completedAt: DateTime +} +``` + +## UI Components + +### Add Skill Modal +- Skill name input with autocomplete +- Category selector (technical, soft, creative, business, language) +- Starting level assessment (optional quiz or self-rating) +- Target level and deadline (optional) +- Save button + +### My Skills Dashboard +- Tabs: Overview | Skills | Goals | Badges | Assessments +- Overview tab: + - Skills ranked by proficiency level + - Recent activity in each skill + - Fastest growing skill + - Current practice streaks + - Total learning hours +- Skills tab: + - List of all tracked skills + - Each skill card shows: + - Skill name and icon + - Current level (Beginner/Novice/Intermediate/Advanced/Expert) + - Progress bar (0-100%) + - Hours logged + - Projects using skill + - Last practiced date + - Practice streak indicator + - Trending indicator (↑ if active this week) + - Click to view details +- Goals tab: + - Active skill goals + - Each shows: + - Skill name + - Current vs. target level + - Deadline + - Progress toward goal + - Suggested activities: "Practice 2 more projects" + - Completed skill goals (archive) +- Badges tab: + - All earned badges displayed + - Organized by date earned + - Share badges to portfolio/social +- Assessments tab: + - History of skill assessments + - Score and recommended level + - Option to take new assessment + +### Skill Detail Page +- Skill name and category +- Large progress bar (0-100%) +- Current level display +- Statistics: + - Total hours logged: 120 + - Projects using skill: 5 + - Last practiced: 3 days ago + - Streak: 12 days + - First logged: 6 months ago +- Practice streak visual (calendar heatmap) +- Recent activities (practice, projects, learning) +- Related/prerequisite skills +- Suggested next steps +- Skill goal (if set) +- Option to log new activity +- Skill dependency tree (visual) + +### Skill Leveling Progress +- Visual progression system: + - Beginner: 0-25% (flat bar) + - Novice: 25-50% (bar with 1 segment filled) + - Intermediate: 50-75% (bar with 2 segments filled) + - Advanced: 75-90% (bar with 3 segments filled) + - Expert: 90-100% (full bar, special color) +- Milestone celebrations when leveling up +- Estimated time to next level based on pace + +### Skill Tree Visualization +- Network diagram showing skill relationships +- Prerequisites shown as arrows pointing up +- Related skills shown as connections +- Unlocked skills highlighted, locked skills grayed out +- Click to view skill details +- Auto-layout for readability + +### Practice Logging Widget +- Quick "Log Practice" button +- Minimal form: + - Skill selector + - Activity type (practice/project/learning) + - Hours spent + - Description (optional) + - Submit +- Takes <1 minute to log + +### Badges & Achievements +- Achievement cards showing: + - Badge icon + - Title: "React Intermediate" + - Date earned + - "Share" button for portfolio/social + - Collectible feel + +## Integration Points + +**Portfolio System:** +- Projects automatically update skill levels +- "React: 8 projects → Advanced level" +- Portfolio shows skill progression timeline + +**Accountability Network:** +- Share skill goals with partners +- "Let's both reach Intermediate in Python" +- Shared progress tracking and leaderboards +- Skill milestone celebrations with partner + +**Activity Log:** +- Skill practice appears as activities +- Can tag activities with relevant skills +- "Completed React tutorial: +5 React XP" + +**Creative Metrics (for creative skills):** +- Creative output counts as practice +- "Wrote 1000 words: +10 Writing XP" +- Art projects level up design skills + +**Job/Freelance Tracking:** +- Client projects update skill usage +- Highest-value skills highlighted +- Portfolio shows most marketable skills + +## Success Criteria + +- Clear progression visible within days of consistent practice +- Users understand how to advance skills +- Skill levels integrate naturally with portfolio +- Practice logging takes <2 minutes +- Levels feel achievable, not grindy +- Partnership features motivate skill growth + +## Technical Considerations + +- Proficiency score calculations (weighted by activity type) +- Streak tracking (timezone-aware date comparisons) +- Skill dependency graph (topological sorting) +- XP/points system (optional gamification) +- Assessment quiz database and scoring +- Skill recommendation engine (based on portfolio/interests) + +## Error Handling + +- Duplicate skill entries: prevent or merge +- Invalid hours: validate positive numbers only +- Assessment scores out of range: sanitize +- Circular dependencies: prevent in skill trees +- Streak breaks: gracefully reset and notify +- Missing prerequisite: warn before advancing + +## Gamification Elements (Optional) + +- XP points: earn from activities, level up skills +- Streak bonuses: longer streaks = faster progression +- Badges/achievements: visual rewards +- Leaderboards: compete with accountability partners on specific skills +- Prestige system: reset level to earn bonus points after mastery +- Skill mastery celebration: "You've become an expert!" + +## Related Features + +- Portfolio: skills demonstrated through projects +- Accountability Network: shared skill goals +- Creative Metrics: creative skill advancement +- Activity Log: practice activities tracked +- Job Tracking: freelance work updates skills + +## Open Questions + +1. Should we have automated skill assessments or user self-assessment? +2. How many skill categories initially vs. user-created skills? +3. Should skill dependencies be strict or just suggestions? +4. Should there be a community skill database? +5. Should XP/points be visible or just levels? diff --git a/.claude/ideas/dashboard/008-relationship-calendar.md b/.claude/ideas/dashboard/008-relationship-calendar.md new file mode 100644 index 000000000..c90920b03 --- /dev/null +++ b/.claude/ideas/dashboard/008-relationship-calendar.md @@ -0,0 +1,347 @@ +# 008 - Relationship Calendar + +## Overview +A relationship maintenance system that reminds users about important dates and encourages regular connection with people they care about. Provides calendar view of birthdays, anniversaries, and check-in deadlines, suggests thoughtful actions, tracks relationship health through frequency of contact, and integrates with accountability partners for shared social activities. + +## Purpose & Goals +- Prevent important relationships from fading due to busy life +- Maintain awareness of important dates (birthdays, anniversaries) +- Suggest proactive outreach before relationships need maintenance +- Track relationship health through contact frequency +- Enable collaborative social events and gatherings +- Reduce guilt about staying connected +- Celebrate important people in life + +## Key User Flows + +### 1. Add Person to Relationships +- User adds person they care about +- Fields: + - Name and optional photo + - Relationship type (friend, family, partner, mentor, colleague, etc.) + - Important dates (birthday, anniversary, meeting date) + - Contact frequency goal ("Check in weekly", "Monthly", etc.) + - Preferred contact methods (call, text, coffee, dinner, etc.) + - Notes about shared interests +- System sets reminders + +### 2. Calendar View +- Monthly calendar showing: + - Important dates highlighted (birthdays, anniversaries) + - Check-in deadlines marked + - Personal events and gatherings +- Different colors for different relationship types +- Hovering on date shows who/what event +- Click to see relationship details and suggested actions + +### 3. Relationship Check-In +- System reminds: "Haven't chatted with [Person] in 3 weeks. Check in?" +- Quick action suggestions: + - "Call for 15 minutes" + - "Send a message" + - "Suggest coffee this weekend" + - "Schedule video call" +- User logs check-in: records contact +- Can attach note: "Caught up on their new job" + +### 4. Important Date Notifications +- Birthday approaching: "Sarah's birthday in 3 days" +- Suggestions: "Send a card", "Plan dinner", "Order a gift" +- Anniversary: "Your 5-year friendship anniversary with Marcus!" +- Custom date reminders: "Date night scheduled for Saturday" + +### 5. Relationship Health Dashboard +- List of important relationships +- Health indicator: "Healthy" (recent contact), "Attention needed" (overdue), "Strong" (frequent contact) +- Last contact date for each person +- Days until next important date +- Quick contact button (call, text, email) +- Upcoming dates this month + +### 6. Group Events & Gatherings +- Create or join shared events with accountability partners +- "Birthday party for James - June 15" +- "Group hike next Saturday" +- Collaborative planning: todos, expense splitting (optional) +- RSVP tracking +- Post-event: group photo sharing, recap + +## Data Model + +```typescript +interface Relationship { + id: string + userId: string + name: string + photoUrl?: string + relationshipType: RelationshipType // "friend", "family", "partner", "mentor", "colleague" + email?: string + phone?: string + socialMedia?: Array<{ + platform: string // "instagram", "twitter", "linkedin" + handle: string + }> + + // Important dates + importantDates?: Array<{ + label: string // "birthday", "anniversary", "wedding_date" + date: DateTime + }> + + // Contact goals + checkInFrequencyDays?: number // Check in every X days (null = no goal) + preferredContactMethods?: string[] // ["call", "text", "coffee", "dinner"] + lastContactDate?: DateTime + lastContactMethod?: string + + // Relationship notes + sharedInterests?: string[] // ["hiking", "cooking", "gaming"] + notes?: string + anniversaryOfFriendship?: DateTime // When did you meet? + + // Shared with accountability partner + sharedWith?: string[] // userIds + + createdAt: DateTime + updatedAt: DateTime +} + +type RelationshipType = "friend" | "family" | "partner" | "mentor" | "colleague" | "acquaintance" + +interface CheckIn { + id: string + userId: string + relationshipId: string + dateTime: DateTime + method: "call" | "text" | "email" | "coffee" | "dinner" | "video_call" | "in_person" | "other" + notes?: string + duration?: number // minutes (for calls/coffee) + photo?: string // Optional photo from meeting + createdAt: DateTime +} + +interface RelationshipEvent { + id: string + userId: string + title: string + description?: string + dateTime: DateTime + relatedPeople?: string[] // relationshipIds + eventType: "birthday" | "anniversary" | "gathering" | "milestone" | "other" + location?: string + isPublic: boolean + + // For shared events with accountability partners + sharedWith?: string[] // userIds + attendees?: string[] // People attending + rsvpStatus?: Map + + // Expense sharing (optional) + sharedExpenses?: Array<{ + description: string + amount: number + paidBy: string // userId + }> + + createdAt: DateTime + updatedAt: DateTime +} + +interface CheckInReminder { + id: string + userId: string + relationshipId: string + dueDate: DateTime + status: "pending" | "completed" | "dismissed" + createdAt: DateTime +} +``` + +## UI Components + +### Add Relationship Modal +- Simple form with fields: + - Name input + - Photo upload (optional) + - Relationship type selector + - Birthday/anniversary date picker + - Check-in frequency dropdown + - Preferred contact methods (multi-select) + - Shared interests (tags) + - Notes textarea +- Save button + +### Relationship Calendar Page +- Full month view (like Google Calendar) +- Different colors for relationship types: + - Blue = Friends + - Red = Family + - Pink = Partner + - Green = Mentors + - Gray = Colleagues +- Important dates appear as events +- Check-in reminders appear as notifications on calendar +- Click date to see all people/events +- Hover on event to see quick preview +- Small "Mark complete" button for check-in reminders + +### Relationship List/Dashboard +- Tabs: Overview | Calendar | People | Events | Check-ins +- Overview tab: + - Quick stats: "10 relationships", "Contacted 4 this week" + - Upcoming important dates (next 30 days) + - People needing check-in soon (overdue list) + - Next birthday/anniversary + - Monthly check-in goal progress +- People tab: + - List of all relationships + - Each person card shows: + - Name and photo + - Relationship type + - Last contact: "3 weeks ago" + - Days since last contact + - Next important date + - Health indicator: 🟢 Healthy / 🟡 Overdue / 🔴 Urgent + - Quick action buttons: Call, Text, Email, Log Check-in +- Events tab: + - Upcoming events and gatherings + - Past events (photos, recaps) + - Create new event button +- Check-ins tab: + - History of all check-ins with dates and methods + - Grouped by person or chronologically + - Notes and photos visible + +### Relationship Detail Page +- Relationship name and photo +- Quick stats: + - Last contact: "3 weeks ago" + - Contact frequency: "Check in every 2 weeks" + - Relationship duration: "Friends for 5 years" + - Next important date: "Birthday - June 15 (25 days)" +- Contact methods and social media links +- Timeline of check-ins (latest first) +- Shared interests +- Notes section +- Shared events (if accountability partner involved) +- Quick actions: Call, Text, Email, Log Check-in, Schedule Call + +### Check-In Modal +- Quick logging after contacting someone +- Fields: + - Contact method (call, text, coffee, dinner, etc.) + - Duration (if call/in-person) + - Notes about conversation + - Optional photo +- Auto-populates current date/time +- Submit button +- Confirmation with next suggested check-in date + +### Check-In Reminder Card +- Push notification or in-app notification +- "Haven't talked to Sarah in 2 weeks. Check in?" +- Suggested actions: + - "Call for 15 min" + - "Send message" + - "Schedule coffee" + - "Dismiss for 1 week" +- Quick action buttons + +### Shared Event Card (Accountability Partners) +- Event title and date +- Location +- Invited attendees +- RSVP status for you +- Shared expense breakdown (if applicable) +- "View event details" link +- Post-event: photo gallery, recap notes + +### Health Indicator +- Visual status for each relationship: + - 🟢 Healthy: Recent contact, on schedule + - 🟡 Overdue: Overdue for check-in + - 🔴 Urgent: Very overdue, relationship at risk +- Hover shows: "Last contact: 3 weeks ago, Goal: every 2 weeks" + +## Integration Points + +**Accountability Network:** +- Create shared social events with accountability partner +- "Let's both call our parents this weekend" +- Partner can see your relationship calendar +- Group activities count toward social goals + +**Calendar/Planning:** +- Events appear in main dashboard calendar +- Important dates sync with personal calendar (optional) +- Reminders appear as calendar notifications + +**Activity Log:** +- Check-ins appear in activity timeline +- "Had coffee with Sarah", "Called mom" +- Shows social engagement metrics + +**Mood & Energy Tracker:** +- Social activities can affect mood/energy +- "Social time energizes you: +1.2 energy" +- Suggests scheduling social time when energy is low + +**Mood/Energy Tracker Integration:** +- "You're more energized after seeing friends" +- Suggestion: "Schedule time with Sarah—you said it energizes you" + +## Success Criteria + +- Users don't let important relationships fade +- Important dates never missed +- Check-in reminders feel helpful, not nagging +- Relationship health is visible at a glance +- Contact logging is quick and easy (<1 minute) +- Shared events with partners are seamless + +## Technical Considerations + +- Calendar visualization (month view, color coding) +- Reminder scheduling and notifications +- Check-in frequency calculations +- Important date notifications +- Time zone awareness for all dates +- Optional: integration with calendar apps (Google Calendar, Apple Calendar) + +## Error Handling + +- Duplicate relationships: warn user +- Invalid dates: prevent future dates for past events +- Missing contact method: allow logging without it +- Overdue check-ins: don't penalize, just suggest +- Event attendee RSVP: handle non-responses gracefully + +## Privacy Considerations + +- Relationship data private by default +- Sharing with accountability partner optional +- Shared events explicit opt-in +- Photos require permission to share +- Can block certain people from seeing your calendar + +## Relationship Insights (Future) + +- "You check in more frequently with friends vs. family" +- "Your social time is concentrated on weekends" +- "You maintain 12 active relationships" +- Suggestions for relationship improvement + +## Related Features + +- Integrates with Accountability Network for social goals +- Feeds into Mood & Energy Tracker (social interaction effects) +- Activity Log shows social engagement +- Can link to Portfolio (professional relationships/networking) + +## Open Questions + +1. Should we integrate with actual calendar apps (Google Calendar, Apple Calendar)? +2. Should we allow groups/family relationships (multiple people at once)? +3. Should we send automated reminder messages on their behalf? +4. Should relationship history be searchable/archived? +5. Should we track relationship sentiment (conversation quality)? diff --git a/.claude/ideas/dashboard/009-investment-dashboard.md b/.claude/ideas/dashboard/009-investment-dashboard.md new file mode 100644 index 000000000..5181d1e1f --- /dev/null +++ b/.claude/ideas/dashboard/009-investment-dashboard.md @@ -0,0 +1,293 @@ +# 009 - Investment Dashboard + +## Overview +A portfolio tracking system for stocks, crypto, and other investments. Provides simple investment logging, performance visualization, portfolio allocation breakdown, gain/loss tracking, and integration with savings goals and spending analytics for comprehensive financial health view. + +## Purpose & Goals +- Track investment portfolio performance without complexity +- Understand asset allocation and diversification +- See gains/losses and total return percentage +- Monitor long-term wealth building progress +- Integrate with savings goals and spending patterns +- Provide insights without requiring financial expertise +- Support multiple asset classes (stocks, crypto, real estate, bonds, etc.) + +## Key User Flows + +### 1. Add Investment +- User adds investment to track +- Fields: + - Asset name (ticker symbol or crypto name) + - Asset type (stock, crypto, real estate, ETF, bond, etc.) + - Quantity owned (shares or coins) + - Purchase price per unit + - Current price (auto-fetch from API if available) + - Purchase date + - Optional notes +- System calculates current value, gain/loss, percentage return +- Optional: add multiple purchases of same asset (cost basis tracking) + +### 2. Portfolio Overview +- Total portfolio value prominently displayed +- Total gain/loss in dollars and percentage +- "You're up $2,450 (12% return)" +- Portfolio allocation pie chart: + - Stocks: 60% + - Crypto: 25% + - Bonds: 15% +- Asset breakdown table: + - Asset name + - Quantity + - Current price + - Current value + - Gain/loss + - Percentage return + - Sparkline showing price trend + +### 3. Performance Tracking +- Portfolio value over time (line graph) +- 1-month, 3-month, 1-year, all-time views +- Total return calculation +- Benchmark comparison (S&P 500, Nasdaq, etc.) +- Best/worst performing assets +- Volatility indicator (how stable is portfolio) + +### 4. Dividend & Income Tracking +- Track dividend-paying stocks +- Crypto staking rewards +- Real estate rental income +- Monthly/annual income from investments +- "Annual dividend income: $1,200" + +### 5. Investment Goals +- Set target portfolio size: "Reach $100k by 2030" +- Track progress toward goal +- Estimated time to reach goal based on returns +- Savings rate impact: "You need to save $X/month to hit goal" +- Integrate with Spending Tracker spending goals + +## Data Model + +```typescript +interface Investment { + id: string + userId: string + assetName: string // "Apple Inc.", "Bitcoin", "Vanguard S&P 500" + assetType: InvestmentType // "stock", "crypto", "etf", "bond", "real_estate" + ticker?: string // "AAPL", "BTC", "VOO" + quantity: number + currentPrice: number + currentValue: number // quantity * currentPrice + totalCost: number // total amount paid for this investment + gains: number // currentValue - totalCost + gainPercent: number // (gains / totalCost) * 100 + lastUpdated: DateTime + + // Purchase history for cost basis + purchases: Array<{ + date: DateTime + quantity: number + pricePerUnit: number + totalCost: number + }> + + // Income + dividendIncome?: number // annual or cumulative + dividendPaymentDates?: DateTime[] // When dividends paid + otherIncome?: number // Real estate rental, staking, etc. + + notes?: string + createdAt: DateTime + updatedAt: DateTime +} + +type InvestmentType = "stock" | "crypto" | "etf" | "bond" | "real_estate" | "commodity" | "other" + +interface Portfolio { + id: string + userId: string + totalValue: number + totalCost: number + totalGains: number + totalGainPercent: number + allocation: Map // percentage breakdown + lastUpdated: DateTime +} + +interface PortfolioSnapshot { + id: string + userId: string + portfolioValue: number + timestamp: DateTime // Daily snapshots for charting +} + +interface InvestmentGoal { + id: string + userId: string + goalName: string // "Reach $100k" + targetValue: number + deadline: DateTime + currentProgress: number // auto-calculated + monthlyContribution?: number // Savings needed monthly + estimatedAchievementDate: DateTime + createdAt: DateTime +} +``` + +## UI Components + +### Add Investment Modal +- Form with fields: + - Asset name/ticker with autocomplete + - Asset type dropdown + - Quantity input + - Purchase price per unit + - Current price (auto-fetch option or manual) + - Purchase date + - Notes (optional) +- Submit button +- Can add multiple purchases for same asset + +### Portfolio Dashboard +- Tabs: Overview | Assets | Performance | Goals | Income +- Overview tab: + - Large portfolio value display: "$47,250" + - Total gains/losses: "+$2,450 (+5.5%)" + - Allocation pie chart (interactive) + - Recent price changes (sparklines for each major asset) + - Quick add investment button +- Assets tab: + - Table of all holdings: + - Asset name/ticker + - Quantity + - Current price + - Current value + - Cost basis + - Gain/loss in dollars and percent + - Sparkline (7-day price trend) + - Sortable by value, gain%, type, etc. + - Click asset to see detailed history +- Performance tab: + - Line chart: portfolio value over time + - Time period selector (1m, 3m, 1y, 5y, all) + - Total return percentage for period + - Best/worst performing assets + - Volatility metric + - Comparison option (vs. S&P 500, Nasdaq) +- Goals tab: + - Investment goals with progress + - "Reach $100k by 2030: $47,250/$100,000 (47%)" + - Time remaining and monthly savings needed + - "At current pace, you'll reach goal in 8 years" +- Income tab: + - Dividend income tracking + - "Annual dividend income: $1,200" + - Monthly income breakdown + - Staking/other income + - Income over time + +### Investment Detail Page +- Asset name, type, ticker +- Current price and price change (% and $) +- Holdings: + - Total shares/quantity + - Average cost per unit + - Total cost + - Current value + - Total gain/loss +- Price chart (sparkline to full chart) +- Purchase history table +- Dividend history (if applicable) +- News/info about asset (optional) + +### Portfolio Widget +- Dashboard home shows portfolio snapshot +- "Portfolio: $47,250 (+$2,450 +5.5%)" +- Allocation pie mini-chart +- Link to expand full portfolio + +### Asset Allocation Pie Chart +- Interactive pie chart +- Slice size = percentage allocation +- Click slice to filter to that asset type +- Hover to see value and percentage +- Colors distinguish asset types + +## Integration Points + +**Spending Tracker Integration:** +- Compare spending vs. investment income +- "Annual dividend income ($1,200) covers monthly groceries" +- Show spending relative to investment gains + +**Savings Goals Integration:** +- Investment goal syncs with spending/savings goals +- "Aim to save $X/month to reach $100k portfolio" +- Combined view of all financial goals + +**Accountability Network:** +- Share investment goals with partner +- "Let's both reach $100k portfolio by 2030" +- Partner can see portfolio growth (not individual holdings) +- Shared investing challenges + +**Financial Dashboard (Future):** +- Combined net worth view: portfolio + savings - debt +- Overall financial health score +- Allocation across all assets + +## Success Criteria + +- Portfolio adds take <2 minutes +- Current portfolio value always accurate and up-to-date +- Performance metrics are correct (gains, percentages) +- Price updates happen automatically if using API +- Users understand portfolio allocation +- Goals feel achievable and motivating + +## Technical Considerations + +- API integration for real-time price data (Alpha Vantage, CoinGecko, etc.) +- Portfolio calculations (weighted average cost basis) +- Performance charting (multiple time periods) +- Daily snapshots for historical tracking +- Tax lot tracking (for tax reporting) +- Optional: import from CSV or Robinhood/Fidelity APIs + +## Error Handling + +- Invalid ticker symbols: suggest corrections +- Negative quantities: prevent +- Price data missing: show manual entry option +- Duplicate holdings: allow multiple buys of same asset +- Goal calculation: handle scenarios where goal not achievable + +## Privacy & Security + +- All portfolio data private +- No sharing of specific holdings (only summaries) +- No API keys or credentials stored +- Encryption for sensitive portfolio data + +## Tax Considerations (Future) + +- Gain/loss calculation for tax reporting +- Identify long-term vs. short-term gains +- Export capital gains for tax filing +- Integration with tax prep software (optional) + +## Related Features + +- Spending Dashboard: spending vs. investment income +- Savings Goals: overall financial targets +- Accountability Network: shared investment goals +- Debt Snowball Tracker: net worth includes investments minus debt +- Financial Dashboard (future): combined net worth view + +## Open Questions + +1. Should we support real estate valuation/estimates? +2. Should we track currency exposure for international investments? +3. Should we provide investment recommendations or education? +4. Should we integrate with brokerage APIs for auto-import? +5. Should we support options/derivatives tracking? diff --git a/.claude/ideas/dashboard/010-debt-snowball-tracker.md b/.claude/ideas/dashboard/010-debt-snowball-tracker.md new file mode 100644 index 000000000..1ea14712d --- /dev/null +++ b/.claude/ideas/dashboard/010-debt-snowball-tracker.md @@ -0,0 +1,331 @@ +# 010 - Debt Snowball Tracker + +## Overview +A debt payoff system that tracks loans, credit card balances, and other debts with progress visualization, payoff strategy recommendations, interest savings calculations, and motivating progress tracking. Helps users visualize debt elimination and celebrate payoffs while integrating with spending and savings goals for comprehensive financial health. + +## Purpose & Goals +- Make debt payoff visible and motivating +- Show progress toward being debt-free +- Calculate interest savings from early payoff +- Support multiple debt payoff strategies (snowball, avalanche) +- Celebrate debt milestones and completions +- Integrate debt payoff with spending and savings tracking +- Reduce financial stress through transparency + +## Key User Flows + +### 1. Add Debt +- User adds debt to track +- Fields: + - Creditor name (bank, credit card, etc.) + - Debt type (credit card, loan, mortgage, etc.) + - Current balance owed + - Interest rate (APR) + - Minimum payment amount + - Due date + - Target payoff date (optional) + - Notes +- System calculates interest accumulation and payoff timeline + +### 2. Debt Dashboard Overview +- Total debt owed prominently displayed +- Progress ring showing % paid off +- "You've eliminated $5,000 of debt. $15,000 remaining." +- List of all debts with individual progress +- Sorted options: balance, interest rate, due date +- Total interest paid to date +- Total interest remaining (if current trajectory) + +### 3. Payoff Strategy +- Snowball strategy: pay smallest debt first (psychological wins) +- Avalanche strategy: pay highest interest first (mathematically optimal) +- Hybrid strategy: recommended payoff order +- System shows: "If you pay $500/month on [Debt], you'll pay off in 30 months" +- Interest saved by accelerating payments: "Pay $600/month → Save $2,000 interest" + +### 4. Progress Visualization +- Individual debt progress bars +- Timeline showing projected payoff dates +- Interest reduction graph +- Monthly payment breakdown +- Payoff milestones: "Next: Eliminate credit card #1 in 8 months" + +### 5. Payoff Tracking +- Log payments as they're made +- Manual entry or auto-sync from spending tracker +- Update balances periodically +- Track extra payments (snowball acceleration) +- Show months remaining for each debt + +### 6. Payoff Achievements & Milestones +- Celebration when debt reaches 25%, 50%, 75%, 100% paid +- Achievement badge: "Paid off $5,000!" +- "You're debt-free on credit card #2! 🎉" +- Annual debt reduction: "You eliminated $8,000 debt this year" +- Total interest saved vs. minimum payments + +## Data Model + +```typescript +interface Debt { + id: string + userId: string + creditorName: string + debtType: DebtType // "credit_card", "personal_loan", "mortgage", "student_loan", "other" + originalBalance: number + currentBalance: number + minimumPayment: number + interestRate: number // APR as percentage + dueDate: DateTime + targetPayoffDate?: DateTime + + // Payment history + payments: Array<{ + date: DateTime + amount: number + notes?: string + }> + + // Interest tracking + totalInterestPaid: number + projectedInterestRemaining: number + payoffStrategy?: "snowball" | "avalanche" | "hybrid" + + // Metadata + notes?: string + isFocused: boolean // Which debt to prioritize payoff + accountNumber?: string // Last 4 digits only + + createdAt: DateTime + updatedAt: DateTime +} + +type DebtType = "credit_card" | "personal_loan" | "mortgage" | "student_loan" | "auto_loan" | "medical" | "other" + +interface PayoffStrategy { + userId: string + strategyType: "snowball" | "avalanche" | "hybrid" + debts: Array<{ + debtId: string + payoffOrder: number + suggestedMonthlyPayment: number + projectedPayoffDate: DateTime + interestSaved: number + }> + totalMonthlyPayment: number + projectedDebtFreeDate: DateTime + totalInterestSaved: number + createdAt: DateTime +} + +interface DebtMilestone { + id: string + userId: string + debtId: string + milestonePercent: number // 25, 50, 75, 100 + achievedDate: DateTime + balanceAtAchievement: number +} + +interface NetWorthSnapshot { + id: string + userId: string + totalAssets: number // Investments, savings + totalDebts: number + netWorth: number // assets - debts + timestamp: DateTime // Daily snapshots +} +``` + +## UI Components + +### Add Debt Modal +- Form with fields: + - Creditor name + - Debt type dropdown + - Current balance + - Interest rate (APR) + - Minimum payment + - Due date + - Target payoff date (optional) + - Notes +- Submit button +- Can add multiple debts + +### Debt Dashboard Page +- Tabs: Overview | Debts | Strategy | Progress | Milestones +- Overview tab: + - Large "Total Debt: $20,000" display + - Total minimum payment monthly + - Total interest paid to date: "$2,450" + - Projected interest remaining: "$3,200" + - Interest saved vs. minimum payments (if paying extra) + - Progress ring: 25% paid off + - "Debt-free in 36 months at current pace" + - Quick add debt button +- Debts tab: + - Table/list of all debts: + - Creditor name + - Debt type + - Current balance + - Interest rate + - Minimum payment + - Payoff date (projected) + - Progress bar (% paid off) + - Sortable by balance, interest rate, due date + - Click to view debt details + - Mark as focused (for strategy) +- Strategy tab: + - Current strategy selection (snowball/avalanche) + - Recommended payoff order: + - Debt 1: pay $X/month → payoff in 12 months + - Debt 2: pay $Y/month → payoff in 18 months (after #1 paid) + - Debt 3: pay $Z/month → payoff in 24 months (after #2 paid) + - "This strategy saves you $X in interest" + - Alternative strategy comparison + - Adjust monthly payment slider to see impact + - "If you pay $600/month: debt-free in 24 months" +- Progress tab: + - Timeline showing payoff milestones + - Monthly interest savings graph + - Remaining balance line chart + - Payment history + - Extra payments highlight +- Milestones tab: + - Recent milestone celebrations + - "Paid off $5,000 (25% of credit card debt)" + - Date achieved + - Interest saved so far + - Next milestone progress + +### Debt Detail Page +- Debt name and type +- Current balance and progress bar +- Interest rate and monthly interest accrual +- Payment history (recent payments listed) +- Payoff timeline: "30 months remaining" +- Log payment button +- Estimated payoff date +- Total interest paid vs. remaining +- Update balance option + +### Payoff Strategy Recommendation +- Shows three options side-by-side: + - Snowball: "Pay smallest first" + - Avalanche: "Pay highest interest first" + - Hybrid: "Optimized for psychology + math" +- For each strategy: + - Payoff timeline + - Interest saved + - Debt-free date +- Select strategy button +- Ability to customize monthly payment amounts + +### Milestone Celebration Modal +- Full-screen celebration when milestone hit +- Confetti animation +- Achievement badge +- "You've paid off 50% of your credit card debt! 🎉" +- Progress to next milestone: "1 year to 75%" +- Share milestone button (optional) + +### Debt Widget +- Dashboard home shows: + - Total debt: "$20,000" + - Progress: "25% paid off" + - Debt-free date: "December 2025" + - Trending indicator (↓ debt is good) + +### Monthly Payment Tracker +- Shows all payments due this month +- Total minimum payment +- Interest accruing +- Next due dates +- Log payment button +- Quick payment logging + +## Integration Points + +**Spending Tracker Integration:** +- Payments appear in spending history +- Compare spending vs. debt payoff payments +- Budget allocation: "You spent $200 on restaurants, could pay debt instead" +- Set debt payoff as spending goal + +**Investment Dashboard Integration:** +- Net worth view: assets - debt = net worth +- "Paying off debt faster than investments growing" +- Prioritization: "Pay 8% interest debt before 3% return on bonds" + +**Accountability Network:** +- Share debt payoff goal with accountability partner +- "Let's both be debt-free by 2025" +- Partner sees progress (not specific debts unless shared) +- Mutual accountability and celebration + +**Financial Dashboard (Future):** +- Combined view: spending, savings, investments, debt +- Overall financial health score +- Recommended debt payoff strategy considering all finances + +**Savings Goals Integration:** +- Emergency fund goal + debt payoff goal balance +- "Allocate 70% to debt, 30% to savings" + +## Success Criteria + +- Adding debt takes <2 minutes +- Progress is always visible and motivating +- Payoff strategy is clear and easy to follow +- Monthly interest calculations are accurate +- Milestones celebrate progress without shame +- Users feel motivated to accelerate payoff +- Integration with spending/savings is seamless + +## Technical Considerations + +- Interest calculation (compound interest formulas) +- Payoff date projections +- Strategy optimization (snowball vs. avalanche calculations) +- Payment tracking and history +- Net worth tracking (daily snapshots) +- Monthly interest accrual calculations + +## Error Handling + +- Invalid interest rates: validate 0-30% range +- Negative balances: prevent, but allow overpayment +- Duplicate debts: warn user +- Payment amounts: validate positive numbers +- Future due dates: warn if past due + +## Motivational Elements + +- Positive language: "You've paid off $X" not "You owe $Y" +- Celebration for milestones (no judgment for late payoff) +- Interest savings highlighted (motivation to accelerate) +- Progress always visible (not hidden until goal) +- Debt-free date countdown + +## Privacy Considerations + +- Sensitive debt information (account numbers, balances) +- Store last 4 digits of account only (not full numbers) +- Sharing with accountability partner is optional +- No public debt disclosures + +## Related Features + +- Spending Tracker: shows spending patterns affecting payoff +- Savings Goals: balance between saving and paying debt +- Investment Dashboard: net worth calculation +- Accountability Network: shared payoff goals +- Financial Dashboard: comprehensive financial view + +## Open Questions + +1. Should we suggest minimum payment adjustments? +2. Should we integrate with banking APIs for auto-payment import? +3. Should we track credit score impact (informational)? +4. Should we provide educational resources on debt reduction? +5. Should we support payment automation (recurring payments)? diff --git a/.claude/ideas/dashboard/011-creative-metrics.md b/.claude/ideas/dashboard/011-creative-metrics.md new file mode 100644 index 000000000..1dea32c7d --- /dev/null +++ b/.claude/ideas/dashboard/011-creative-metrics.md @@ -0,0 +1,375 @@ +# 011 - Creative Metrics + +## Overview +A creative productivity tracker that measures output across various creative disciplines: writing (words), design (projects), music (tracks), video (hours), photography (photos), art (pieces), etc. Provides streak tracking, monthly/annual productivity metrics, burnout detection, creative flow visualization, and integration with portfolio and accountability network for motivation and accountability. + +## Purpose & Goals +- Track creative output in measurable ways +- Celebrate consistent creative practice and productivity +- Detect burnout patterns (declining productivity, creative blocks) +- Maintain momentum through visible progress +- Support creative goals (write a novel, produce an album, etc.) +- Enable accountability with creative partners +- Show creative evolution over time +- Provide motivation through streaks and milestones + +## Key User Flows + +### 1. Log Creative Output +- User logs creative work as it's completed +- Quick entry: + - Creative type (writing, design, music, video, photography, art, etc.) + - Amount/metric (words, projects, tracks, hours, photos, pieces) + - Title/description (optional) + - Notes (mood, tools used, inspiration) + - Time spent (optional) +- Can be quick (tags + number) or detailed (full metadata) +- Entries appear in activity log and timeline + +### 2. Creative Dashboard Overview +- Monthly creative output at a glance +- Total words written, designs completed, etc. +- "This month: 12,000 words written, 3 designs completed" +- Daily streak: "15 days of consistent creative output" +- Compared to last month: "+20% more productive" + +### 3. Creative by Type +- Separate metrics for each creative discipline +- Writing: "2,000 words/day average, 40,000 words this month" +- Design: "3 projects completed, average 2 days per project" +- Music: "4 tracks produced, 16 hours spent" +- Photography: "200 photos taken, 12 edited and posted" +- Video: "3 videos edited, 8 hours of content created" +- Art: "5 pieces completed, mixed media focus" + +### 4. Streaks & Consistency +- Consecutive days of creative output +- "15-day creative streak 🔥" +- Streak reset tracking (when was last break?) +- Motivation: "Keep the streak alive!" +- Historical streaks (longest, this year, etc.) + +### 5. Creative Flow Detection +- Identify most productive times of day +- "You write most between 10am-1pm" +- "Design momentum peaks on Wednesday afternoons" +- Suggest optimal creative times +- Track energy/mood during creative work +- Detect burnout: declining output, longer hours for same output + +### 6. Creative Goals +- "Write 50,000 words this month (NaNoWiMo)" +- "Complete 5 design projects" +- "Finish music album (12 tracks)" +- Progress toward goals displayed prominently +- Pacing suggestions: "3,333 words/day to hit goal" +- Countdown to deadline + +### 7. Creative Milestones +- Words written: "100k lifetime", "Wrote my first novel" +- Projects: "Completed 50 design projects" +- Songs: "Produced 20 tracks" +- Streak milestones: "30-day creative streak" +- Time invested: "1,000 hours total creative practice" + +### 8. Burnout Detection & Rest Days +- System notices: "You've been averaging 6 hours/day. Time for a break?" +- Track quality alongside quantity: "Fewer hours but higher quality" +- Rest days are celebrated: "You took a well-deserved break" +- No guilt culture: creative rest is productive +- Suggestions for refreshing creativity + +## Data Model + +```typescript +interface CreativeSession { + id: string + userId: string + creativeType: CreativeType // "writing", "design", "music", "video", "photography", "art" + date: DateTime + dateLogged: DateTime // When user logged this + + // Metrics (vary by type) + metricsData: { + type: CreativeType + value: number // 2000 words, 1 project, 3 hours, 50 photos, etc. + unit: string // "words", "projects", "hours", "photos", etc. + } + + timeSpent?: number // in minutes + title?: string // "Chapter 5 - The Journey", "Mobile app redesign" + description?: string + notes?: string // mood, tools, inspiration + + // Session metadata + mood?: 1 | 2 | 3 | 4 | 5 // How did you feel? + energy?: 1 | 2 | 3 | 4 | 5 // Creative energy level + tools?: string[] // Software used: ["Figma", "Procreate", "Logic Pro"] + tags?: string[] // Project tags, styles, genres + + // Quality rating + qualityRating?: 1 | 2 | 3 | 4 | 5 // How satisfied? + + linkedProject?: string // Portfolio projectId if portfolio integration + + createdAt: DateTime + updatedAt: DateTime +} + +type CreativeType = "writing" | "design" | "music" | "video" | "photography" | "art" | "other" + +interface CreativeMetrics { + userId: string + period: "day" | "week" | "month" | "year" | "alltime" + creativeType: CreativeType + totalOutput: number + totalTimeSpent: number // minutes + sessionCount: number + averageSessionLength: number + averageQuality: number + bestDay: DateTime + bestSession: CreativeSession +} + +interface CreativeStreak { + userId: string + currentStreakDays: number + longestStreakDays: number + currentStreakStart: DateTime + longestStreakStart: DateTime + longestStreakEnd: DateTime + streakBroken: boolean +} + +interface CreativeGoal { + id: string + userId: string + creativeType: CreativeType + goalDescription: string // "Write 50,000 words" + targetValue: number + currentValue: number // auto-synced + deadline: DateTime + status: "active" | "completed" | "failed" + suggestedDailyPace: number + createdAt: DateTime +} + +interface BurnoutIndicator { + userId: string + averageHoursPerDay: number + qualityTrend: "improving" | "stable" | "declining" + streakStatus: "active" | "broken_recently" + lastBreakDate?: DateTime + daysSinceBreak: number + burnoutRisk: "low" | "medium" | "high" + recommendations: string[] + lastUpdated: DateTime +} +``` + +## UI Components + +### Quick Creative Log Card +- Floating action button or quick-add from any page +- Minimal form: + - Creative type selector (dropdown or tabs) + - Amount input (words, projects, etc.) + - Title input (optional) + - Time spent input (optional) + - Notes textarea (optional) + - Submit button +- Takes <1 minute to log +- Can be logged retroactively + +### Creative Dashboard Page +- Tabs: Overview | By Type | Streaks | Goals | Analysis | Milestones +- Overview tab: + - Large display: "This month: 12,000 words | 3 designs | 8 hours music" + - Sparkline showing daily output this month + - Current streak: "15 days 🔥" + - Compared to last month: "+20% more productive" + - Mood/energy breakdown + - Quality trend (is work getting better or worse?) + - Quick log button +- By Type tab: + - Each creative discipline gets its own section + - Writing: + - Words written: "2,000 words/day average" + - Monthly total: "40,000 words" + - Best writing time: "10am-1pm" + - Recent sessions list + - Design: projects, average time per project, best design day + - Music: tracks produced, average track length, genres used + - Photography: photos taken/edited, collection breakdown + - Video: video hours, number of projects, average length + - Art: pieces created, mediums used, collection growth +- Streaks tab: + - Current streak display: "15 consecutive days" + - Streak calendar (heatmap showing consistent days) + - Longest streak ever: "32 days" + - Streak recovery: "Broke streak 2 weeks ago, rebuild in progress" + - Motivational messages +- Goals tab: + - Active creative goals with progress + - "Write 50,000 words: 35,000/50,000 (70%)" + - Deadline countdown + - Pacing suggestion: "Write 3,333 words/day to hit goal" + - Time remaining + - Completed goals (archive) +- Analysis tab: + - Most productive times (heatmap by hour of day) + - Best days of week for creativity + - Mood vs. output correlation + - Quality trend (improving/stable/declining) + - Seasonal patterns (monthly breakdown) + - Burnout risk assessment +- Milestones tab: + - Recent milestone celebrations + - Lifetime metrics: "100k words written", "50 designs completed" + - Streak achievements: "30-day streak" + - Annual summary: "Wrote 200k words this year" + +### Creative Type Widget +- Shows selected creative type's metrics +- "Writing: 40,000 words this month" +- Sparkline for last 30 days +- Streak indicator +- Quick log button + +### Streak Visualization +- Calendar heatmap showing consistency +- Green = creative session that day +- Darker green = longer/more productive session +- Gray = no session +- Current streak highlighted +- Motivational phrase: "Keep it up!" "You're on fire!" + +### Creative Goal Card +- Goal title and type +- Large progress bar +- Current value / target +- Days remaining +- Daily pace needed +- "You need 3,333 words/day to finish" +- Completion estimate + +### Burnout Detection Alert +- If system detects burnout risk: + - "You've been working 6+ hours daily for 2 weeks" + - "Time for a creative break?" + - Suggestion: "Rest days are productive too" +- Option to plan a break day +- Normalize rest as part of creative process + +### Quality Analysis +- Graph showing quality ratings over time +- Correlation with hours spent (diminishing returns?) +- Best quality work times +- Suggestions: "Your best work is 2-3 hour sessions" + +### Milestones Archive +- Chronological list of all milestones achieved +- "200k words written - March 2024" +- "Completed 50 design projects - June 2024" +- "30-day creative streak - February 2025" +- Shareable milestone cards + +## Integration Points + +**Portfolio System:** +- Creative projects auto-appear in portfolio +- "Completed design project: X" = portfolio project +- Creative metrics show in portfolio: "200 designs completed, 8,000 hours" +- Link creative goals to portfolio milestones + +**Skill Leveling System:** +- Creative practice counts as skill advancement +- "Design skill: 50 projects → Advanced level" +- "Writing skill: 200k words → Advanced level" +- Tool proficiency: "Figma: 8 projects → Expert" + +**Accountability Network:** +- Share creative goals with accountability partner +- "Let's both write 50k words this month" +- Partner sees progress (motivational) +- Shared creative challenges: "Produce a song together" +- Celebrate milestones together + +**Activity Log:** +- Creative sessions appear as major activities +- "Wrote 5,000 words", "Designed new app mockup" +- Timeline shows creative productivity +- Correlated with mood/energy + +**Mood & Energy Tracker:** +- Log mood before/after creative session +- Creativity can energize or drain +- Suggest creative time when mood/energy is good +- Correlation: "Creative time improves your mood" + +## Success Criteria + +- Creative logging takes <1 minute +- Streaks are motivating without guilt on breaks +- Output metrics are accurate and clear +- Goals feel achievable and trackable +- Burnout is detected and addressed supportively +- Users celebrate creative milestones +- Accountability partners keep each other motivated + +## Technical Considerations + +- Flexible metrics system (words, projects, hours, photos, etc.) +- Streak calculations and reset logic +- Quality rating aggregation +- Burnout detection algorithm +- Productivity trend analysis +- Time zone aware date boundaries +- Historical data for annual reviews + +## Error Handling + +- Invalid output amounts: validate positive numbers +- Invalid creative types: suggest existing types +- Duplicate entries same day: allowed (multiple sessions) +- Quality ratings optional +- Time spent optional (can be empty) + +## Motivational Principles + +- Celebrate consistency over quantity +- Rest days are encouraged, not penalized +- Quality matters more than volume long-term +- Streaks are motivating but not mandatory +- Burnout recognition and prevention important +- Share milestones, not compare raw numbers + +## Privacy Considerations + +- Creative work details shareable (with control) +- Don't expose full creative output to public +- Can choose what appears in portfolio +- Quality ratings are personal feedback only + +## Creative Tools Integration (Future) + +- Integration with writing software (Word, Notion, Scrivener) +- Design app integration (Figma, Adobe Creative Cloud) +- Music DAW integration (Logic, Ableton, FL Studio) +- Auto-logging creative output from these apps + +## Related Features + +- Portfolio: showcases creative work +- Skill Leveling: levels up based on creative practice +- Accountability Network: shared creative goals +- Activity Log: creative sessions in timeline +- Mood Tracker: mood impact of creativity + +## Open Questions + +1. Should we integrate with creative apps for auto-logging? +2. Should we allow collaborative creative tracking? +3. Should we provide writing/design prompts for inspiration? +4. Should we track creative income earned? +5. Should we show collaboration on projects? diff --git a/.claude/ideas/dashboard/012-event-coordination-hub.md b/.claude/ideas/dashboard/012-event-coordination-hub.md new file mode 100644 index 000000000..c577c5a3a --- /dev/null +++ b/.claude/ideas/dashboard/012-event-coordination-hub.md @@ -0,0 +1,414 @@ +# 012 - Event Coordination Hub + +## Overview +A collaborative event planning and coordination system that enables users to organize gatherings, manage attendees, coordinate logistics, track expenses, and capture memories. Integrates with accountability partners, relationship calendar, and activity log to create a complete event lifecycle experience from planning through post-event reflection. + +## Purpose & Goals +- Simplify event planning and coordination +- Enable collaborative planning with friends and accountability partners +- Track event expenses and participant contributions +- Manage attendee RSVPs and preferences +- Coordinate logistics: location, time, materials, tasks +- Capture and share event memories +- Enable post-event reflection and feedback +- Connect events to relationships and social goals + +## Key User Flows + +### 1. Create Event +- User creates event with details: + - Event name ("Birthday party for James", "Group hike", "Book club meeting") + - Description and purpose + - Date and time (or time range for flexibility) + - Location + - Event type (birthday, gathering, trip, celebration, activity, etc.) + - Estimated attendee count + - Invite list (select from contacts/accountability partners) + - Special details (dietary restrictions, skill levels, etc.) +- System generates event page with RSVP link + +### 2. RSVP & Attendee Management +- Invitees receive invite (in-app or email) +- Can RSVP: Yes, No, Maybe, with optional message +- Attendees see updated attendee list (privacy: name only or full details?) +- Organizer can see dietary restrictions, special needs +- Reminder notifications for pending RSVPs +- Final headcount for planning + +### 3. Event Coordination +- To-do list for event preparation +- Divided by category: setup, food, activities, logistics +- Task assignment to volunteers +- Progress tracking (% complete) +- Collaborative checklist (anyone can update) +- Shared notes and planning documents +- Decision tracking: "Voted: pizza vs. sandwiches" + +### 4. Expense Tracking +- Log event expenses as incurred +- "Purchased decorations: $25" +- "Pizza delivery: $80" +- Track who paid for what +- Calculate per-person cost +- Show who owes whom money +- Optional: expense splitting calculator +- Settlement tracking: who paid back + +### 5. Event Day Timeline +- Shared timeline showing schedule +- Arrival times and guest activities +- Real-time updates: "Sarah just arrived" +- Photo uploads during event +- Comments and reactions +- Event highlights captured + +### 6. Post-Event Memories +- Photo gallery from event +- Video clips/moments +- Guest contributions (photos attendees took) +- Event recap: highlights and key moments +- Guest feedback/testimonials +- Memory archive for later viewing + +### 7. Event Reflection & Feedback +- Quick survey: "How was the event?" (rating + optional comment) +- "What was your favorite part?" +- Photo highlights: best moments +- Budget review: actual vs. planned +- Lessons learned: "Next time do X differently" +- Archive successful events as templates + +## Data Model + +```typescript +interface Event { + id: string + organizerId: string // User who created event + title: string + description?: string + eventType: EventType // "birthday", "gathering", "trip", "celebration", "activity", "meeting", "other" + startDate: DateTime + endDate?: DateTime // For multi-day events + location?: string + address?: string // Full address for mapping + + // Attendees + invitees: string[] // User IDs or emails + attendees: Array<{ + userId: string + rsvpStatus: "yes" | "no" | "maybe" + rsvpDate: DateTime + dietaryRestrictions?: string + specialNeeds?: string + notes?: string + }> + expectedAttendeeCount?: number + + // Planning + isPublic: boolean // Visible to all invited or private + isSharedEvent: boolean // With accountability partners + collaborators: string[] // Other organizers + + // Timeline + createdAt: DateTime + updatedAt: DateTime + status: "planning" | "confirmed" | "active" | "completed" | "canceled" +} + +type EventType = "birthday" | "gathering" | "trip" | "celebration" | "activity" | "meeting" | "other" + +interface EventTask { + id: string + eventId: string + title: string + description?: string + category: "setup" | "food" | "activities" | "logistics" | "cleanup" + assignedTo?: string // userId + dueDate?: DateTime + isCompleted: boolean + completedBy?: string + completedAt?: DateTime + subtasks?: Array<{ + title: string + isCompleted: boolean + }> + priority: "low" | "medium" | "high" + createdAt: DateTime +} + +interface EventExpense { + id: string + eventId: string + description: string + amount: number + paidBy: string // userId + date: DateTime + category: "food" | "decorations" | "venue" | "entertainment" | "other" + attendeesInvolved?: string[] // Who to split cost among + notes?: string + receipt?: string // URL to receipt photo + createdAt: DateTime +} + +interface EventMemory { + id: string + eventId: string + type: "photo" | "video" | "note" | "testimonial" + content: string // File URL or text content + uploadedBy: string // userId + caption?: string + timestamp?: DateTime // When during event + likes?: string[] // userIds who liked + comments?: Array<{ + userId: string + text: string + timestamp: DateTime + }> + isHighlight: boolean // Feature as key memory + createdAt: DateTime +} + +interface EventFeedback { + id: string + eventId: string + userId: string // Who gave feedback + rating: 1 | 2 | 3 | 4 | 5 + favoritePartResponse?: string + lessonsLearned?: string + wouldAttendAgain?: boolean + notes?: string + submittedAt: DateTime +} + +interface EventTemplate { + id: string + userId: string + basedOnEventId?: string + name: string // "Birthday party template" + defaultTasks: string[] // Task list copied from template + defaultExpenses?: Array<{ description: string, estimatedAmount: number }> + notes?: string +} +``` + +## UI Components + +### Create Event Modal +- Multi-step form (or single scrolling) +- Step 1: Basic info (title, type, date, time, location) +- Step 2: Invite attendees (select from contacts, email addresses) +- Step 3: Special details (dietary, accessibility, notes) +- Step 4: Review and create +- Preview of event page before publishing +- Save as template option + +### Event Detail Page +- Event header: title, date, time, location +- Tabs: Overview | Attendees | Planning | Expenses | Gallery | Feedback +- Overview tab: + - Event description + - Countdown to event + - RSVP status (Yes: 12, Maybe: 3, No: 2) + - Quick stats: confirmed attendees, total expenses so far + - Collaborative planning status + - Share event link button +- Attendees tab: + - List of invited guests + - RSVP status for each + - Accept/remind buttons for pending responses + - Attendee notes: dietary restrictions, special needs + - Filter by RSVP status + - Export attendee list +- Planning tab: + - Collaborative to-do checklist + - Grouped by category (setup, food, activities, cleanup) + - Each task shows: + - Task name and description + - Assigned to (person or "Volunteer needed") + - Due date + - Completion status + - Subtasks + - Mark complete button + - Priority indicators + - Progress bar: X of Y tasks complete + - Shared notes/documents + - Voting on decisions: "Pizza vs. sandwiches" +- Expenses tab: + - List of all expenses logged + - Each shows: description, amount, paid by, category + - Total event cost + - Per-person split + - Who owes whom (if uneven contribution) + - Add expense button + - Settlement tracker + - Budget vs. actual (if budget set) +- Gallery tab: + - Photo grid of all event memories + - Uploaded by (credit photographer) + - Chronological or highlight-first view + - Add/upload more photos button + - Comments on photos + - Mark as favorite/highlight + - Archive/delete photos + - Create slideshow +- Feedback tab: + - Survey results (if event completed) + - Ratings breakdown + - Feedback comments + - Lessons learned + - Would attend again % (if celebration type) + +### Attendee Card +- Name/avatar +- RSVP status (Yes 🟢, No 🔴, Maybe 🟡) +- Date RSVPed +- Dietary restrictions/special needs shown +- Quick message button +- Remind button (if no RSVP) + +### Event Task Card +- Task title and description +- Category badge +- Assigned to (or "Need volunteer") +- Due date and priority indicator +- Completion checkbox +- Progress on subtasks (3/5 done) +- Click to expand and see details +- Comments/notes section + +### Expense Tracker +- Running total prominently displayed +- Table of all expenses: + - Description + - Amount + - Paid by (person avatar) + - Category + - Date +- Add expense button +- Settlement summary: + - Per-person split + - Who paid extra/is owed + - "You paid $50 extra" or "You owe $10" + +### Event Timeline/Gallery +- Chronological view of photos/videos +- Each item shows upload time and photographer +- Ability to comment and like +- Highlight key moments +- Create gallery/slideshow view +- Download/share option + +### Post-Event Feedback Modal +- Quick survey after event: + - "How was the event?" (5-star rating) + - "What was your favorite part?" (open text) + - "Would you attend again?" (yes/no) + - "Any suggestions for next time?" (open text) +- Optional: submit feedback button +- Skip option + +### Event Widget +- Dashboard shows upcoming events +- "Next event: Sarah's birthday - June 15" +- Your tasks pending +- Pending RSVPs to send +- Link to event details + +### Event Calendar View +- Monthly calendar showing all events +- Different colors for event types +- Click event to view details +- Quick RSVP button +- Attendee count shown +- Countdown to upcoming events + +## Integration Points + +**Relationship Calendar:** +- Events linked to people you care about +- Birthday events auto-created (reminder to plan) +- Event attendees appear in relationship calendar +- Post-event: contact logged as "met for [event]" + +**Accountability Network:** +- Create shared events with accountability partner +- "Let's plan a group hike together" +- Partner sees event and can co-organize +- Collaborative planning between partners + +**Activity Log:** +- Event attendance logged as major activity +- "Attended Sarah's birthday party" +- Photos appear in activity timeline +- Event memories integrated + +**Spending Tracker:** +- Event expenses appear in spending history +- "Event expenses: $120" aggregated +- Can allocate spending to savings goals +- Budget planning connected to spending goals + +**Calendar Integration:** +- Events appear in main dashboard calendar +- Optional: sync to Google Calendar/Apple Calendar +- Reminders and notifications + +## Success Criteria + +- Event creation takes <5 minutes +- Collaboration is intuitive for multiple organizers +- Expense tracking is simple and accurate +- RSVP process is easy for attendees +- Photo sharing and memories are seamless +- Post-event feedback is captured for improvement +- Users feel connected through shared event experience + +## Technical Considerations + +- Real-time collaboration (WebSocket for live updates) +- Event invitation system (email + in-app) +- Expense calculation and splitting +- Photo upload and storage optimization +- Comment/like real-time updates +- Calendar integration APIs +- Notification system for RSVPs, tasks, reminders + +## Error Handling + +- Invalid dates prevented (past dates, end before start) +- RSVP duplicates: update existing not create new +- Expense math: validate positive amounts +- Attendee deletion: confirm before removing +- Event cancellation: notify all attendees +- Image upload: size/format validation + +## Privacy Considerations + +- Attendee lists visible only to invited +- Shared event data limited (attendees, photos, feedback) +- Can control photo visibility (private/attendees only/public) +- Budget details visible only to organizer/co-organizers +- Dietary restrictions visible only to organizers + +## Gamification Elements (Optional) + +- Event planning streaks: consecutive events organized +- "Party planner" badge for hosting events +- Photo upload achievements: "Captured the moment" +- Expense splitter hero: managed complex splits perfectly + +## Related Features + +- Relationship Calendar: event planning for important people +- Accountability Network: collaborative event planning +- Activity Log: event attendance and memories +- Spending Tracker: event expenses and budgeting +- Mood & Energy: social events affect mood/energy + +## Open Questions + +1. Should we support calendar-style scheduling tools (drag to reschedule)? +2. Should we have a shared wishlist for gift events? +3. Should we provide venue/vendor recommendations? +4. Should we integrate with food delivery services for catering? +5. Should we support event mapping (guest travel times)? diff --git a/.claude/plans/2026-01-10-Dashboard.md b/.claude/plans/2026-01-10-Dashboard.md new file mode 100644 index 000000000..3e28391fa --- /dev/null +++ b/.claude/plans/2026-01-10-Dashboard.md @@ -0,0 +1,485 @@ +## Project Overview + +Create a personal dashboard application as a monorepo with: + +- **Web App**: TanStack Start with WorkOS authentication, cyberpunk-themed UI +- **Server**: Nitro-based API with WebSocket support for real-time sync +- **Shared Package**: Common utilities for both web and server +- **Timer Feature**: Recreate the CHRONO timer (cyberpunk multi-timer) in React + +## Design Decisions + +- **Existing apps**: Keep docs/, move web-template/ to __unused_web-template/ +- **Timer storage**: Both localStorage (offline) + server persistence via WebSocket +- **Auth UI**: Cyberpunk theme ported from Rewind (neon/glassmorphism) + +## Architecture + +``` +src/dashboard/ +├── __unused_web-template/ # Archived Next.js template (for reference) +├── apps/ +│ ├── docs/ # Keep existing docs app +│ ├── web/ # TanStack Start app (from decide/tanstack-start/) +│ │ ├── src/ +│ │ │ ├── routes/ +│ │ │ │ ├── __root.tsx +│ │ │ │ ├── index.tsx +│ │ │ │ ├── timer/ +│ │ │ │ │ └── index.tsx # Timer page +│ │ │ │ ├── auth/ +│ │ │ │ │ ├── signin.tsx +│ │ │ │ │ ├── signup.tsx +│ │ │ │ │ ├── forgot-password.tsx +│ │ │ │ │ └── reset-password.tsx +│ │ │ │ └── (protected)/ # Auth-required routes +│ │ │ ├── components/ +│ │ │ │ ├── timer/ # Timer components +│ │ │ │ └── auth/ # Auth components +│ │ │ └── lib/ +│ │ └── .env.local +│ │ +│ └── server/ # Nitro server +│ ├── routes/ +│ │ ├── api/ +│ │ │ ├── health.ts +│ │ │ ├── timer/[id].ts +│ │ │ └── user/index.ts +│ │ └── _ws.ts # WebSocket handler +│ ├── utils/ +│ └── nitro.config.ts +│ +└── packages/ + ├── shared/ # Shared utilities + │ ├── src/ + │ │ ├── types/ + │ │ ├── utils/ + │ │ └── constants/ + │ └── package.json + ├── ui/ # Existing - will extend + ├── eslint-config/ + ├── typescript-config/ + └── tailwind-config/ +``` + +## Implementation Phases + +### Phase 0: Branch Creation & Initial Commit ✓ + +**Status**: User already created turborepo in src/dashboard/ + +1. Create feature/dashboard branch +2. Commit existing turborepo structure with `feat(dashboard): Init turborepo` + +### Phase 1: TanStack Start Setup + +**Files to copy**: `decide/tanstack-start/` → `src/dashboard/apps/web/` + +1. Copy entire decide/tanstack-start/ to apps/web/ +2. Update package.json name to `@dashboard/web` +3. Configure workspace references +4. Copy WorkOS env variables from Rewind project: +5. Commit with `feat(dashboard): Init tanstack-start project in turborepo` + +### Phase 2: Shared Package + +**Location**: `src/dashboard/packages/shared/` + +Create shared utilities package with: + +- Timer types and interfaces +- Common constants +- Utility functions (time formatting, etc.) +- Zod schemas for validation + +```typescript +// packages/shared/src/types/timer.ts +export interface Timer { + id: string + name: string + type: 'stopwatch' | 'countdown' + isRunning: boolean + pausedTime: number + countdownDuration: number + laps: number[] + // ... more fields +} +``` + +### Phase 3: Nitro Server Setup + +**Location**: `src/dashboard/apps/server/` + +Initialize Nitro server with: + +```bash +cd src/dashboard/apps/server +bunx giget nitro . +``` + +**Routes to create**: + +- `GET /api/health` - Health check +- `GET /api/timers` - List timers (from DB/localStorage sync) +- `POST /api/timers` - Create timer +- `PUT /api/timers/:id` - Update timer +- `DELETE /api/timers/:id` - Delete timer +- `GET /api/user` - Get current user (WorkOS session) +- `POST /api/auth/verify` - Verify WorkOS token + +**WebSocket handler** (`_ws.ts`): + +- Real-time timer sync across clients +- Presence awareness +- Timer state broadcasting + +### Phase 4: Authentication System (Cyberpunk Theme) + +Adapt Rewind auth patterns for TanStack Start with full cyberpunk styling: + +**Key differences from Next.js**: + +- TanStack Start uses AuthKit-React provider (already in template) +- No server actions - use API routes instead +- Client-side form handling with TanStack Form + +**Routes to create**: + +- `/auth/signin` - Email/password + OAuth login +- `/auth/signup` - Registration with verification +- `/auth/forgot-password` - Password reset request +- `/auth/reset-password` - Complete password reset +- `/auth/callback` - OAuth redirect handler +- `/auth/error` - Auth error display + +**Cyberpunk UI Elements to Port from Rewind**: + +- Glass-morphism cards with backdrop blur +- Neon glow effects (amber, cyan) +- Animated gradient orbs (`animate-pulse`) +- Cyber grid background with scan lines +- Time ripple animations +- Tech corner decorations +- Gradient text for branding + +**Components to adapt from Rewind**: + +- `email-verification-form.tsx` - OTP input with cyberpunk styling +- `error-page.tsx` - Auth error with glitch effects +- Auth layout with animated background + +### Phase 5: Timer Feature + +**Location**: `src/dashboard/apps/web/src/routes/timer/` + +Recreate CHRONO timer in React with full server sync: + +**Core Components**: + +``` +timer/ +├── index.tsx # Timer page route +├── components/ +│ ├── TimerCard.tsx # Individual timer +│ ├── TimerDisplay.tsx # Time display with glow +│ ├── TimerControls.tsx # Start/Pause/Lap/Reset +│ ├── TimerTypeSwitch.tsx # Stopwatch/Countdown toggle +│ ├── LapsContainer.tsx # Lap history +│ ├── CountdownInput.tsx # Duration input +│ └── EmptyState.tsx # No timers message +├── hooks/ +│ ├── useTimer.ts # Timer logic hook +│ ├── useTimerStore.ts # TanStack Store for state management +│ ├── useTimerCollection.ts # PowerSync collection queries +│ └── usePowerSync.ts # PowerSync connection management +├── lib/ +│ ├── timer-engine.ts # RAF-based tick engine +│ └── time-utils.ts # Formatting functions +└── styles.css # Cyberpunk CSS +``` + +**Key Features to Implement**: + +1. Multiple timers with unique IDs +2. Stopwatch (count up) and Countdown (count down) modes +3. Start/Pause/Reset/Lap controls +4. Pop-out window mode (`?timer={id}`) +5. Offline-first with SQLite (PowerSync) +6. Automatic bi-directional sync across devices (PowerSync) +7. Countdown completion flash animation +8. Cyberpunk UI with neon glow effects + +**Sync Architecture** (using TanStack Store + PowerSync): + +- TanStack Store for reactive state management +- PowerSync for offline-first SQLite persistence with automatic sync +- Optimistic updates with automatic rollback on sync errors +- Real-time bi-directional sync across devices +- User-scoped timers (requires authentication) + +**PowerSync Setup**: + +```typescript +// src/db/powersync.ts +import { PowerSyncDatabase, Schema, Table, column } from '@powersync/web' +import '@journeyapps/wa-sqlite' + +export const APP_SCHEMA = new Schema({ + timers: new Table({ + name: column.text, + type: column.text, // 'stopwatch' | 'countdown' + is_running: column.integer, // boolean as 0/1 + paused_time: column.integer, + countdown_duration: column.integer, + laps: column.text, // JSON stringified array + user_id: column.text, + created_at: column.text, + updated_at: column.text, + }), +}) + +export const db = new PowerSyncDatabase({ + database: { dbFilename: 'dashboard.sqlite' }, + schema: APP_SCHEMA, +}) +``` + +**TanStack DB Collection with PowerSync**: + +```typescript +// src/db-collections/timers.ts +import { createCollection } from '@tanstack/react-db' +import { powerSyncCollectionOptions } from '@tanstack/powersync-db-collection' +import { z } from 'zod' +import { db, APP_SCHEMA } from '../db/powersync' + +const timerSchema = z.object({ + id: z.string(), + name: z.string(), + type: z.enum(['stopwatch', 'countdown']), + is_running: z.number().transform(val => val > 0), // SQLite int → boolean + paused_time: z.number(), + countdown_duration: z.number(), + laps: z.string().transform(val => JSON.parse(val || '[]')), // JSON → array + user_id: z.string(), + created_at: z.string().transform(val => new Date(val)), + updated_at: z.string().transform(val => new Date(val)), +}) + +export const timersCollection = createCollection( + powerSyncCollectionOptions({ + database: db, + table: APP_SCHEMA.props.timers, + schema: timerSchema, + serializer: { + is_running: (val: boolean) => val ? 1 : 0, + laps: (val: number[]) => JSON.stringify(val), + created_at: (val: Date) => val.toISOString(), + updated_at: (val: Date) => val.toISOString(), + }, + }) +) +``` + +**PowerSync Backend Connector** (for server sync): + +```typescript +// src/db/powersync-connector.ts +import { PowerSyncBackendConnector, PowerSyncCredentials } from '@powersync/web' + +export class DashboardConnector implements PowerSyncBackendConnector { + async fetchCredentials(): Promise { + // Get token from WorkOS session and exchange for PowerSync credentials + const response = await fetch('/api/auth/powersync-token') + return response.json() + } + + async uploadData(database: AbstractPowerSyncDatabase): Promise { + // Upload pending changes to Nitro server + const batch = await database.getCrudBatch(100) + if (batch) { + await fetch('/api/sync/upload', { + method: 'POST', + body: JSON.stringify(batch.crud), + }) + await batch.complete() + } + } +} +``` + +### Phase 6: Tailwind Configuration + +Copy and adapt from Rewind: + +``` +Rewind/apps/timetravel-web/tailwind.config.js → src/dashboard/apps/web/tailwind.config.ts +``` + +**Custom classes needed for timer**: + +- `.glass-card` - Glassmorphism +- `.neon-amber`, `.neon-cyan` - Glow effects +- `.cyber-grid`, `.scan-lines` - Background effects +- Animation keyframes: `fadeInUp`, `pulseGlow`, `flash`, `flicker` + +### Phase 7: Frontend Routes + +Create additional dashboard routes: + +- `/` - Dashboard home +- `/timer` - Timer application +- `/settings` - User settings +- `/profile` - User profile + +## Critical Files Reference + +### From Rewind (Auth): + +- `/Users/Martin/Tresors/Projects/Rewind/apps/timetravel-web/lib/actions/auth.ts` +- `/Users/Martin/Tresors/Projects/Rewind/apps/timetravel-web/lib/auth.ts` +- `/Users/Martin/Tresors/Projects/Rewind/apps/timetravel-web/components/auth/email-verification-form.tsx` +- `/Users/Martin/Tresors/Projects/Rewind/apps/timetravel-web/app/(auth)/*.tsx` + +### From TanStack Start Template: + +- `/Users/Martin/Tresors/Projects/GenesisTools/decide/tanstack-start/src/integrations/workos/provider.tsx` +- `/Users/Martin/Tresors/Projects/GenesisTools/decide/tanstack-start/src/components/workos-user.tsx` +- `/Users/Martin/Tresors/Projects/GenesisTools/decide/tanstack-start/src/routes/demo/workos.tsx` + +### Timer Reference: + +- Download and save to: `src/dashboard/timer/index.static.html` +- Source: [https://foltyn.dev/timer/index.html](https://foltyn.dev/timer/index.html) +- Use `curl -o src/dashboard/timer/index.static.html https://foltyn.dev/timer/index.html` + +# AI (optional) + +ANTHROPIC_API_KEY= + +``` + +### apps/server/.env +```env +WORKOS_API_KEY= +PORT=4000 +``` + +## CLAUDE.md Updates + +Add to project CLAUDE.md: + +```markdown +## Context7 Documentation References + +When working with the dashboard project, use these context7 library IDs for documentation: + +- **TanStack Start**: `/websites/tanstack_start_framework_react` +- **TanStack Start + WorkOS Auth**: `/workos/authkit-tanstack-start` +- **Motia (Backend framework)**: `/motiadev/motia` +- **shadcn/ui components**: `/websites/ui_shadcn` +- **Turborepo**: `/websites/turborepo` +- **TanStack Query**: `/websites/tanstack_query` +- **TanStack DB**: `/tanstack/db` +- **TanStack Router**: `/websites/tanstack_router` + +Use with: `mcp-cli call plugin_context7_context7/query-docs '{"libraryId": "", "topic": "..."}'` + +## PowerSync Documentation + +For offline-first sync with TanStack DB, refer to: +- https://tanstack.com/db/latest/docs/collections/powersync-collection + +Packages: `@tanstack/powersync-db-collection @powersync/web @journeyapps/wa-sqlite` +``` + +## Verification Steps + +1. **Build Check**: `cd src/dashboard && bun run build` +2. **Type Check**: `cd src/dashboard && bun run check-types` +3. **Dev Server**: `cd src/dashboard && bun run dev` +4. **Web App**: Access [http://localhost:3000](http://localhost:3000) +5. **Timer Route**: Access [http://localhost:3000/timer](http://localhost:3000/timer) +6. **Auth Flow**: Test signin/signup/logout +7. **Server API**: Access [http://localhost:4000/api/health](http://localhost:4000/api/health) +8. **WebSocket**: Test timer sync across tabs + +## Commit Sequence + +### Phase 0: Setup + +1. `git checkout -b feature/dashboard` +2. `git add src/dashboard/ && git commit -m "feat(dashboard): Init turborepo"` + +### Phase 1: TanStack Start Setup + +1. Move web-template: `git mv src/dashboard/apps/web-template src/dashboard/__unused_web-template && git commit -m "chore(dashboard): Archive web-template app"` +2. Copy tanstack-start to apps/web/: `git commit -m "feat(dashboard): Copy tanstack-start template to apps/web"` +3. Update package.json name and workspace refs: `git commit -m "chore(dashboard): Configure web app workspace references"` +4. Add .env.local with WorkOS vars: `git commit -m "feat(dashboard): Add WorkOS environment configuration"` + +### Phase 2: Shared Package + +1. Create packages/shared scaffold: `git commit -m "feat(dashboard): Add shared utilities package scaffold"` +2. Add timer types and schemas: `git commit -m "feat(dashboard): Add timer types and Zod schemas"` + +### Phase 3: Nitro Server + +1. Initialize Nitro app: `git commit -m "feat(dashboard): Initialize Nitro server"` +2. Add health and basic API routes: `git commit -m "feat(dashboard): Add server health and user API routes"` +3. Add timer API routes: `git commit -m "feat(dashboard): Add timer CRUD API routes"` +4. Add PowerSync sync endpoints: `git commit -m "feat(dashboard): Add PowerSync sync endpoints"` + +### Phase 4: Authentication + +1. Add auth layout with cyberpunk theme: `git commit -m "feat(dashboard): Add cyberpunk auth layout"` +2. Add signin page: `git commit -m "feat(dashboard): Add signin page with OAuth"` +3. Add signup page: `git commit -m "feat(dashboard): Add signup page with email verification"` +4. Add forgot/reset password pages: `git commit -m "feat(dashboard): Add password reset flow"` +5. Add auth callback handler: `git commit -m "feat(dashboard): Add OAuth callback handler"` + +### Phase 5: Timer Feature + +1. Download static timer reference: `git commit -m "docs(dashboard): Add static timer reference"` +2. Add PowerSync database setup: `git commit -m "feat(dashboard): Add PowerSync database configuration"` +3. Add timer collection with TanStack DB: `git commit -m "feat(dashboard): Add timer PowerSync collection"` +4. Add timer components: `git commit -m "feat(dashboard): Add timer UI components"` +5. Add timer page route: `git commit -m "feat(dashboard): Add timer page with full functionality"` +6. Add cyberpunk timer styles: `git commit -m "style(dashboard): Add cyberpunk timer CSS"` + +### Phase 6: Configuration + +1. Copy and adapt Tailwind config: `git commit -m "chore(dashboard): Configure Tailwind with cyberpunk theme"` + +### Phase 7: Documentation + +1. Update CLAUDE.md: `git commit -m "docs: Add context7 and PowerSync documentation references"` + +## Dependencies to Install + +### apps/web (additional) + +```bash +bun add @tanstack/react-store @tanstack/react-db @tanstack/powersync-db-collection @powersync/web @journeyapps/wa-sqlite iron-session zod +``` + +**Note**: + +- TanStack Store for state management (already in tanstack-start template) +- PowerSync for offline-first SQLite with automatic sync +- @journeyapps/wa-sqlite for WASM SQLite in browser + +### apps/server + +```bash +bun add nitropack @workos-inc/node +``` + +**Note**: Nitro includes `h3` as a core dependency - no need to install separately. WebSocket support is built into Nitro via the `_ws.ts` route convention. + +### packages/shared + +```bash +bun add zod +``` + diff --git a/.claude/plans/2026-01-13-badge-progress-ui.md b/.claude/plans/2026-01-13-badge-progress-ui.md new file mode 100644 index 000000000..0eacea6a3 --- /dev/null +++ b/.claude/plans/2026-01-13-badge-progress-ui.md @@ -0,0 +1,67 @@ +# Badge Progress UI Implementation Plan + +## Overview +Create a badge showcase with earned badges and progress toward new ones for the Personal AI Assistant dashboard. + +## Files to Create + +### 1. `src/routes/assistant/-components/badges/BadgeCard.tsx` +Single badge display with: +- Rarity-colored glow effects +- Badge icon (from Lucide) +- Display name and description +- Earned date for unlocked badges +- Tooltip with badge details +- Legendary badges pulse with gold shimmer + +### 2. `src/routes/assistant/-components/badges/BadgeShowcase.tsx` +Earned badges grid: +- Grid layout for earned badges +- Empty state when no badges earned +- Badge count header +- Filter by rarity option + +### 3. `src/routes/assistant/-components/badges/BadgeProgress.tsx` +Progress bars for in-progress badges: +- Shows badges not yet earned +- Neon-filled progress bars +- Current/target values +- Percentage complete +- Remaining text + +### 4. `src/routes/assistant/-components/badges/BadgeUnlockAnimation.tsx` +Unlock celebration overlay: +- Dialog-based modal +- Confetti particle burst +- Badge flies in animation +- Rarity glow effect +- Dismiss/share buttons + +### 5. `src/routes/assistant/-components/badges/index.ts` +Exports all badge components + +### 6. Update `src/routes/assistant/analytics.tsx` +Add badges section to the analytics page: +- Replace placeholder content +- Add BadgeShowcase for earned badges +- Add BadgeProgress for in-progress badges + +## Rarity Color Scheme +- Common: gray/silver (`gray-400`, `gray-500`) +- Uncommon: green (`green-400`, `green-500`) +- Rare: blue/purple (`purple-400`, `purple-500`) +- Legendary: amber/gold with glow (`amber-400`, `amber-500`) + +## Cyberpunk Aesthetic +- Dark backgrounds with colored glows +- Neon progress bar fills +- Tech corner decorations (like FeatureCard) +- Pulse animations for legendary badges +- Particle burst on unlock + +## Dependencies +- Existing: useBadgeProgress hook +- Existing: Badge, BadgeProgress types +- Existing: BADGE_DEFINITIONS +- Existing: getBadgeRarityColor utility +- Lucide icons for badge icons diff --git a/.claude/plans/2026-01-13-blocker-detector.md b/.claude/plans/2026-01-13-blocker-detector.md new file mode 100644 index 000000000..cec8b429d --- /dev/null +++ b/.claude/plans/2026-01-13-blocker-detector.md @@ -0,0 +1,77 @@ +# Blocker Detector Implementation Plan + +## Overview +Implement a blocker detection and tracking system for the Personal AI Assistant dashboard. + +## Components to Create + +### 1. `src/routes/assistant/-components/blockers/` +Location: `/Users/Martin/Tresors/Projects/GenesisTools/src/dashboard/apps/web/src/routes/assistant/-components/blockers/` + +#### Files: +- `BlockerCard.tsx` - Single blocker display with time blocked +- `BlockerList.tsx` - Dashboard widget listing all blockers +- `BlockerActions.tsx` - Quick action buttons (remind, switch, wait) +- `BlockerModal.tsx` - Dialog for marking task as blocked +- `index.ts` - Exports + +### 2. Update Task Detail Page +File: `src/routes/assistant/tasks/$taskId.tsx` +- Add "Mark as Blocked" button +- Show current blocker if task is blocked +- Add "Resolve Blocker" button + +## Data Model (existing) +Using existing types from `@/lib/assistant/types`: +- `TaskBlocker` - Main blocker entity +- `TaskBlockerInput` - Input for creating blocker +- `BlockerFollowUpAction` - 'remind' | 'switch' | 'wait' + +## Hook (existing) +Using `useBlockers` from `@/lib/assistant/hooks`: +- `addBlocker(input)` - Create blocker +- `resolveBlocker(id)` - Mark as resolved +- `getActiveBlockers()` - All unresolved blockers +- `getActiveBlockerForTask(taskId)` - Blocker for specific task +- `getLongStandingBlockers(days)` - Blockers older than N days +- `getBlockerDurationDays(blocker)` - Time blocked + +## UI/UX Requirements + +### Cyberpunk Aesthetic +- Rose/red color theme +- Glass cards with rose border +- Pulsing indicator for long-blocked (>2 days) +- Action buttons with hover glow + +### Blocker Card Shows: +- Task title (linked) +- Blocker reason +- Blocker owner (if set) +- Time blocked +- Follow-up action set +- Quick actions + +### Quick Actions: +1. "Remind @owner" - Shows draft message +2. "Switch task" - Link to What's Next +3. "Set reminder" - Date picker + +### Urgency Coloring: +- < 1 day: Normal rose +- 1-2 days: Brighter rose +- > 2 days: Pulsing red with glow + +## Implementation Order +1. Create blockers directory structure +2. Implement BlockerCard component +3. Implement BlockerActions component +4. Implement BlockerList widget +5. Implement BlockerModal dialog +6. Update task detail page with blocker section +7. Test and verify + +## Commit Message +``` +feat(blockers): implement blocker detection and tracking +``` diff --git a/.claude/plans/2026-01-13-critical-path-visualizer.md b/.claude/plans/2026-01-13-critical-path-visualizer.md new file mode 100644 index 000000000..ff1e6cfb1 --- /dev/null +++ b/.claude/plans/2026-01-13-critical-path-visualizer.md @@ -0,0 +1,71 @@ +# Critical Path Visualizer - Implementation Plan + +## Overview +Create a visual dependency graph showing task relationships and critical path to shipping for the Personal AI Assistant dashboard. + +## Architecture + +### Files to Create + +1. **`src/routes/assistant/-components/critical-path/`** + - `CriticalPathGraph.tsx` - Main SVG graph with pan/zoom + - `DependencyNode.tsx` - Hexagonal task node component + - `PathAnalysis.tsx` - Analysis panel showing bottlenecks + - `BottleneckAlert.tsx` - Warning component for bottlenecks + - `DependencySelector.tsx` - Task dependency picker for task detail + - `useCriticalPath.ts` - Hook for graph calculations + - `graph-utils.ts` - Topological sort, critical path algorithms + - `index.ts` - Exports + +2. **Update `src/routes/assistant/tasks/$taskId.tsx`** + - Add "Depends on" task selector + - Add "Blocks" task display + - Add "View in Critical Path" link + +### Types (Already in types.ts) +- `GraphNode` - Node with position, level, critical path status +- `GraphEdge` - Edge between nodes +- `CriticalPathAnalysis` - Analysis results +- `ViewportState` - Pan/zoom state + +## Component Details + +### CriticalPathGraph.tsx +- SVG-based interactive graph +- Pan: Mouse drag on background +- Zoom: Scroll wheel +- Node click: Show task tooltip +- Critical path: Red pulsing edges +- Non-critical: Gray edges +- Cyberpunk grid background + +### DependencyNode.tsx +- Hexagon shape with glow effect +- Color based on task urgency +- Critical path nodes have red glow +- Bottleneck indicator (warning icon) +- Progress ring around hexagon + +### PathAnalysis.tsx +- Critical path sequence display +- Days to completion estimate +- Bottleneck warnings +- Task counts + +### Graph Algorithms (graph-utils.ts) +1. **Topological Sort**: Kahn's algorithm for level assignment +2. **Critical Path**: Longest path through DAG +3. **Bottleneck Detection**: Most downstream dependencies +4. **Layout**: Force-directed within levels + +## Cyberpunk Aesthetic +- Dark grid background (#0a0a14) +- Neon glow effects (purple, cyan, red) +- Hexagonal nodes +- Pulsing animations on critical path +- Tech corners on panels + +## Responsive Design +- Desktop: Full graph with analysis panel +- Tablet: Collapsible analysis panel +- Mobile: Simplified list view with path indicator diff --git a/.claude/plans/2026-01-13-decision-log.md b/.claude/plans/2026-01-13-decision-log.md new file mode 100644 index 000000000..99e3fe93d --- /dev/null +++ b/.claude/plans/2026-01-13-decision-log.md @@ -0,0 +1,99 @@ +# Decision Log Implementation Plan + +## Overview +Implement a decision tracking system for the Personal AI Assistant to prevent re-debating settled decisions. + +## Files to Create + +### 1. Component Files (`src/routes/assistant/-components/decisions/`) + +#### `DecisionCard.tsx` +- Glass card with status-colored badges (emerald=active, gray=superseded, rose=reversed) +- Shows: title, status badge, date, impact area tag +- Expandable sections for reasoning and alternatives +- Action buttons: Supersede, Reverse, Edit, Delete +- Uses FeatureCard pattern with color mapping based on status + +#### `DecisionForm.tsx` +- Dialog form for creating/editing decisions +- Fields: title, reasoning (textarea), alternatives (array input), impact area (select), related tasks (multi-select), tags (comma-separated) +- Uses existing Dialog, Input, Textarea, Label components +- Purple-themed submit button + +#### `DecisionTimeline.tsx` +- Visual timeline view of decisions +- Neon line connector between nodes +- Each node shows: date, title, status indicator +- Color coding by status +- Click to expand details + +#### `SupersededChain.tsx` +- Shows decision evolution chain (decision -> superseded by -> etc) +- Arrow connectors between cards +- Compact card view +- Visual representation of why decisions changed + +#### `DecisionLog.tsx` +- Main container component +- Status tabs with counts: Active, Superseded, Reversed, All +- Search bar for keyword filtering +- Filter dropdown for impact areas +- Grid of DecisionCards +- Empty state when no decisions + +#### `index.ts` +- Export all components + +### 2. Page File (`src/routes/assistant/decisions.tsx`) +- Replace placeholder with full implementation +- Use DashboardLayout +- Import and use DecisionLog component +- Connect to useDecisionLog hook +- Handle all CRUD operations + +## Component Patterns to Follow + +### Styling (Cyberpunk Aesthetic) +- Glass cards: `bg-[#0a0a14]/80 backdrop-blur-sm` +- Status colors: + - Active: `emerald-500` (bg-emerald-500/10, border-emerald-500/30, text-emerald-400) + - Superseded: `gray-500` (bg-gray-500/10, border-gray-500/30, text-gray-400) + - Reversed: `rose-500` (bg-rose-500/10, border-rose-500/30, text-rose-400) +- Impact area colors: + - frontend: purple + - backend: blue + - infrastructure: orange + - process: cyan + - architecture: amber + - product: emerald +- Corner decorations using FeatureCard +- Neon glow effects on hover/active + +### Animations +- `animate-fade-in-up` for staggered card entry +- Smooth height transition for expandable sections: `transition-all duration-300` +- Hover brightness: `hover:brightness-110` + +### Data Flow +- Use `useDecisionLog` hook from `@/lib/assistant/hooks` +- Hook provides: decisions, loading, error, initialized +- CRUD: createDecision, updateDecision, deleteDecision +- Actions: supersedeDecision, reverseDecision +- Filters: getActiveDecisions, getSupersededDecisions, getReversedDecisions, getByImpactArea +- Utilities: getDecisionChain, getAllTags + +## Implementation Order +1. DecisionCard.tsx - Core display component +2. DecisionForm.tsx - Create/edit modal +3. SupersededChain.tsx - Chain visualization +4. DecisionTimeline.tsx - Timeline view +5. DecisionLog.tsx - Main container +6. index.ts - Exports +7. decisions.tsx - Page implementation + +## Types Used (from `@/lib/assistant/types`) +- `Decision` - Main entity +- `DecisionInput` - Create input +- `DecisionUpdate` - Update input +- `DecisionStatus` - 'active' | 'superseded' | 'reversed' +- `DecisionImpactArea` - 'frontend' | 'backend' | 'infrastructure' | 'process' | 'architecture' | 'product' diff --git a/.claude/plans/2026-01-13-distraction-tracker.md b/.claude/plans/2026-01-13-distraction-tracker.md new file mode 100644 index 000000000..29cb588ca --- /dev/null +++ b/.claude/plans/2026-01-13-distraction-tracker.md @@ -0,0 +1,75 @@ +# Distraction Tracker Implementation Plan + +## Overview +Implement a system to log interruptions and visualize distraction patterns for the Personal AI Assistant dashboard. + +## Files to Create + +### 1. Components in `src/routes/assistant/-components/distractions/` + +#### `QuickLogButton.tsx` +- Floating action button with subtle pulse animation +- Opens the distraction log modal +- Keyboard shortcut support (Ctrl+D) +- Cyberpunk neon styling + +#### `DistractionLogModal.tsx` +- Source selector with icons (Slack, Email, Meeting, Coworker, Hunger, Other) +- Optional description textarea +- Auto-fill task interrupted if task in progress +- Neon-colored source icons + +#### `DistractionStats.tsx` +- Distribution pie chart with recharts +- Glow effect on chart segments +- Source breakdown with counts and percentages +- Total distractions and time lost + +#### `DistractionPatterns.tsx` +- Timeline bar chart (distractions by day of week) +- Peak distraction time analysis +- Pattern detection ("Tuesday 2-4pm is chaos window") + +#### `DistractionInsights.tsx` +- Recommendations in glass cards +- Actionable suggestions ("Mute Slack 9-11am") +- Experiment tracking ("Try this for 1 week") + +#### `index.ts` +- Export all components + +### 2. Update Analytics Page +Modify `src/routes/assistant/analytics.tsx` to include distraction section. + +## Component Architecture + +``` +analytics.tsx + DistractionSection (new section on analytics page) + DistractionStats (pie chart) + DistractionPatterns (bar chart + analysis) + DistractionInsights (recommendations) + +QuickLogButton (floating, global) + DistractionLogModal (modal dialog) +``` + +## Data Flow +- Use existing `useDistractions` hook from `@/lib/assistant/hooks/` +- Hook provides: logDistraction, getStats, getTodayDistractions, etc. +- DistractionStats type already defined in storage/types.ts + +## UI/Styling +- Cyberpunk aesthetic with neon colors per source +- Glass card styling for insights +- Recharts with custom theming +- Subtle pulse animation on quick log button +- Source icons with glow effects + +## Color Mapping for Sources +- Slack: cyan-500 (MessageSquare) +- Email: blue-500 (Mail) +- Meeting: orange-500 (Users) +- Coworker: purple-500 (User) +- Hunger: amber-500 (Coffee) +- Other: gray-500 (AlertCircle) diff --git a/.claude/plans/2026-01-13-energy-heatmap.md b/.claude/plans/2026-01-13-energy-heatmap.md new file mode 100644 index 000000000..815859bf8 --- /dev/null +++ b/.claude/plans/2026-01-13-energy-heatmap.md @@ -0,0 +1,68 @@ +# Energy Heatmap Implementation Plan + +## Overview +Implement a productivity patterns visualization showing when user is most focused using a 7x24 grid (days of week x hours) with cyberpunk aesthetic. + +## Files to Create + +### 1. HeatmapCell.tsx +- Individual cell component with tooltip +- Color intensity based on focus quality (1-5 scale) +- Hover state with neon glow effect +- Tooltip showing: day/time, focus quality, context switches, tasks completed + +### 2. EnergyHeatmap.tsx +- 7x24 grid container +- Renders HeatmapCell for each hour/day combination +- Row labels (Mon-Sun), Column labels (hours) +- Color scale legend +- Scanline CSS animation effect +- Uses useEnergyData hook for data + +### 3. EnergyInsights.tsx +- Pattern analysis panel +- Peak focus time identification +- Afternoon slump detection +- Best day of week +- Glass card with cyberpunk styling + +### 4. FocusRecommendation.tsx +- Time-based task suggestion banner +- Shows when current time matches peak focus hours +- Links to recommended complex task +- Dismissible banner + +### 5. LogEnergyModal.tsx +- Quick self-report dialog +- Focus quality slider (1-5) +- Work type selector +- Context switches count +- Notes field + +### 6. index.ts +- Export all analytics components + +## Files to Modify + +### analytics.tsx +- Replace placeholder with actual implementation +- Add EnergyHeatmap section +- Add Insights panel +- Add Log Energy button +- Add Focus Recommendation banner + +## Design Tokens (Cyberpunk) +- Grid borders: cyan-500/20 +- Low energy: slate-800 (dark) +- Medium energy: cyan-700 +- High energy: cyan-400 (bright) +- Peak energy: amber-400 with glow +- Scanline: rgba(0, 255, 255, 0.05) repeating gradient +- Glass card: bg-slate-900/80 backdrop-blur + +## Data Flow +1. useEnergyData hook fetches last 30 days of snapshots +2. getHeatmapData computes averages by day/hour +3. Grid cells render with computed intensity +4. Insights computed from hourlyAverages/dailyAverages +5. Current time compared to peak hours for recommendation diff --git a/.claude/plans/2026-01-13-escalation-alerts.md b/.claude/plans/2026-01-13-escalation-alerts.md new file mode 100644 index 000000000..53f0c48da --- /dev/null +++ b/.claude/plans/2026-01-13-escalation-alerts.md @@ -0,0 +1,159 @@ +# Auto-Escalation Alerts Implementation Plan + +**Date:** 2026-01-13 +**Feature:** Deadline Risk Detection and Alerts + +## Overview + +Implemented proactive deadline risk detection and resolution options for the Personal AI Assistant dashboard. The system monitors tasks with deadlines and alerts users when tasks are at risk of missing their deadlines. + +## Components Created + +### 1. EscalationOptions.tsx +**Path:** `src/routes/assistant/-components/escalation/EscalationOptions.tsx` + +Resolution option cards for handling deadline risks: +- **Extend Deadline**: Request more time with date picker +- **Get Help**: Add helper name and notes for pair programming +- **Cut Scope**: List features to defer or cut +- **Accept Risk**: Acknowledge delay with optional note + +Features: +- Cyberpunk-styled cards with hover glow effects +- Recommended option highlighted with gradient badge +- Dynamic forms based on selected option +- Color-coded by option type (blue, purple, amber, red) + +### 2. EscalationAlert.tsx +**Path:** `src/routes/assistant/-components/escalation/EscalationAlert.tsx` + +Full escalation modal showing: +- Task details (title, deadline, progress) +- Risk metrics grid (deadline, time left, progress, projected completion) +- Progress bar with color coding +- Days late indicator +- Resolution options integration + +Features: +- Critical (red) vs at-risk (yellow) styling +- Animated warning icons for critical risks +- Shadow/glow effects based on risk level + +### 3. EscalationWidget.tsx +**Path:** `src/routes/assistant/-components/escalation/EscalationWidget.tsx` + +Dashboard widget for the toolbar: +- Compact badge showing "X deadline(s) at risk" +- Color-coded by severity (red for critical, yellow for at-risk) +- Clickable to open escalation modal +- Pulsing animation for critical alerts +- Breakdown badges showing count by risk level + +### 4. RiskIndicator.tsx (Enhanced) +**Path:** `src/routes/assistant/-components/escalation/RiskIndicator.tsx` + +Risk badges for task cards: +- `RiskIndicator`: Basic pulsing dot indicator +- `RiskBadge`: Compact inline badge +- `TaskCardRiskIndicator`: Enhanced indicator with days late display + +Features: +- Pulsing animation for critical risks +- Ping animation ring for red level +- Glow effects with CSS box-shadow + +### 5. index.ts +**Path:** `src/routes/assistant/-components/escalation/index.ts` + +Exports all escalation components for easy importing. + +## Integration Points + +### TaskCard.tsx (Updated) +**Path:** `src/lib/assistant/components/TaskCard.tsx` + +Added props: +- `riskLevel?: DeadlineRiskLevel` - Risk level from useDeadlineRisk hook +- `daysLate?: number` - Days late for display +- `onRiskClick?: (taskId: string) => void` - Handler for opening escalation modal + +New features: +- Risk indicator in header (between status and urgency badge) +- "Handle Risk" menu item in dropdown + +### tasks/index.tsx (Updated) +**Path:** `src/routes/assistant/tasks/index.tsx` + +Added: +- `useDeadlineRisk` hook integration +- `EscalationWidget` in toolbar (after streak indicator) +- `EscalationAlert` modal for handling risks +- Risk data passed to TaskCard and GridView +- Resolution handlers for all 4 options + +## Risk Calculation Logic + +The `useDeadlineRisk` hook (existing) calculates: + +**Risk Levels:** +- `green`: On track (projected completion before deadline) +- `yellow`: At risk (< 2 days remaining OR < 50% complete with <= 5 days) +- `red`: Critical (projected late OR overdue) + +**Recommended Actions:** +- `extend`: Red risk with >= 30% complete +- `scope`: Red risk with < 30% complete +- `help`: Yellow risk with < 50% complete +- `accept`: Green or yellow with >= 50% complete + +## Cyberpunk Aesthetic + +### Colors +- Yellow: At-risk warnings (yellow-400/500) +- Red: Critical alerts (red-400/500) +- Blue: Extend option (blue-400/500) +- Purple: Help option (purple-400/500) +- Amber: Scope option (amber-400/500) + +### Animations +- `animate-pulse`: Pulsing dot indicators +- `animate-ping`: Ring effect for critical +- Custom `pulse-glow-red`: Pulsing shadow for critical widget + +### Effects +- Box-shadow glow on risk indicators +- Gradient badges for recommended options +- Scale transforms on hover +- Transition effects on all interactive elements + +## Data Flow + +``` +tasks -> useDeadlineRisk.calculateAllRisks() -> risks[] + | + v + +-> EscalationWidget (toolbar summary) + | +risks[] -> getRiskForTask(taskId) -> TaskCard (risk indicator) + | + +-> EscalationAlert (full modal) + | + v + EscalationOptions (resolution form) + | + v + handleEscalationResolve() + | + +-> updateTask() (extend/scope) + +-> console.log() (help/accept) + +-> calculateAllRisks() (refresh) +``` + +## Future Enhancements + +1. **Communication Log Integration**: Log "help" requests as communication entries +2. **Decision Log Integration**: Log "accept risk" as decisions +3. **Notifications**: Push notifications for escalating risks +4. **Historical Tracking**: Track resolution choices over time +5. **Team Features**: Notify stakeholders when deadlines are extended +6. **Analytics**: Risk patterns and resolution effectiveness metrics diff --git a/.claude/plans/2026-01-13-handoff-compiler.md b/.claude/plans/2026-01-13-handoff-compiler.md new file mode 100644 index 000000000..0f7f96489 --- /dev/null +++ b/.claude/plans/2026-01-13-handoff-compiler.md @@ -0,0 +1,136 @@ +# Handoff Compiler Implementation Plan + +## Overview +Create auto-generated context documents when tasks move to teammates. The Handoff Compiler provides a terminal/console-styled document preview with editable sections. + +## Architecture + +### Components to Create + +1. **`src/routes/assistant/-components/handoff/`** + - `HandoffDocument.tsx` - Compiled handoff view with cyberpunk terminal style + - `HandoffPreview.tsx` - Preview modal before sending + - `HandoffEditor.tsx` - Edit/customize sections + - `HandoffHistory.tsx` - Past handoffs list + - `index.ts` - exports + +2. **Update Task Detail Page** + - Add "Hand off task" button to `$taskId.tsx` + - Show handoff banner if task was handed to current user + - Acknowledge button functionality + +## Component Details + +### HandoffDocument.tsx +A read-only view of a compiled handoff document styled like a terminal output. + +**Sections:** +- Summary (task title + description) +- Context Notes (from parking lot) +- Decisions Made (linked decisions) +- Blockers (current blockers) +- Next Steps (editable list) +- Gotchas (editable notes) +- Contact info + +**Styling:** +- Monospace font for context +- Neon underlines for section headers (cyan glow) +- Glass card container +- Terminal prompt style prefixes + +### HandoffPreview.tsx +Modal dialog for previewing the handoff before sending. + +**Features:** +- "Hand off to" text input +- Preview of compiled document +- Edit button to switch to editor +- Send/Cancel buttons +- Auto-compile from task data + +### HandoffEditor.tsx +Form for editing handoff sections before sending. + +**Editable Fields:** +- Summary (pre-filled from task) +- Context Notes (pre-filled from parking) +- Next Steps (array input) +- Gotchas (textarea) +- Contact info (text input) + +### HandoffHistory.tsx +List of past handoffs for a task. + +**Features:** +- Timeline view +- Status indicators (pending review, acknowledged) +- Link to view full document + +## Data Flow + +1. User clicks "Hand off task" button +2. System auto-compiles handoff from: + - Task title/description + - Active parking context + - Linked decisions (from useDecisionLog) + - Active blockers (from useBlockers) +3. User reviews in HandoffPreview +4. User can edit in HandoffEditor +5. User enters recipient and sends +6. Handoff stored via useHandoff hook + +## Hooks Integration + +- `useHandoff` - Create/update/acknowledge handoffs +- `useTaskStore` - Get task and parking data +- `useDecisionLog` - Get related decisions +- `useBlockers` - Get current blockers + +## UI States + +### Sender View +- "Hand off task" button in task detail header +- HandoffPreview modal +- HandoffEditor modal (if editing) + +### Receiver View +- Banner at top of task detail: "Task handed off to you from @sender" +- Acknowledge button +- View handoff document link + +## Cyberpunk Styling + +```css +/* Terminal style */ +.handoff-terminal { + font-family: 'JetBrains Mono', monospace; + background: rgba(10, 10, 20, 0.9); + border: 1px solid rgba(0, 255, 255, 0.2); +} + +/* Section headers */ +.handoff-section-header { + color: #00ffff; + border-bottom: 2px solid transparent; + border-image: linear-gradient(90deg, #00ffff, transparent) 1; + text-transform: uppercase; + letter-spacing: 0.1em; +} + +/* Prompt prefix */ +.handoff-prompt::before { + content: '>'; + color: #00ffff; + margin-right: 0.5rem; +} +``` + +## Implementation Order + +1. Create index.ts with exports +2. Create HandoffDocument.tsx (view) +3. Create HandoffEditor.tsx (form) +4. Create HandoffPreview.tsx (modal) +5. Create HandoffHistory.tsx (list) +6. Update $taskId.tsx with button and banner diff --git a/.claude/plans/2026-01-13-kanban-board.md b/.claude/plans/2026-01-13-kanban-board.md new file mode 100644 index 000000000..2bada67ba --- /dev/null +++ b/.claude/plans/2026-01-13-kanban-board.md @@ -0,0 +1,74 @@ +# Kanban Board Implementation Plan + +## Overview +Implement a drag-and-drop Kanban board for task management with 4 columns using @dnd-kit libraries. + +## Components to Create + +### 1. `src/routes/assistant/-components/kanban/KanbanBoard.tsx` +- Main container with DndContext from @dnd-kit/core +- Manages drag state and handles DragEnd events +- Uses DragOverlay for preview during drag +- Handles status updates via useTaskStore.updateTask() +- Optimistic updates with rollback on error + +### 2. `src/routes/assistant/-components/kanban/KanbanColumn.tsx` +- Uses useDroppable from @dnd-kit/core +- Props: status, color, title, tasks, onAddTask +- Glassmorphism styling with backdrop-blur +- Neon border glow matching column color +- Tech corner decorations (like FeatureCard) +- Shows count badge in header + +### 3. `src/routes/assistant/-components/kanban/KanbanCard.tsx` +- Uses useDraggable from @dnd-kit/core +- Simplified version of TaskCard +- Shows: title, urgency badge, deadline +- Click navigates to /assistant/tasks/$taskId +- Drag preview with scale(1.05) and shadow + +### 4. `src/routes/assistant/-components/kanban/KanbanHeader.tsx` +- Column header with icon, title, count badge +- "Add Task" button per column + +### 5. `src/routes/assistant/-components/kanban/index.ts` +- Barrel exports + +## Column Configuration + +| Column | Status | Color | Icon | +|--------|--------|-------|------| +| Backlog | backlog | cyan | Circle | +| In Progress | in-progress | amber | Play | +| Blocked | blocked | rose | Ban | +| Completed | completed | emerald | CheckCircle | + +## Rewrite: `src/routes/assistant/tasks/index.tsx` +- Replace grid view with KanbanBoard +- Keep toolbar (filters, park, add task) +- Pass tasks and handlers to KanbanBoard + +## Styling Requirements + +### Cyberpunk Aesthetic +- Glassmorphism: `bg-[#0a0a14]/80 backdrop-blur-sm` +- Neon borders: `border-{color}-500/20 hover:border-{color}-500/40` +- Corner decorations: Same pattern as FeatureCard +- Glow effect on columns + +### Drag Interactions +- Drag preview: `scale-[1.05] shadow-2xl shadow-{color}-500/30` +- Drop target highlight: `ring-2 ring-{color}-500/50` +- Smooth spring animations via CSS transitions + +### Mobile +- Horizontal scroll: `overflow-x-auto snap-x snap-mandatory` +- Column width: `min-w-[280px] w-[85vw] sm:w-auto` + +## Implementation Order +1. Create KanbanCard.tsx +2. Create KanbanHeader.tsx +3. Create KanbanColumn.tsx +4. Create KanbanBoard.tsx +5. Create index.ts +6. Rewrite tasks/index.tsx diff --git a/.claude/plans/2026-01-13-micro-celebrations.md b/.claude/plans/2026-01-13-micro-celebrations.md new file mode 100644 index 000000000..45845aaca --- /dev/null +++ b/.claude/plans/2026-01-13-micro-celebrations.md @@ -0,0 +1,73 @@ +# Micro-Celebrations Implementation Plan + +## Overview +Implement a graduated celebration system with 3 tiers for the Personal AI Assistant dashboard. + +## Architecture + +### Files Structure +``` +src/lib/assistant/components/celebrations/ + - MicroCelebration.tsx # Tier 1: Toast notification (bottom-right, 3s) + - BadgeNotification.tsx # Tier 2: Center toast (5s, click to dismiss) + - CelebrationManager.tsx # Decides which tier to show + - FocusSessionComplete.tsx # Focus session completion toast + - StreakMilestone.tsx # Streak achievement toast + - particles.ts # Particle animation utilities + - index.ts # Exports +``` + +### Celebration Tiers + +**TIER 1 - Micro Toast (non-intrusive)** +- Position: bottom-right +- Duration: 3s auto-dismiss +- Animation: slide-in from right +- Use cases: + - Focus session complete (25 min) + - Small task complete (nice-to-have urgency) + - 3-task day milestone + +**TIER 2 - Badge Notification (center toast)** +- Position: center-bottom +- Duration: 5s, click to dismiss +- Animation: scale-in + glow pulse +- Use cases: + - 5-day streak + - 10 tasks completed + - Speedrunner (5 tasks in day) + +**TIER 3 - Full Celebration (existing CelebrationModal)** +- Use existing modal component +- Use cases: + - Critical task complete + - 7-day streak + - Rare/legendary badge unlock + +### State Management +- Use existing `useCelebrations` hook +- Add celebration mode preference to store: `full-party` | `subtle` | `silent` +- Store preference in localStorage + +### Integration Points +1. `useTaskStore.completeTask()` - trigger celebrations +2. `useCelebrations` hook - manages pending/active celebrations +3. CelebrationManager component - renders appropriate tier + +## Implementation Steps + +1. Create celebrations directory and types +2. Implement MicroCelebration (Tier 1 toast) +3. Implement BadgeNotification (Tier 2 center toast) +4. Create CelebrationManager to orchestrate tiers +5. Add particle animation utilities +6. Integrate with task completion flow +7. Add celebration mode settings +8. Test all celebration triggers + +## Cyberpunk Aesthetic Guidelines +- Neon border glow (emerald/amber/purple) +- Semi-transparent dark backgrounds +- Smooth slide-in animations +- Particle effects on badge unlock +- Font: monospace for stats, sans-serif for messages diff --git a/.claude/plans/2026-01-13-weekly-review-dashboard.md b/.claude/plans/2026-01-13-weekly-review-dashboard.md new file mode 100644 index 000000000..acb56c56a --- /dev/null +++ b/.claude/plans/2026-01-13-weekly-review-dashboard.md @@ -0,0 +1,109 @@ +# Weekly Review Dashboard Implementation Plan + +## Overview +Implementing a weekly productivity review dashboard with charts and insights for the Personal AI Assistant. + +## Components to Create + +### 1. Analytics Components (`src/routes/assistant/-components/analytics/`) + +#### `WeeklyReview.tsx` +- Main container component +- Week selector dropdown (this week, last week, 2 weeks ago, etc.) +- Orchestrates all child components +- Handles data loading via `useWeeklyReview` hook +- Responsive grid layout + +#### `WeekStats.tsx` +- Summary cards for key metrics +- Tasks completed (with week-over-week comparison, trend arrow) +- Focus time (in hours) +- Current streak +- Glass card effect with neon accents + +#### `CompletionTrend.tsx` +- Area chart showing tasks over last 8 weeks +- Uses recharts AreaChart +- Neon cyan gradient fill +- Dark background with grid lines +- Tooltip showing exact values + +#### `DeadlinePerformance.tsx` +- Donut/Pie chart showing on-time vs late percentage +- Uses recharts PieChart with inner radius +- Amber for on-time, rose for late +- Center label showing overall percentage + +#### `EnergyByDay.tsx` +- Bar chart showing energy levels per day of week +- Uses recharts BarChart +- Emerald color scheme +- Shows pattern (e.g., "Thursday is your weak spot") + +#### `WeeklyInsights.tsx` +- Terminal-styled insights panel +- AI-like recommendations +- Examples: + - "You completed 38% more tasks this week!" + - "Thursday is your weak spot. Try lighter tasks." + - "Peak focus: Monday 9-11am" +- Monospace font, typing animation feel + +#### `BadgesEarned.tsx` +- Grid of badges earned this week +- Uses existing badge definitions from types.ts +- Rarity-colored borders + +#### `ReviewExport.tsx` +- Export button with dropdown +- Options: Copy to clipboard, Download as image (future) +- Generates shareable text summary + +### 2. Update `analytics.tsx` +- Replace placeholder with `WeeklyReview` component +- Pass userId from auth + +## Data Flow + +``` +analytics.tsx + -> WeeklyReview + -> useWeeklyReview(userId) + -> useStreak(userId) + -> useEnergyData(userId) + -> useBadgeProgress(userId) + +WeeklyReview orchestrates: + -> WeekStats (summary cards) + -> CompletionTrend (line chart) + -> DeadlinePerformance (donut chart) + -> EnergyByDay (bar chart) + -> WeeklyInsights (recommendations) + -> BadgesEarned (badges grid) + -> ReviewExport (export button) +``` + +## Styling + +### Cyberpunk Aesthetic +- Glass effect: `bg-[#0a0a14]/80 backdrop-blur-sm` +- Neon colors: + - Cyan: `#06b6d4` (charts, primary accent) + - Amber: `#f59e0b` (success, on-time) + - Emerald: `#10b981` (energy, positive) + - Rose: `#f43f5e` (late, negative) +- Corner decorations from FeatureCard +- Grid background with scan lines + +### Chart Styling +- Dark background: `#0a0a14` +- Grid lines: `rgba(255,255,255,0.05)` +- Tooltips with glass effect +- Axis labels in muted gray + +## Technical Notes +- Use React 19 (no useCallback/useMemo needed - React Compiler) +- recharts v3.6.0 is installed +- Use existing hooks from `@/lib/assistant/hooks` +- Use existing types from `@/lib/assistant/types` +- Authentication via `useAuth` from WorkOS diff --git a/CodeExamples.md b/CodeExamples.md new file mode 100644 index 000000000..5b75a7371 --- /dev/null +++ b/CodeExamples.md @@ -0,0 +1,466 @@ +# CLI Libraries - Code Examples + +This document contains practical code examples for yargs, @cliffy/command, and @logtape/logtape. + +--- + +## yargs - Complete Example + +**File: `src/examples/yargs-example.ts`** + +```typescript +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; + +interface Options { + port?: number; + host?: string; + verbose?: boolean; + config?: string; +} + +async function main() { + const argv = await yargs(hideBin(process.argv)) + .command( + 'serve [port]', + 'Start development server', + (yargs) => { + return yargs + .positional('port', { + describe: 'Port number to listen on', + default: 3000, + type: 'number' + }) + .option('host', { + alias: 'h', + describe: 'Host to bind to', + default: 'localhost', + type: 'string' + }) + .option('verbose', { + alias: 'v', + describe: 'Enable verbose logging', + type: 'boolean', + default: false + }); + }, + (argv) => { + console.log(`Starting server on ${argv.host}:${argv.port}`); + if (argv.verbose) { + console.log('Verbose mode enabled'); + } + } + ) + .command( + 'build', + 'Build the project for production', + (yargs) => { + return yargs + .option('minify', { + describe: 'Minify output', + type: 'boolean', + default: true + }) + .option('sourcemap', { + alias: 's', + describe: 'Generate source maps', + type: 'boolean', + default: false + }); + }, + (argv) => { + console.log('Building project...'); + if (argv.minify) console.log(' - Minifying'); + if (argv.sourcemap) console.log(' - Generating source maps'); + } + ) + .command( + 'watch ', + 'Watch files for changes', + (yargs) => { + return yargs + .positional('path', { + describe: 'Path to watch', + type: 'string' + }) + .option('extensions', { + alias: 'e', + describe: 'File extensions to watch', + type: 'array', + default: ['.ts', '.js'] + }); + }, + (argv) => { + console.log(`Watching ${argv.path} for changes...`); + console.log(`Watching extensions: ${(argv.extensions as string[]).join(', ')}`); + } + ) + .option('config', { + alias: 'c', + describe: 'Path to config file', + type: 'string' + }) + .alias('help', 'h') + .alias('version', 'v') + .version('1.0.0') + .strict() + .parse(); +} + +main().catch(console.error); +``` + +### Usage Examples + +```bash +# Start server with custom port and verbose logging +bun run src/examples/yargs-example.ts serve 8080 --host 0.0.0.0 --verbose + +# Build for production with minification and sourcemaps +bun run src/examples/yargs-example.ts build --minify --sourcemap + +# Watch TypeScript and TSX files +bun run src/examples/yargs-example.ts watch src -e .ts -e .tsx + +# Show help +bun run src/examples/yargs-example.ts --help +bun run src/examples/yargs-example.ts serve --help +``` + +--- + +## @cliffy/command - Complete Example + +**File: `examples/cliffy-example.ts`** + +```typescript +import { Command } from "https://deno.land/x/cliffy/command/mod.ts"; +import { Table } from "https://deno.land/x/cliffy/table/mod.ts"; + +interface Config { + debug?: boolean; + verbose?: boolean; +} + +await new Command() + .name("mytool") + .version("1.0.0") + .description("A powerful CLI tool built with Cliffy") + .globalOption("-d, --debug", "Enable debug mode") + .globalOption("-v, --verbose", "Enable verbose logging") + + // Serve command + .command("serve [port]", "Start development server") + .option("-h, --host ", "Host to bind to", { default: "localhost" }) + .option("-w, --watch", "Watch for file changes") + .action(({ port = 3000, host, watch, debug, verbose }) => { + console.log(`Starting server on ${host}:${port}`); + if (watch) console.log("File watching enabled"); + if (verbose) console.log("Verbose mode enabled"); + if (debug) console.log("Debug mode enabled"); + }) + + // Build command with subcommands + .command("build", "Build the project") + .command("dev", "Build for development") + .option("-s, --sourcemap", "Generate source maps") + .action(({ sourcemap, debug }) => { + console.log("Building for development..."); + if (sourcemap) console.log(" - Generating source maps"); + if (debug) console.log(" - Debug info included"); + }) + .command("prod", "Build for production") + .option("-m, --minify", "Minify output", { default: true }) + .option("--strip-comments", "Strip comments") + .action(({ minify, stripComments }) => { + console.log("Building for production..."); + if (minify) console.log(" - Minifying"); + if (stripComments) console.log(" - Stripping comments"); + }) + + // Config command with subcommands + .command("config", "Manage configuration") + .command("set ", "Set a configuration value") + .action(({ key, value }) => { + console.log(`Set config: ${key} = ${value}`); + }) + .command("get ", "Get a configuration value") + .action(({ key }) => { + console.log(`Get config: ${key}`); + }) + .command("list", "List all configuration") + .action(() => { + const data = [ + ["Key", "Value"], + ["debug", "false"], + ["theme", "dark"], + ["port", "3000"], + ]; + new Table().header(data[0]).body(data.slice(1)).render(); + }) + + // Watch command + .command("watch ", "Watch files for changes") + .option("-e, --extensions ", "File extensions to watch", { + default: [".ts", ".js"] + }) + .option("--run ", "Command to run on change") + .action(({ pattern, extensions, run, verbose }) => { + console.log(`Watching ${pattern}...`); + console.log(`Extensions: ${extensions.join(", ")}`); + if (run) console.log(`Running on change: ${run}`); + if (verbose) console.log("Verbose output enabled"); + }) + + .parse(Deno.args); +``` + +### Usage Examples + +```bash +# Start server with file watching +deno run examples/cliffy-example.ts serve 8080 --host 0.0.0.0 --watch + +# Build for development with sourcemaps +deno run examples/cliffy-example.ts build dev --sourcemap + +# Build for production with minification +deno run examples/cliffy-example.ts build prod --minify + +# List configuration +deno run examples/cliffy-example.ts config list + +# Set configuration +deno run examples/cliffy-example.ts config set theme dark + +# Watch TypeScript files +deno run examples/cliffy-example.ts watch "src/**/*.ts" -e .ts -e .tsx --run "build" + +# Show help +deno run examples/cliffy-example.ts --help +deno run examples/cliffy-example.ts serve --help +``` + +--- + +## @logtape/logtape - Complete Example + +**File: `src/examples/logtape-example.ts`** + +```typescript +import { configure, getLogger } from "@logtape/logtape"; + +// Configure logtape with different sinks and log levels +configure({ + sinks: { + console: { + type: "console", + format: "json" // or "compact" + } + }, + loggers: [ + { + category: "genesis", + level: "debug" + }, + { + category: "genesis.sync", + level: "info" + }, + { + category: "genesis.watch", + level: "debug" + }, + { + category: "genesis.build", + level: "info" + } + ] +}); + +// Main application logger +const mainLogger = getLogger("genesis"); + +// Tool-specific loggers (hierarchical) +const syncLogger = getLogger("genesis.sync"); +const watchLogger = getLogger("genesis.watch"); +const buildLogger = getLogger("genesis.build"); + +async function exampleSync() { + syncLogger.info("Starting sync operation"); + + try { + syncLogger.debug("Connecting to remote", { + host: "api.example.com", + port: 443 + }); + + // Simulate work + await new Promise(resolve => setTimeout(resolve, 100)); + + syncLogger.info("Data synced successfully", { + itemsCount: 42, + duration: 100, + timestamp: new Date().toISOString() + }); + + } catch (error) { + syncLogger.error("Sync failed", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + retryable: true + }); + } +} + +async function exampleWatch() { + watchLogger.info("Starting file watcher", { + pattern: "src/**/*.ts", + extensions: [".ts", ".tsx"] + }); + + watchLogger.debug("Watcher initialized", { + ignorePaths: ["node_modules", ".git", "dist"] + }); + + // Simulate file change + watchLogger.info("File changed detected", { + file: "src/index.ts", + type: "modified", + timestamp: new Date().toISOString() + }); +} + +async function exampleBuild() { + buildLogger.info("Build started"); + + try { + buildLogger.debug("Resolving dependencies", { + count: 156 + }); + + buildLogger.info("Compiling TypeScript", { + files: 42, + errors: 0, + warnings: 2 + }); + + buildLogger.info("Bundling assets", { + bundles: 3, + totalSize: "2.4MB" + }); + + buildLogger.info("Build completed successfully", { + duration: 2500, + output: "dist/", + version: "1.0.0" + }); + + } catch (error) { + buildLogger.error("Build failed", { + phase: "bundling", + error: error instanceof Error ? error.message : String(error), + exitCode: 1 + }); + throw error; + } +} + +async function exampleWithContext() { + // Logging with rich context for debugging + mainLogger.info("Application initialized", { + version: "1.0.0", + environment: "development", + bun_version: Bun.version, + platform: process.platform, + timestamp: new Date().toISOString() + }); + + const userId = "user-123"; + const requestId = "req-456"; + + mainLogger.debug("Processing user action", { + userId, + requestId, + action: "data-import", + metadata: { + source: "csv", + rows: 1000, + columns: 15 + } + }); +} + +// Run examples +async function main() { + mainLogger.info("Running logtape examples"); + + await exampleSync(); + console.log("---"); + + await exampleWatch(); + console.log("---"); + + await exampleBuild(); + console.log("---"); + + await exampleWithContext(); + + mainLogger.info("All examples completed"); +} + +main().catch((error) => { + mainLogger.error("Fatal error", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined + }); + process.exit(1); +}); +``` + +### Usage Examples + +```bash +# Run all examples +bun run src/examples/logtape-example.ts + +# Use in your own code +import { getLogger } from "@logtape/logtape"; + +const logger = getLogger("my-tool"); +logger.info("Tool started"); +logger.debug("Debug info", { key: "value" }); +logger.error("An error occurred", { reason: "connection failed" }); +``` + +### Output Format + +LogTape outputs structured JSON by default: + +```json +{"level":"info","category":"genesis.sync","message":"Starting sync operation","timestamp":"2025-01-13T10:30:00Z"} +{"level":"debug","category":"genesis.sync","message":"Connecting to remote","host":"api.example.com","port":443} +{"level":"info","category":"genesis.sync","message":"Data synced successfully","itemsCount":42,"duration":100} +``` + +--- + +## Quick Reference + +### yargs - Best for: +- Complex Node.js/Bun CLI tools +- Multiple commands and subcommands +- Automatic help generation +- Shell completions + +### @cliffy/command - Best for: +- Deno CLI applications +- Type-safe argument parsing +- Built-in validation +- Structured subcommand hierarchies + +### @logtape/logtape - Best for: +- Hierarchical logging with categories +- Structured logging with rich context +- Cross-runtime applications (Deno, Node.js, Bun, Browser) +- Minimal dependencies diff --git a/Useful.md b/Useful.md index 162cc214a..7272f3789 100644 --- a/Useful.md +++ b/Useful.md @@ -144,11 +144,11 @@ await new Command() .description("Complex CLI application") .command("config", "Manage configuration") .command("set ", "Set a configuration value") - .action((options, key, value) => { + .action(({ key, value }) => { console.log(`Set ${key} = ${value}`); }) .command("get ", "Get a configuration value") - .action((options, key) => { + .action(({ key }) => { console.log(`Get ${key}`); }) .command("list", "List all configuration") @@ -169,7 +169,7 @@ await new Command() ### Documentation -Full documentation available at: [Cliffy Command Documentation](https://cliffy.io/docs/command/) +Full documentation available at: https://cliffy.io/docs/command/ --- @@ -325,8 +325,8 @@ async function main() { ### Documentation Full documentation and API references available at: -- [LogTape Documentation](https://logtape.org) -- [JSR Package](https://jsr.io/@logtape/logtape) +- https://logtape.org (main docs) +- https://jsr.io/@logtape/logtape (JSR package) --- @@ -360,17 +360,12 @@ Full documentation and API references available at: ## Usage in GenesisTools ### Argument Parsing -GenesisTools uses **commander** for argument parsing. It provides: +GenesisTools currently uses **minimist** for argument parsing. Both yargs and @cliffy/command could be considered for future enhancements: -- **Subcommands**: Define hierarchical command structures with `.command()` -- **Options**: Strongly typed options with `.option()` and automatic help generation -- **Action handlers**: Clean separation of command logic with `.action()` +- **yargs**: Better for complex Node.js/Bun CLI tools with many options and commands +- **@cliffy/command**: Better for Deno-based tools that need type safety and built-in validation -For interactive prompts, GenesisTools uses **@inquirer/prompts** which provides: - -- **Modern API**: Promise-based with individual prompt functions (`select`, `input`, `confirm`, etc.) -- **Type safety**: Built-in TypeScript support -- **Cancellation handling**: `ExitPromptError` from `@inquirer/core` for clean user cancellation +For GenesisTools' Bun-based environment, **yargs** would be the more natural choice if migration were considered. ### Logging GenesisTools currently uses **pino** for logging. **@logtape/logtape** offers advantages: diff --git a/findings.md b/findings.md new file mode 100644 index 000000000..79a28fb78 --- /dev/null +++ b/findings.md @@ -0,0 +1,152 @@ +# Findings & Decisions - Assistant Implementation + +## Requirements +From .claude/ideas/assistant/001-004 files: + +### Phase 1 (Complete) +- [x] Task CRUD with urgency hierarchy (critical/important/nice-to-have) +- [x] Context Parking (Cmd+P modal, parking history) +- [x] Completion Celebrations (confetti modal) +- [x] Streak tracking +- [x] Badge definitions (11 badges) +- [x] What's Next recommendation widget +- [x] **Kanban Board** - Drag-and-drop with @dnd-kit + +### Phase 2 (Complete) +- [x] Communication Log - Unified log with search and filtering +- [x] Decision Log - Formal decision capture with status tracking +- [x] Critical Path Visualizer - Interactive SVG dependency graph +- [x] Blocker Detector - Mark blocked, track resolution +- [x] Energy Heatmap - 7x24 grid with focus quality + +### Phase 3 (Complete) +- [x] Handoff Compiler - Auto-generate context docs +- [x] Auto-Escalation Alerts - Deadline risk detection with options +- [x] Micro-Celebrations - 3-tier celebration system (toast/badge/full) +- [x] Badge Progress UI - Showcase + progress bars +- [x] Weekly Review Dashboard - Charts, insights, export +- [x] Distraction Tracker - Log interruptions, pattern analysis + +## Research Findings + +### Final Codebase Structure +``` +src/dashboard/apps/web/src/routes/assistant/ +├── -components/ +│ ├── kanban/ # KanbanBoard, KanbanColumn, KanbanCard +│ ├── communication/ # CommunicationLog, LogEntry, LogForm, LogFilters +│ ├── decisions/ # DecisionLog, DecisionCard, DecisionForm +│ ├── critical-path/ # CriticalPathGraph, DependencyNode, PathAnalysis +│ ├── blockers/ # BlockerList, BlockerCard, BlockerModal +│ ├── analytics/ # EnergyHeatmap, WeeklyReview, WeekStats, etc. +│ ├── handoff/ # HandoffDocument, HandoffEditor, HandoffHistory +│ ├── escalation/ # EscalationAlert, RiskIndicator, EscalationWidget +│ ├── celebrations/ # MicroCelebration, CelebrationManager, BadgeCelebration +│ ├── badges/ # BadgeShowcase, BadgeProgress, BadgeCard +│ └── distractions/ # DistractionLog, DistractionStats, DistractionPatterns +├── -hooks/ # Extended with 12 new hooks +├── -lib/storage/ # Extended LocalStorage adapter +├── -types.ts # Extended with all new interfaces +├── tasks/ +│ ├── index.tsx # Kanban board (replaced grid) +│ └── $taskId.tsx # Task detail with blockers, handoffs, dependencies +├── next.tsx # What's Next recommendations +├── parking.tsx # Context parking history +├── analytics.tsx # Energy heatmap, weekly review, distractions, badges +├── communication.tsx # Communication log page +└── decisions.tsx # Decision log page +``` + +### Storage Architecture Discovery +**CRITICAL FINDING:** All assistant features use **localStorage only** + +| Component | Storage | Backend DB | Multi-device | +|-----------|---------|------------|--------------| +| Tasks/Kanban | localStorage | None | No | +| Communication Log | localStorage | None | No | +| Decision Log | localStorage | None | No | +| Blockers | localStorage | None | No | +| Handoffs | localStorage | None | No | +| Energy Snapshots | localStorage | None | No | +| Distractions | localStorage | None | No | +| Weekly Reviews | localStorage | None | No | +| Badges/Streaks | localStorage | None | No | + +**What works:** +- Cross-tab sync via BroadcastChannel +- Immediate client-side persistence +- No network latency + +**What doesn't work:** +- Multi-device sync +- Data survives browser clear +- Backup/restore +- Collaboration + +### Drizzle Schema Status +The `src/drizzle/schema.ts` only contains: +- `timers` - for stopwatch/countdown +- `activityLogs` - timer events +- `todos` - example table (not connected) + +**No assistant tables exist** in the database. + +## Technical Decisions +| Decision | Rationale | +|----------|-----------| +| @dnd-kit over react-beautiful-dnd | Modern, maintained, accessible, works with React 19 | +| recharts for charts | Lightweight, declarative, React-native | +| SVG for critical path | Custom graph viz with pan/zoom | +| LocalStorage adapter | Consistent with existing storage pattern | +| BroadcastChannel for sync | Cross-tab sync already implemented | +| TanStack Store | Already used, not Context or Redux | + +## Issues Encountered +| Issue | Resolution | +|-------|------------| +| Templates not found at expected path | Found at nested path with duplicate folder name | +| string \| null TypeScript errors | Added currentUserId captures after null checks | +| Multiple agents modifying $taskId.tsx | Agents re-read files before modifying | +| Celebration files in wrong commit | Bundled with handoff commit | + +## Commits Summary +| Commit | Feature | Files Changed | +|--------|---------|---------------| +| aa50cd2 | Types & Storage | Types, hooks, storage adapter | +| c7320ac | Kanban Board | kanban/*, tasks/index.tsx | +| 73c51f0 | Badge Progress UI | badges/* | +| fb79c59 | Communication Log | communication/*, communication.tsx | +| 403e12e | Decision Log | decisions/*, decisions.tsx | +| 95cd556 | Auto-Escalation | escalation/* | +| b57adfc | Energy Heatmap | analytics/Energy*, analytics.tsx | +| bbdea0c | Handoff + Celebrations | handoff/*, celebrations/* | +| f79f0bd | Blocker Detector | blockers/*, tasks/$taskId.tsx | +| 5617cd5 | Weekly Review | analytics/Weekly*, analytics.tsx | +| 7fee535 | Distraction Tracker | distractions/*, analytics.tsx | +| 9b22893 | Critical Path | critical-path/*, tasks/$taskId.tsx | +| dfa230e | TypeScript fixes (batch 1) | hooks/*.ts | +| 191655f | TypeScript fixes (batch 2) | hooks/*.ts | + +## Resources +- Detailed plan: .claude/plans/encapsulated-gathering-stream.md +- Master vision: .claude/ideas/assistant/001-assistant-personal-ai-master.md +- Phase 1 detailed: .claude/ideas/assistant/002-assistant-phase1-detailed.md +- Phase 2 roadmap: .claude/ideas/assistant/003-assistant-phase2-roadmap.md +- Phase 3 roadmap: .claude/ideas/assistant/004-assistant-phase3-roadmap.md + +## Next Steps for Backend Integration +1. Define tables in `src/drizzle/schema.ts`: + - `assistant_tasks` + - `assistant_communications` + - `assistant_decisions` + - `assistant_blockers` + - `assistant_handoffs` + - `assistant_energy_snapshots` + - `assistant_distractions` + - `assistant_weekly_reviews` +2. Create server functions in `src/lib/assistant/server/` +3. Integrate PowerSync for offline-first sync +4. Migrate storage adapter to use Drizzle + +--- +*Updated: 2026-01-13 after all agents completed and storage analysis* diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3055cca68..cef8eaa7f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,11 +29,8 @@ importers: '@iarna/toml': specifier: ^2.2.5 version: 2.2.5 - '@inquirer/prompts': - specifier: ^8.2.0 - version: 8.2.0(@types/node@25.0.6) '@modelcontextprotocol/sdk': - specifier: ^1.25.2 + specifier: ^1.11.0 version: 1.25.2(hono@4.11.3)(zod@3.25.76) '@modelcontextprotocol/server-github': specifier: ^2025.4.8 @@ -59,6 +56,9 @@ importers: '@types/jsdom': specifier: ^21.1.7 version: 21.1.7 + '@types/minimist': + specifier: ^1.2.5 + version: 1.2.5 '@types/turndown': specifier: ^5.0.5 version: 5.0.6 @@ -72,7 +72,7 @@ importers: specifier: ^5.0.86 version: 5.0.119(zod@3.25.76) axios: - specifier: ^1.13.2 + specifier: ^1.11.0 version: 1.13.2 boxen: specifier: ^8.0.1 @@ -89,9 +89,6 @@ importers: clipboardy: specifier: ^4.0.0 version: 4.0.0 - commander: - specifier: ^14.0.2 - version: 14.0.2 diff: specifier: ^8.0.2 version: 8.0.2 @@ -137,6 +134,9 @@ importers: minimatch: specifier: ^10.0.1 version: 10.1.1 + minimist: + specifier: ^1.2.8 + version: 1.2.8 node-notifier: specifier: ^10.0.1 version: 10.0.1 @@ -398,140 +398,6 @@ packages: '@iarna/toml@2.2.5': resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} - '@inquirer/ansi@2.0.3': - resolution: {integrity: sha512-g44zhR3NIKVs0zUesa4iMzExmZpLUdTLRMCStqX3GE5NT6VkPcxQGJ+uC8tDgBUC/vB1rUhUd55cOf++4NZcmw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - - '@inquirer/checkbox@5.0.4': - resolution: {integrity: sha512-DrAMU3YBGMUAp6ArwTIp/25CNDtDbxk7UjIrrtM25JVVrlVYlVzHh5HR1BDFu9JMyUoZ4ZanzeaHqNDttf3gVg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/confirm@6.0.4': - resolution: {integrity: sha512-WdaPe7foUnoGYvXzH4jp4wH/3l+dBhZ3uwhKjXjwdrq5tEIFaANxj6zrGHxLdsIA0yKM0kFPVcEalOZXBB5ISA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/core@11.1.1': - resolution: {integrity: sha512-hV9o15UxX46OyQAtaoMqAOxGR8RVl1aZtDx1jHbCtSJy1tBdTfKxLPKf7utsE4cRy4tcmCQ4+vdV+ca+oNxqNA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/editor@5.0.4': - resolution: {integrity: sha512-QI3Jfqcv6UO2/VJaEFONH8Im1ll++Xn/AJTBn9Xf+qx2M+H8KZAdQ5sAe2vtYlo+mLW+d7JaMJB4qWtK4BG3pw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/expand@5.0.4': - resolution: {integrity: sha512-0I/16YwPPP0Co7a5MsomlZLpch48NzYfToyqYAOWtBmaXSB80RiNQ1J+0xx2eG+Wfxt0nHtpEWSRr6CzNVnOGg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/external-editor@2.0.3': - resolution: {integrity: sha512-LgyI7Agbda74/cL5MvA88iDpvdXI2KuMBCGRkbCl2Dg1vzHeOgs+s0SDcXV7b+WZJrv2+ERpWSM65Fpi9VfY3w==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/figures@2.0.3': - resolution: {integrity: sha512-y09iGt3JKoOCBQ3w4YrSJdokcD8ciSlMIWsD+auPu+OZpfxLuyz+gICAQ6GCBOmJJt4KEQGHuZSVff2jiNOy7g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - - '@inquirer/input@5.0.4': - resolution: {integrity: sha512-4B3s3jvTREDFvXWit92Yc6jF1RJMDy2VpSqKtm4We2oVU65YOh2szY5/G14h4fHlyQdpUmazU5MPCFZPRJ0AOw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/number@4.0.4': - resolution: {integrity: sha512-CmMp9LF5HwE+G/xWsC333TlCzYYbXMkcADkKzcawh49fg2a1ryLc7JL1NJYYt1lJ+8f4slikNjJM9TEL/AljYQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/password@5.0.4': - resolution: {integrity: sha512-ZCEPyVYvHK4W4p2Gy6sTp9nqsdHQCfiPXIP9LbJVW4yCinnxL/dDDmPaEZVysGrj8vxVReRnpfS2fOeODe9zjg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/prompts@8.2.0': - resolution: {integrity: sha512-rqTzOprAj55a27jctS3vhvDDJzYXsr33WXTjODgVOru21NvBo9yIgLIAf7SBdSV0WERVly3dR6TWyp7ZHkvKFA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/rawlist@5.2.0': - resolution: {integrity: sha512-CciqGoOUMrFo6HxvOtU5uL8fkjCmzyeB6fG7O1vdVAZVSopUBYECOwevDBlqNLyyYmzpm2Gsn/7nLrpruy9RFg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/search@4.1.0': - resolution: {integrity: sha512-EAzemfiP4IFvIuWnrHpgZs9lAhWDA0GM3l9F4t4mTQ22IFtzfrk8xbkMLcAN7gmVML9O/i+Hzu8yOUyAaL6BKA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/select@5.0.4': - resolution: {integrity: sha512-s8KoGpPYMEQ6WXc0dT9blX2NtIulMdLOO3LA1UKOiv7KFWzlJ6eLkEYTDBIi+JkyKXyn8t/CD6TinxGjyLt57g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/type@4.0.3': - resolution: {integrity: sha512-cKZN7qcXOpj1h+1eTTcGDVLaBIHNMT1Rz9JqJP5MnEJ0JhgVWllx7H/tahUp5YEK1qaByH2Itb8wLG/iScD5kw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} @@ -661,6 +527,9 @@ packages: '@types/minimatch@5.1.2': resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + '@types/minimist@1.2.5': + resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + '@types/node-fetch@2.6.13': resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} @@ -1104,9 +973,6 @@ packages: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - chardet@2.1.1: - resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -1159,10 +1025,6 @@ packages: resolution: {integrity: sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==} engines: {node: '>=20'} - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - clipboardy@4.0.0: resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} engines: {node: '>=18'} @@ -1206,10 +1068,6 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - commander@14.0.2: - resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} - engines: {node: '>=20'} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -2588,10 +2446,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - mute-stream@3.0.0: - resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} - engines: {node: ^20.17.0 || >=22.9.0} - nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -3922,125 +3776,6 @@ snapshots: '@iarna/toml@2.2.5': {} - '@inquirer/ansi@2.0.3': {} - - '@inquirer/checkbox@5.0.4(@types/node@25.0.6)': - dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/confirm@6.0.4(@types/node@25.0.6)': - dependencies: - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/core@11.1.1(@types/node@25.0.6)': - dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@25.0.6) - cli-width: 4.1.0 - mute-stream: 3.0.0 - signal-exit: 4.1.0 - wrap-ansi: 9.0.2 - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/editor@5.0.4(@types/node@25.0.6)': - dependencies: - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/external-editor': 2.0.3(@types/node@25.0.6) - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/expand@5.0.4(@types/node@25.0.6)': - dependencies: - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/external-editor@2.0.3(@types/node@25.0.6)': - dependencies: - chardet: 2.1.1 - iconv-lite: 0.7.2 - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/figures@2.0.3': {} - - '@inquirer/input@5.0.4(@types/node@25.0.6)': - dependencies: - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/number@4.0.4(@types/node@25.0.6)': - dependencies: - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/password@5.0.4(@types/node@25.0.6)': - dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/prompts@8.2.0(@types/node@25.0.6)': - dependencies: - '@inquirer/checkbox': 5.0.4(@types/node@25.0.6) - '@inquirer/confirm': 6.0.4(@types/node@25.0.6) - '@inquirer/editor': 5.0.4(@types/node@25.0.6) - '@inquirer/expand': 5.0.4(@types/node@25.0.6) - '@inquirer/input': 5.0.4(@types/node@25.0.6) - '@inquirer/number': 4.0.4(@types/node@25.0.6) - '@inquirer/password': 5.0.4(@types/node@25.0.6) - '@inquirer/rawlist': 5.2.0(@types/node@25.0.6) - '@inquirer/search': 4.1.0(@types/node@25.0.6) - '@inquirer/select': 5.0.4(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/rawlist@5.2.0(@types/node@25.0.6)': - dependencies: - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/search@4.1.0(@types/node@25.0.6)': - dependencies: - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/select@5.0.4(@types/node@25.0.6)': - dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.1(@types/node@25.0.6) - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@25.0.6) - optionalDependencies: - '@types/node': 25.0.6 - - '@inquirer/type@4.0.3(@types/node@25.0.6)': - optionalDependencies: - '@types/node': 25.0.6 - '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.0': @@ -4194,6 +3929,8 @@ snapshots: '@types/minimatch@5.1.2': {} + '@types/minimist@1.2.5': {} + '@types/node-fetch@2.6.13': dependencies: '@types/node': 22.19.5 @@ -4692,8 +4429,6 @@ snapshots: chalk@5.6.2: {} - chardet@2.1.1: {} - chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -4752,8 +4487,6 @@ snapshots: slice-ansi: 7.1.2 string-width: 8.1.0 - cli-width@4.1.0: {} - clipboardy@4.0.0: dependencies: execa: 8.0.1 @@ -4800,8 +4533,6 @@ snapshots: dependencies: delayed-stream: 1.0.0 - commander@14.0.2: {} - concat-map@0.0.1: {} configstore@3.1.5: @@ -6337,8 +6068,6 @@ snapshots: ms@2.1.3: {} - mute-stream@3.0.0: {} - nanoid@3.3.11: {} natural-compare@1.4.0: {} diff --git a/progress.md b/progress.md new file mode 100644 index 000000000..90e97e948 --- /dev/null +++ b/progress.md @@ -0,0 +1,156 @@ +# Progress Log - Assistant Implementation + +## Session: 2026-01-13 + +### Phase 0: Planning & Setup +- **Status:** complete +- **Started:** 2026-01-13 +- Actions taken: + - Explored codebase structure via 3 parallel agents + - Read all .claude/ideas/assistant/00*.md files + - Created comprehensive plan at .claude/plans/encapsulated-gathering-stream.md + - Created Manus-style planning files (task_plan.md, findings.md, progress.md) + - Identified 13 features to implement + - Installed dependencies: @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities, recharts +- Files created/modified: + - .claude/plans/encapsulated-gathering-stream.md (created) + - task_plan.md (created) + - findings.md (created) + - progress.md (created) + - src/dashboard/apps/web/package.json (modified - added deps) + +### Phase 1: Types & Storage (Agent 13) +- **Status:** complete +- **Commit:** aa50cd2 feat(assistant): extend types and storage for Phase 2-3 features +- Actions taken: + - Extended types.ts with all new interfaces + - Created 10 new hooks (useCommunicationLog, useDecisionLog, etc.) + - Extended storage adapter with new methods + - Updated hooks/index.ts exports +- Files created/modified: + - src/lib/assistant/types.ts (extended) + - src/lib/assistant/hooks/*.ts (created 10 new hooks) + - src/lib/assistant/lib/storage/*.ts (extended) + +### Phase 2: Feature Agents (1-12) +- **Status:** complete +- **Started:** 2026-01-13 ~03:24 +- **Completed:** 2026-01-13 ~03:40 +- Actions taken: + - All 12 agents launched in parallel + - All agents completed successfully + - 12 feature commits created +- Files created/modified: + - src/routes/assistant/-components/kanban/*.tsx (Kanban board) + - src/routes/assistant/-components/communication/*.tsx (Communication log) + - src/routes/assistant/-components/decisions/*.tsx (Decision log) + - src/routes/assistant/-components/critical-path/*.tsx (Critical path graph) + - src/routes/assistant/-components/blockers/*.tsx (Blocker detector) + - src/routes/assistant/-components/analytics/*.tsx (Energy heatmap, Weekly review) + - src/routes/assistant/-components/handoff/*.tsx (Handoff compiler) + - src/routes/assistant/-components/escalation/*.tsx (Auto-escalation) + - src/routes/assistant/-components/celebrations/*.tsx (Micro-celebrations) + - src/routes/assistant/-components/badges/*.tsx (Badge progress UI) + - src/routes/assistant/-components/distractions/*.tsx (Distraction tracker) + - src/routes/assistant/tasks/index.tsx (rewritten for Kanban) + - src/routes/assistant/tasks/$taskId.tsx (added dependencies, blockers, handoffs) + - src/routes/assistant/analytics.tsx (integrated all analytics features) + - src/routes/assistant/communication.tsx (new page) + - src/routes/assistant/decisions.tsx (new page) + +### Phase 3: Verification +- **Status:** complete +- Actions taken: + - Verified all 14 commits present + - Fixed TypeScript errors in hooks (string | null issues) + - Created 2 fix commits + - Type check passes for assistant hooks +- Files created/modified: + - src/lib/assistant/hooks/*.ts (null check fixes) + +## Test Results +| Test | Input | Expected | Actual | Status | +|------|-------|----------|--------|--------| +| Kanban drag-drop | Drag task to new column | Status updates | - | needs visual test | +| Communication CRUD | Add new entry | Entry saved | - | needs visual test | +| Decision log | Add decision | Decision saved | - | needs visual test | +| Analytics charts | Open analytics | Charts render | - | needs visual test | +| Type check | bunx tsc --noEmit | No hook errors | 0 hook errors | pass | + +## Error Log +| Timestamp | Error | Attempt | Resolution | +|-----------|-------|---------|------------| +| 2026-01-13 | Template path wrong | 1 | User provided correct nested path | +| 2026-01-13 | string \| null TypeScript errors | 1 | Added currentUserId captures in hooks | + +## 5-Question Reboot Check +| Question | Answer | +|----------|--------| +| Where am I? | Phase 3 - Verification complete | +| Where am I going? | Visual testing, then backend integration | +| What's the goal? | Full 3-phase AI Assistant with Kanban, analytics, etc. | +| What have I learned? | All features use localStorage only - no backend DB yet | +| What have I done? | Implemented all 13 features via parallel agents | + +## Agent Tracking +| Agent | Feature | Status | AgentID | Commit | +|-------|---------|--------|---------|--------| +| 13 | Types & Storage | complete | a31c085 | aa50cd2 | +| 1 | Kanban Board | complete | a420661 | c7320ac | +| 2 | Communication Log | complete | abf59b7 | fb79c59 | +| 3 | Decision Log | complete | a997385 | 403e12e | +| 4 | Critical Path | complete | abafc25 | 9b22893 | +| 5 | Blocker Detector | complete | a0d988a | f79f0bd | +| 6 | Energy Heatmap | complete | a8944cf | b57adfc | +| 7 | Handoff Compiler | complete | a7fba3e | bbdea0c | +| 8 | Auto-Escalation | complete | a2eb7df | 95cd556 | +| 9 | Micro-Celebrations | complete | a70e65c | (bundled with bbdea0c) | +| 10 | Badge Progress UI | complete | a41fd87 | 73c51f0 | +| 11 | Weekly Review | complete | afee0a4 | 5617cd5 | +| 12 | Distraction Tracker | complete | a9c2831 | 7fee535 | + +## Post-Agent Review Checklist +- [x] Check all commits were made (14 feature + 2 fix commits) +- [x] Verify type consistency across features (hooks fixed) +- [x] Check Drizzle schema if needed (currently using localStorage only) +- [x] Run tsc --noEmit for type check (0 hook errors) +- [ ] Test dev server builds (bun run dev) +- [ ] Visual verification of all pages + +## Storage Status +**Database persistence now available!** + +### Completed (2026-01-13) +- [x] 14 Drizzle tables defined in `src/drizzle/schema.ts` +- [x] REST-like server functions in `src/lib/assistant/assistant.server.ts` +- [x] TanStack Query hooks in `src/lib/assistant/hooks/useAssistantQueries.ts` +- [x] Hooks exported from index.ts for gradual migration + +### Architecture +``` +Client (TanStack Query) + ↓ refetchOnWindowFocus +Server Functions (TanStack Start) + ↓ Drizzle ORM +Neon PostgreSQL +``` + +### New Query Hooks Available +- `useAssistantTasksQuery(userId)` - fetch all tasks +- `useCreateAssistantTaskMutation()` - create task +- `useUpdateAssistantTaskMutation()` - update task +- ... (50+ hooks for all 14 tables) + +### Migration Strategy +1. Existing localStorage hooks continue to work +2. Gradually migrate components to use new `*Query` hooks +3. New hooks use server-first with `refetchOnWindowFocus: true` +4. Run `bunx drizzle-kit push` when ready to create DB tables + +### Next Steps +1. Run `bunx drizzle-kit push` to create tables in Neon +2. Migrate components from `useTaskStore` to `useAssistantTasksQuery` +3. Test with real database + +--- +*Updated: 2026-01-13 after database persistence implementation* diff --git a/src/dashboard/.gitignore b/src/dashboard/.gitignore new file mode 100644 index 000000000..79e0077ca --- /dev/null +++ b/src/dashboard/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +node_modules +.pnp +.pnp.js + +# testing +coverage + +# next.js +.next/ +out/ +build +.swc/ + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# turbo +.turbo + +# ui +dist/ diff --git a/src/dashboard/.npmrc b/src/dashboard/.npmrc new file mode 100644 index 000000000..ded82e2f6 --- /dev/null +++ b/src/dashboard/.npmrc @@ -0,0 +1 @@ +auto-install-peers = true diff --git a/src/dashboard/README.md b/src/dashboard/README.md new file mode 100644 index 000000000..438763d56 --- /dev/null +++ b/src/dashboard/README.md @@ -0,0 +1,58 @@ +# Turborepo Tailwind CSS starter + +This Turborepo starter is maintained by the Turborepo core team. + +## Using this example + +Run the following command: + +```sh +npx create-turbo@latest -e with-tailwind +``` + +## What's inside? + +This Turborepo includes the following packages/apps: + +### Apps and Packages + +- `docs`: a [Next.js](https://nextjs.org/) app with [Tailwind CSS](https://tailwindcss.com/) +- `web`: another [Next.js](https://nextjs.org/) app with [Tailwind CSS](https://tailwindcss.com/) +- `ui`: a stub React component library with [Tailwind CSS](https://tailwindcss.com/) shared by both `web` and `docs` applications +- `@repo/eslint-config`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`) +- `@repo/typescript-config`: `tsconfig.json`s used throughout the monorepo + +Each package/app is 100% [TypeScript](https://www.typescriptlang.org/). + +### Building packages/ui + +This example is set up to produce compiled styles for `ui` components into the `dist` directory. The component `.tsx` files are consumed by the Next.js apps directly using `transpilePackages` in `next.config.ts`. This was chosen for several reasons: + +- Make sharing one `tailwind.config.ts` to apps and packages as easy as possible. +- Make package compilation simple by only depending on the Next.js Compiler and `tailwindcss`. +- Ensure Tailwind classes do not overwrite each other. The `ui` package uses a `ui-` prefix for it's classes. +- Maintain clear package export boundaries. + +Another option is to consume `packages/ui` directly from source without building. If using this option, you will need to update the `tailwind.config.ts` in your apps to be aware of your package locations, so it can find all usages of the `tailwindcss` class names for CSS compilation. + +For example, in [tailwind.config.ts](packages/tailwind-config/tailwind.config.ts): + +```js + content: [ + // app content + `src/**/*.{js,ts,jsx,tsx}`, + // include packages if not transpiling + "../../packages/ui/*.{js,ts,jsx,tsx}", + ], +``` + +If you choose this strategy, you can remove the `tailwindcss` and `autoprefixer` dependencies from the `ui` package. + +### Utilities + +This Turborepo has some additional tools already setup for you: + +- [Tailwind CSS](https://tailwindcss.com/) for styles +- [TypeScript](https://www.typescriptlang.org/) for static type checking +- [ESLint](https://eslint.org/) for code linting +- [Prettier](https://prettier.io) for code formatting diff --git a/src/dashboard/apps/docs/.gitignore b/src/dashboard/apps/docs/.gitignore new file mode 100644 index 000000000..1437c53f7 --- /dev/null +++ b/src/dashboard/apps/docs/.gitignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel diff --git a/src/dashboard/apps/docs/README.md b/src/dashboard/apps/docs/README.md new file mode 100644 index 000000000..04c1d97ba --- /dev/null +++ b/src/dashboard/apps/docs/README.md @@ -0,0 +1,28 @@ +## Getting Started + +First, run the development server: + +```bash +yarn dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `src/app/page.tsx`. The page auto-updates as you edit the file. + +To create [API routes](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) add an `api/` directory to the `app/` directory with a `route.ts` file. For individual endpoints, create a subfolder in the `api` directory, like `api/hello/route.ts` would map to [http://localhost:3000/api/hello](http://localhost:3000/api/hello). + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn/foundations/about-nextjs) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_source=github.com&utm_medium=referral&utm_campaign=turborepo-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/src/dashboard/apps/docs/app/favicon.ico b/src/dashboard/apps/docs/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..3f804c026c253d52f61b6f70ec351d1044e6bd8a GIT binary patch literal 8267 zcma)hcQjmI)b^b*7~SY4LI%-BkKUOPCHjn#MD!ZHcS9r@Eus^hh~7oiC_w~4)Tlua zqW2m;zkj~9zCXV8zU!`Y_PYB#&wkFi>#no*IXhBU`ym-I6EOe)Wa?^2{af4dUxO0d z_WE;9gtrD_r=+C>05x$WR~GoU?`&3T`dR=Ga327$5dd&;>%y)BfVU6;{51yv=`;YK zcgt+nlf4}vu+)5r1aAI&a@&d$Z#_hAY9^ilK#usYfzC5_C~uvFUg}yX!Zl)AN`QD? ztH=}p?$)X!mC$}O+gbi;G!sp)f9)O(0<}1%-(vmC#01n;dhERn?&>4Rf@PMDZZSO? zH~K1D??;yT?$O*Ymc@9Bp#|JO8t>bqkp;!wX-HH&r|KNNqVdF!lvyKcZDsQagKV$1EaO>G5b~z{lm=@dy$&R=zMh z$~8;>m{`9UYHRNqtrEIcfH!g!G7_&7)}AYiwGg*jjjhkXeDedLsazlaYV&bda z!kW-UlG`Oz>JSA)xE3IC^@=>QT+)3)yJP7U@qbWLP8^{qW1_A44v1p|#K|5f`uysi z*44qcK=Yv>KpS@8T=vjmJkP=CKKbp^qLMcWLRWFX;y}k!rel4V@f`=FUe0F#?JFfd z41^%9qiC>5&sVcWM1XmqK+v1=*=SsHnofW|qwlM8(FeHj2#ptgSPgRDCdmx+H-n z!gy#1U%256Ke}>>Whht4X$BLi{PH-Pi&&0pBebGnI?vMD*l@)SMeyFV$Ok$$9rK%! z=lN)*h95?5LZ@0#0c->5TC6Wi{2dY?lt20}u?=Wunp&rfFra*c7f|#xZIvCd0#6h}_^^5&RT5KWKWh@1Zd>KLQiPlEtP!{wfoLI^)@EiqLGwx*tT>x8(9a z1B7$K;*Ax|DXZCq7=EU7eE!T;t-f>mINXhs6~s!7^nU_E5IiHe#%~29sN7qF?8mjR zd||&6wwNM*#3ZK^rI=6(0))kmWYvV#3e~JaN#?mNmSjS#evmXgS)OHX-5m}&=$B*e zCtTyEIr&>pc=Whi0SzQ35X6oRFgHt>_qd8->zhEBH{)8LOiqMPFY+#?Asqz~cs^F; ztyyaR_+`tHF{Mn4&mnlL+@rtj2>Yl8Nyo4<$bQ_JxXHtUIYsj{CJBmtal#^JktKXe z5N4Y^6UZcSO7saP-V+dlH9khlBQ}U*FKiZfB4*A-d%smB{LKvV1JNjA0>NBVq*oQA zl{&C;AcW#60^alRT}E++feLl!sDO5DM@UTK*Tmg?KoBci>`1^s@&L#vG|dq)Mpcg; zZsw<|PC4-NKaF+s81xQev7zrBh`@qrduJK}RHmn$dxVQ#Fq5a_Cb0pqz26L*g$%DeqhvF^ zUi*Q7(q~PU2X}-OaX35?F{`Z7t8Z$x7W%3*FywdzqJ4%GVctj_~ z2w|fsrpjQ#C4QKRD;1#cHm=$>={Z;T?In=GEB^bT<9o+Fhbd0f8s0IymivG)@rWRT zwHuu?!EI*Qig;9tC*H@Xi21~E=2w4@A_O{E@MrbeRe|0Yo{k*LQXOB8Nt?+4CpS@S zDLKJi$VHK9DzPQL+k2cW&Bl7<%xk7K@cs%+_r#)AHXiv!qWCt{DRB1-#r2yb@Q&Vu zUi=$*Q+Wb%yoKmO@vcJkm!@;(klfNhDr0?@Y#&qJB1LFqLATN~P$s z;i*4!jO*iF#9K_P=c9@b#uli=Nu$<4r?(oEQ!vf!WdU|cY43|I5_VXJ=Nc#X7M9LP^t%sfHUufWA@EL5HOH_}JWceG^FVMy z4LqW8S9LMs$L!E{4}=iMw(4r5DpH$7u2k<26?BHybziE%hsFGpCX|i7%>uSDd)}(H z_$#1nQ}Ho}LCR|83$OyOho4x2Zz(c8QNWF$QF{~3VqJp&4ndgSb zfm^7Mf%e)Z-@g_+S|lE@EzeqiUA?>2d=DcCgs1lM8*ramnb+fDsN<2o9?175$PltE zt?DDqchcs{>w1i~l!)}F!nm>thwkQ5Iz<6PyR%rgVG;AHe0DxbRb)2k1e~pzcSeo* zxL12GxoWx)`9PKWjyQ-U^v+^rpj}NZ%bNnsx*x&z)Hw<~^5D-H zFZ9QVzMgAYQa}DqOJAdjuC+D0Z?D6fW8gKk)DtEmaiz3C=c3MNkGoSLB2Zcdxo~ft zUSirRA0|zL`^&yODqH-@e!&q|YzvBcR9*fJzU;%#ObtJf$ln@kVSkW-?6tkIM7!Sy zTlg9!S80G&JUq4&b=_S-3K}inQ6iBm3xo}N{H@uk@%1yG0bb6 zEX4y(^jydiE!>!(38th_ITmY*ZheeTxv=DN=1sLmCVZe7F5B&17n)WV^K1m&8jH~dKv!1Xyqo3>nRhqB+y=Z# z^I4G05_K$A5Je43Bl9ItQwB5#_E$ejm57f|`*24+6ZViHctvZOy?p9L{Ju37z}8s*RY+kGst5xt)_qAj)c{ ztAz^*zFdoi=D+t}I*So^e7kmqCNsq6jm}aBn8jEt)V%A2Zbkz_k0YSn-$`|2HFG&g z7nh-@Sxi#wO{Z1@AAEm;RBc}BF(Z8K+m9SfuW4%T{9Vc)o#4iDJYri=Z;2P)^BJ6~ zBGYW){ize)xr2mgE1MY>0LnQJY-%--b6=ZvayYJ1NaQm`c=;X^HsZmM!|qS9jx>sX ztrrKz$v${i@JLq>zJjiXrjN}m=-CITqba(P$t>K6dN)wk_w~QUu8_ox$>r|-fUR2@0Gw=r8*Q57O8pb3JTC+KrtN!V< zSUGOi<^)?@Csm7`5z~`VSP(AGL;BSrn0bbu@HI<$B2gCl?;C*0Gb;YRYSM{4bIX8Eck6yYCRKp;gOU1b`Fd)EmS6N>mRXrXVsJyEg zyM8j=@H8ax903rNIV!-^EgK?fF%|eHTDiq; zhp^|LBrGQvJh@dMxJ2LjgH*-*Eb;`Z6qWgfh4XG9nOzPD@MHOzAs%7;V5OnO3mJ@X zsZ70q|7>iueu_%Ic9%hlAn=`rl-9T$D)N20I!!Rzjrn=4Xu=yACiV%=|h%K$<_;!9qEige-fVkcBBDrq zo5r_3pYI0l!xg>Hqs9VdgiU^xXd8^ZYgdLGj=5A8r^fF2XU!p6sKNp_w@_c<=|7-dm*(T90b^9~S| z20-@aBch&Yt4;RHG1Ki>qZM3<7fvmaiZ6*e`bm1S_0=H8kqKmb0=J|v5{&mQWPmSy zE_(Nvh)#-coS^t+@Zt8^ZE{{cB(5|EHQ$Jt;^|Z^5`|fh-=$ePnpG3fvL|!PD3y*x zQPVdi)rdy^I;i7^!H1_UvYZ1`;ox$2y49{oz$1j1v!s?9=G106yGu_R#t+{GpSJwP zL5~RU8cuvBN?~Nge5WMs{%s31#SX(wkr(Wz?}F5)VPzvSw+#wi z56a0PcrixmL05?Z%cKIa8G-HUK_Z5HqNge%+9E8|H#=uNs#T2oB%s<+tTkb{~-{(F~5C0n3s>K%m;2Tg7hF^N| zw)AdAsf|so-o#^!92#Rs{PuA8k_uC-^Fu^%&y4%EHnTv&{obNaV zFZHG?cvMDlPqr(X%9_Pk)6e%H{2M=}Ql)Zg@_E4IzP`wKOh zqj9_`D6LZ;qI6POX6*=#R#Q4myb#T19EYEv`1H%tj+K{_#HrJ4WJno>svX{6zJDp~ z{44TOu-;K%Y@6bZNLi-#p7n8K0X_q@_!%fEg)i38x!UK``IQ_oQ#0e%#V*9s^^Mh@ z%2Tj$?GxuIY+ReV%pI>3c=QUVnTP85v?tiplYsx`P3?}Wz2Ey@2GQ@uCoVF%SvbWl z*UqdBPkBpPETZYqJ3_{?@#v33NgJ;|3-VgkoIgE@I@oCO5iHW$XK(EZzk-%3$}s2`Xu3Se#7>{UY|FyZXhf0&dKlUFQBUWm{r3Z&`~bzTplvlsoZQi@>8^I^{x^S-iHTC^^^dbESmHI;`+*MtV^Sp*dsU@VDxr}wE!hycaQIN3mL*MuUlFm$3_kHK#DB(>-hQRL(K8sDO}`=lHOnLm+L4xJKQua&fjKrqLa4^IEZ&SqZkU3+o{L_cU#v#i`;B%~on35{~c2{UkJ&XmO&L z_MdTGS>l{9uvT~ZWY6YCpgX!46>k(qg55^0jOY{I&>l;KPDBOw7LzB>9ei-BF0D;b zAu;Yrckq2$Dhgo9FI-&Zx8>>kSanP5ZHDDmLiPDH*q=9NaSaqzAj%d>%{biJ?hrX8 zDo^oq;m9SlkZZ}Fd9N(U#4?;lZ)A}nE~vjV3N>WHgAmrT{<~9Vq2_)b+iB{zm+Q^n zaUkpG*Ti1+8$5Q?1~`is03TQdiB)uYOUhu+nOwpts*P_KKkEOZ|squgjI;hjc5%@?|a6 zbJON+&BZR7l#7l+Lfog9K)7*s+c(xYb)q}I@}Lwd>t~_(ep08GUEGzCdJYVex^*_Y z{9J6K=BVbERrB*W#rVU@rls6p&0D)3#S9?DjMU{b!q6uvVb^J#TA$RE<2gKp{{@1A zq4{4cC}Bl#ME7pH=dl}yXC!T%<~99z8WKAvyWi`|nuC@p(A5J2BcS77@jY6hh~+a6 zg3u?~N`vXOXFhi4MZB>aggSF#d;`|aLwx*dN}H8E9Uu*>AV5;sI!wP6^eZ3Fu4kOcMn zF*$=5;`zJJcXTIps8|}rA$B&E@@Z%7G3|LBu|(DT^93zUp$c5|!&hQQ&L2)F%kDU! zUX`iEdB6DaHUWCw@WF)QO3PrCJfv6z#36UfZMpvLTm#p6%ud0Uei`^VU@V*?Rh?MG zcQ>jYOEfWt9hi3`KR7FLg%UJ3MggfSB%Lg(Y-*_S*F--HkSMfe||GReVjAz zJg7SFTr~y}WqZEviXteD2N@O`wRp@jC1Kt|%Y`MJYxkpsxpbtO@*AW{;`xAMR}g>I;-S zevuN6a0p%v|+ z7wRU1fwxl`@|GKKRdnTE({!<<3CJf+T)YfZ_1*`(1tpQ(fFD>9`|77|^wYO8+d zJKA9z`Vu~bR{Q_TgTzx%d0PwG-p45yWg8|7Q_HfA%32S$Sv7YrzUIvV&A<97Cx$7d7%j=f)}5>dy^T`8%P)e+|W0FRulA{kcsKXYW3dn)ufAZfVfyKEqPB&^_-<@Pz-FV6dc#X+KB zuRi0IciB5H@S}0g_x*%lJe|~rI@mf~|`1ZJ)W9)H6h$|8O=;ry4-V%0dw%8h2R6a%S` zC>JseFEK#uAanaK!M;ztdPjd- zief6z_rk@vN6Ozl$w=i4m(aaipVm@)(3v^^!r4OSZYv6mm+dOj0G$gK<+z<6ip$4#cq5E6cGm!&n>ckCu%gV&aC1e@FL5YDd^^V`?7 zur>2_32@(NQG#pADO_0E@m64+q39!2`FVzLGh2b!;l<5A$M$T&+lm)eJZdZzk76|h z7^&C{d@C#y#)2JXwPvf9>ar~kAzv9&o*HNR7WGk(!D>PE$h0io7v)`&w#BSw`-91f z{y1>sRg~|8)Bi;w`2RwL_iyeg`kt*Gm-OEjv^l*{#$MJIUN+KJ9yYfI5D^j);TIO- z7ZFAai%Sa$Nec_{-S$F4gY9KT{|~|0)!M<<|Nl>DTc+N;B{2S{VBl)&S&z+)#7up*&mr`AlQ!J}qFVjq05#$&HTvkm+l@9Q4yzSB)OfK|)Y a5CHzt!@LfZ#gcC&0Cki$vQpVR{Qm$*Br?$e literal 0 HcmV?d00001 diff --git a/src/dashboard/apps/docs/app/globals.css b/src/dashboard/apps/docs/app/globals.css new file mode 100644 index 000000000..fd853867f --- /dev/null +++ b/src/dashboard/apps/docs/app/globals.css @@ -0,0 +1,26 @@ +@import "tailwindcss"; +@import "@repo/tailwind-config"; + +:root { + --foreground-rgb: 0, 0, 0; + --background-start-rgb: 214, 219, 220; + --background-end-rgb: 255, 255, 255; +} + +@media (prefers-color-scheme: dark) { + :root { + --foreground-rgb: 255, 255, 255; + --background-start-rgb: 0, 0, 0; + --background-end-rgb: 0, 0, 0; + } +} + +body { + color: rgb(var(--foreground-rgb)); + background: linear-gradient( + to bottom, + transparent, + rgb(var(--background-end-rgb)) + ) + rgb(var(--background-start-rgb)); +} diff --git a/src/dashboard/apps/docs/app/layout.tsx b/src/dashboard/apps/docs/app/layout.tsx new file mode 100644 index 000000000..0a1167476 --- /dev/null +++ b/src/dashboard/apps/docs/app/layout.tsx @@ -0,0 +1,19 @@ +import "@repo/ui/styles.css"; +import "./globals.css"; +import type { Metadata } from "next"; +import { Geist } from "next/font/google"; + +const geist = Geist({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "Create Turborepo", + description: "Generated by create turbo", +}; + +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} diff --git a/src/dashboard/apps/docs/app/page.tsx b/src/dashboard/apps/docs/app/page.tsx new file mode 100644 index 000000000..ae9243365 --- /dev/null +++ b/src/dashboard/apps/docs/app/page.tsx @@ -0,0 +1,103 @@ +import { Card } from "@repo/ui/card"; +import { Gradient } from "@repo/ui/gradient"; +import { TurborepoLogo } from "@repo/ui/turborepo-logo"; +import Image from "next/image"; + +const LINKS = [ + { + title: "Docs", + href: "https://turborepo.com/docs", + description: "Find in-depth information about Turborepo features and API.", + }, + { + title: "Learn", + href: "https://turborepo.com/docs/handbook", + description: "Learn more about monorepos with our handbook.", + }, + { + title: "Templates", + href: "https://turborepo.com/docs/getting-started/from-example", + description: "Choose from over 15 examples and deploy with a single click.", + }, + { + title: "Deploy", + href: "https://vercel.com/new", + description: "Instantly deploy your Turborepo to a shareable URL with Vercel.", + }, +]; + +export default function Page() { + return ( +
+
+

+ examples/with-tailwind -  + docs +

+ +
+ +
+
+
+
+ Turborepo +
+
+ +
+ +
+ +
+
+ +
+ + Turborepo logo + + + + + + + + + + +
+
+
+ +
+ {LINKS.map(({ title, href, description }) => ( + + {description} + + ))} +
+
+ ); +} diff --git a/src/dashboard/apps/docs/eslint.config.js b/src/dashboard/apps/docs/eslint.config.js new file mode 100644 index 000000000..e8759ff50 --- /dev/null +++ b/src/dashboard/apps/docs/eslint.config.js @@ -0,0 +1,4 @@ +import { nextJsConfig } from "@repo/eslint-config/next-js"; + +/** @type {import("eslint").Linter.Config} */ +export default nextJsConfig; diff --git a/src/dashboard/apps/docs/next-env.d.ts b/src/dashboard/apps/docs/next-env.d.ts new file mode 100644 index 000000000..c4b7818fb --- /dev/null +++ b/src/dashboard/apps/docs/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +import "./.next/dev/types/routes.d.ts"; + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/src/dashboard/apps/docs/next.config.ts b/src/dashboard/apps/docs/next.config.ts new file mode 100644 index 000000000..9dd42bf36 --- /dev/null +++ b/src/dashboard/apps/docs/next.config.ts @@ -0,0 +1,9 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + typescript: { + ignoreBuildErrors: true, + }, +}; + +export default nextConfig; diff --git a/src/dashboard/apps/docs/package.json b/src/dashboard/apps/docs/package.json new file mode 100644 index 000000000..571e3b327 --- /dev/null +++ b/src/dashboard/apps/docs/package.json @@ -0,0 +1,34 @@ +{ + "name": "docs", + "version": "1.0.0", + "type": "module", + "private": true, + "scripts": { + "dev": "next dev --port 3000", + "build": "next build", + "start": "next start", + "lint": "eslint --max-warnings 0", + "check-types": "next typegen && tsc --noEmit" + }, + "dependencies": { + "@repo/ui": "*", + "next": "16.0.10", + "react": "^19.2.0", + "react-dom": "^19.1.0" + }, + "devDependencies": { + "@next/eslint-plugin-next": "^15.4.6", + "@repo/eslint-config": "*", + "@repo/tailwind-config": "*", + "@repo/typescript-config": "*", + "@tailwindcss/postcss": "^4.1.5", + "@types/node": "^22.15.30", + "@types/react": "^19.1.0", + "@types/react-dom": "^19.1.1", + "autoprefixer": "^10.4.20", + "eslint": "^9.39.1", + "postcss": "^8.5.3", + "tailwindcss": "^4.1.5", + "typescript": "5.9.2" + } +} diff --git a/src/dashboard/apps/docs/postcss.config.js b/src/dashboard/apps/docs/postcss.config.js new file mode 100644 index 000000000..b2391c16c --- /dev/null +++ b/src/dashboard/apps/docs/postcss.config.js @@ -0,0 +1,3 @@ +import { postcssConfig } from "@repo/tailwind-config/postcss"; + +export default postcssConfig; diff --git a/src/dashboard/apps/docs/public/circles.svg b/src/dashboard/apps/docs/public/circles.svg new file mode 100644 index 000000000..6533be5ba --- /dev/null +++ b/src/dashboard/apps/docs/public/circles.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/dashboard/apps/docs/public/next.svg b/src/dashboard/apps/docs/public/next.svg new file mode 100644 index 000000000..5174b28c5 --- /dev/null +++ b/src/dashboard/apps/docs/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dashboard/apps/docs/public/turborepo.svg b/src/dashboard/apps/docs/public/turborepo.svg new file mode 100644 index 000000000..2f9aa1f37 --- /dev/null +++ b/src/dashboard/apps/docs/public/turborepo.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/dashboard/apps/docs/public/vercel.svg b/src/dashboard/apps/docs/public/vercel.svg new file mode 100644 index 000000000..d2f842227 --- /dev/null +++ b/src/dashboard/apps/docs/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dashboard/apps/docs/tsconfig.json b/src/dashboard/apps/docs/tsconfig.json new file mode 100644 index 000000000..df214c3cd --- /dev/null +++ b/src/dashboard/apps/docs/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "@repo/typescript-config/nextjs.json", + "compilerOptions": { + "plugins": [ + { + "name": "next" + } + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + "next-env.d.ts", + "next.config.ts", + ".next/types/**/*.ts" + ], + "exclude": ["node_modules"] +} diff --git a/src/dashboard/apps/server/.env.example b/src/dashboard/apps/server/.env.example new file mode 100644 index 000000000..d82ea2a49 --- /dev/null +++ b/src/dashboard/apps/server/.env.example @@ -0,0 +1,11 @@ +# Nitro Server Environment Variables + +# WorkOS API Key for server-side authentication +# Get this from WorkOS dashboard: https://dashboard.workos.com/ +WORKOS_API_KEY=sk_test_... + +# Server port +PORT=4000 + +# Environment +NODE_ENV=development diff --git a/src/dashboard/apps/server/.gitignore b/src/dashboard/apps/server/.gitignore new file mode 100644 index 000000000..d547d8a26 --- /dev/null +++ b/src/dashboard/apps/server/.gitignore @@ -0,0 +1,8 @@ +node_modules +dist +.data +.nitro +.cache +.output +.env +.env.local diff --git a/src/dashboard/apps/server/README.md b/src/dashboard/apps/server/README.md new file mode 100644 index 000000000..b161ee5d4 --- /dev/null +++ b/src/dashboard/apps/server/README.md @@ -0,0 +1,3 @@ +# Nitro starter + +Look at the [nitro quick start](https://nitro.build/guide#quick-start) to learn more how to get started. diff --git a/src/dashboard/apps/server/nitro.config.ts b/src/dashboard/apps/server/nitro.config.ts new file mode 100644 index 000000000..e7bb4d1c4 --- /dev/null +++ b/src/dashboard/apps/server/nitro.config.ts @@ -0,0 +1,8 @@ +import { defineNitroConfig } from "nitropack/config"; + +// https://nitro.build/config +export default defineNitroConfig({ + compatibilityDate: "latest", + srcDir: "server", + imports: false, +}); diff --git a/src/dashboard/apps/server/package.json b/src/dashboard/apps/server/package.json new file mode 100644 index 000000000..95315b8bd --- /dev/null +++ b/src/dashboard/apps/server/package.json @@ -0,0 +1,20 @@ +{ + "name": "@dashboard/server", + "private": true, + "type": "module", + "scripts": { + "build": "nitro build", + "dev": "nitro dev --port 4000", + "preview": "node .output/server/index.mjs" + }, + "dependencies": { + "@workos-inc/node": "8.0.0-rc.10", + "@dashboard/shared": "workspace:*" + }, + "devDependencies": { + "@repo/typescript-config": "workspace:*", + "h3": "^1.15.4", + "nitropack": "^2.12.4", + "typescript": "^5.9.2" + } +} diff --git a/src/dashboard/apps/server/server/routes/_ws.ts b/src/dashboard/apps/server/server/routes/_ws.ts new file mode 100644 index 000000000..86f3813c7 --- /dev/null +++ b/src/dashboard/apps/server/server/routes/_ws.ts @@ -0,0 +1,91 @@ +import { WS_EVENTS } from "@dashboard/shared"; +import { defineWebSocketHandler } from "h3"; + +interface Client { + id: string; + userId?: string; + peer: unknown; +} + +const clients = new Map(); + +export default defineWebSocketHandler({ + open(peer) { + const clientId = `client_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`; + clients.set(clientId, { id: clientId, peer }); + + console.log(`[WebSocket] Client connected: ${clientId}`); + + // Send welcome message + peer.send( + JSON.stringify({ + type: "connected", + clientId, + timestamp: new Date().toISOString(), + }) + ); + }, + + message(peer, message) { + try { + const data = JSON.parse(message.text()); + const { type, payload } = data; + + console.log(`[WebSocket] Received message: ${type}`); + + switch (type) { + case WS_EVENTS.TIMER_UPDATE: + case WS_EVENTS.TIMER_CREATE: + case WS_EVENTS.TIMER_DELETE: + // Broadcast timer changes to all connected clients except sender + broadcastToOthers(peer, data); + break; + + case WS_EVENTS.SYNC_REQUEST: + // Handle sync request + peer.send( + JSON.stringify({ + type: WS_EVENTS.SYNC_RESPONSE, + timestamp: new Date().toISOString(), + message: "Sync request received", + }) + ); + break; + + default: + console.log(`[WebSocket] Unknown message type: ${type}`); + } + } catch (error) { + console.error("[WebSocket] Error parsing message:", error); + } + }, + + close(peer) { + // Find and remove the client + for (const [clientId, client] of clients.entries()) { + if (client.peer === peer) { + clients.delete(clientId); + console.log(`[WebSocket] Client disconnected: ${clientId}`); + break; + } + } + }, + + error(_peer, error) { + console.error("[WebSocket] Error:", error); + }, +}); + +function broadcastToOthers(sender: unknown, message: unknown) { + const messageStr = JSON.stringify(message); + + for (const client of clients.values()) { + if (client.peer !== sender) { + try { + (client.peer as { send: (msg: string) => void }).send(messageStr); + } catch (error) { + console.error(`[WebSocket] Failed to send to client ${client.id}:`, error); + } + } + } +} diff --git a/src/dashboard/apps/server/server/routes/api/health.ts b/src/dashboard/apps/server/server/routes/api/health.ts new file mode 100644 index 000000000..519e2370e --- /dev/null +++ b/src/dashboard/apps/server/server/routes/api/health.ts @@ -0,0 +1,10 @@ +import { eventHandler } from "h3"; + +export default eventHandler(() => { + return { + status: "healthy", + timestamp: new Date().toISOString(), + service: "@dashboard/server", + version: "0.0.1", + }; +}); diff --git a/src/dashboard/apps/server/server/routes/api/sync/upload.ts b/src/dashboard/apps/server/server/routes/api/sync/upload.ts new file mode 100644 index 000000000..08b23f530 --- /dev/null +++ b/src/dashboard/apps/server/server/routes/api/sync/upload.ts @@ -0,0 +1,69 @@ +import { createError, eventHandler, readBody } from "h3"; + +interface CrudOperation { + op: "PUT" | "PATCH" | "DELETE"; + type: string; + id: string; + data?: Record; +} + +interface CrudBatch { + crud: CrudOperation[]; +} + +export default eventHandler(async (event) => { + try { + const body = await readBody(event); + + if (!body.crud || !Array.isArray(body.crud)) { + throw createError({ + statusCode: 400, + statusMessage: "Bad Request", + message: "Invalid sync payload: expected { crud: CrudOperation[] }", + }); + } + + console.log(`[Sync] Received ${body.crud.length} operations`); + + // Process each operation + const results: { id: string; success: boolean; error?: string }[] = []; + + for (const op of body.crud) { + try { + // TODO: Apply operations to database + // For now, just log and acknowledge + console.log(`[Sync] ${op.op} ${op.type}/${op.id}`); + + results.push({ + id: op.id, + success: true, + }); + } catch (error) { + results.push({ + id: op.id, + success: false, + error: error instanceof Error ? error.message : "Unknown error", + }); + } + } + + const successCount = results.filter((r) => r.success).length; + const failureCount = results.filter((r) => !r.success).length; + + return { + success: failureCount === 0, + processed: body.crud.length, + succeeded: successCount, + failed: failureCount, + results, + timestamp: new Date().toISOString(), + }; + } catch (error) { + console.error("[Sync] Upload error:", error); + throw createError({ + statusCode: 500, + statusMessage: "Internal Server Error", + message: error instanceof Error ? error.message : "Sync upload failed", + }); + } +}); diff --git a/src/dashboard/apps/server/server/routes/api/timers/[id].ts b/src/dashboard/apps/server/server/routes/api/timers/[id].ts new file mode 100644 index 000000000..c1399c1d6 --- /dev/null +++ b/src/dashboard/apps/server/server/routes/api/timers/[id].ts @@ -0,0 +1,85 @@ +import type { SerializedTimer } from "@dashboard/shared"; +import { createError, eventHandler, getMethod, getRouterParam, readBody } from "h3"; + +// In-memory store (shared with index.ts - will be refactored to use a proper store) +const timers = new Map(); + +export default eventHandler(async (event) => { + const method = getMethod(event); + const id = getRouterParam(event, "id"); + + if (!id) { + throw createError({ + statusCode: 400, + statusMessage: "Bad Request", + message: "Timer ID is required", + }); + } + + // GET /api/timers/:id - Get a specific timer + if (method === "GET") { + const timer = timers.get(id); + + if (!timer) { + throw createError({ + statusCode: 404, + statusMessage: "Not Found", + message: `Timer with ID ${id} not found`, + }); + } + + return { timer }; + } + + // PUT /api/timers/:id - Update a timer + if (method === "PUT") { + const timer = timers.get(id); + + if (!timer) { + throw createError({ + statusCode: 404, + statusMessage: "Not Found", + message: `Timer with ID ${id} not found`, + }); + } + + const body = await readBody>(event); + + const updatedTimer: SerializedTimer = { + ...timer, + ...body, + id, // Ensure ID cannot be changed + updated_at: new Date().toISOString(), + }; + + timers.set(id, updatedTimer); + + return { + success: true, + timer: updatedTimer, + }; + } + + // DELETE /api/timers/:id - Delete a timer + if (method === "DELETE") { + const existed = timers.delete(id); + + if (!existed) { + throw createError({ + statusCode: 404, + statusMessage: "Not Found", + message: `Timer with ID ${id} not found`, + }); + } + + return { + success: true, + message: `Timer ${id} deleted`, + }; + } + + throw createError({ + statusCode: 405, + statusMessage: "Method Not Allowed", + }); +}); diff --git a/src/dashboard/apps/server/server/routes/api/timers/index.ts b/src/dashboard/apps/server/server/routes/api/timers/index.ts new file mode 100644 index 000000000..6b52f7238 --- /dev/null +++ b/src/dashboard/apps/server/server/routes/api/timers/index.ts @@ -0,0 +1,56 @@ +import type { SerializedTimer } from "@dashboard/shared"; +import { createError, eventHandler, getMethod, readBody } from "h3"; + +// In-memory store for timers (will be replaced with database later) +const timers = new Map(); + +export default eventHandler(async (event) => { + const method = getMethod(event); + + // GET /api/timers - List all timers + if (method === "GET") { + return { + timers: Array.from(timers.values()), + total: timers.size, + }; + } + + // POST /api/timers - Create a new timer + if (method === "POST") { + const body = await readBody>(event); + + if (!body.name) { + throw createError({ + statusCode: 400, + statusMessage: "Bad Request", + message: "Timer name is required", + }); + } + + const now = new Date().toISOString(); + const timer: SerializedTimer = { + id: `timer_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`, + name: body.name, + type: body.type || "stopwatch", + is_running: 0, + paused_time: 0, + countdown_duration: body.countdown_duration || 0, + laps: "[]", + user_id: body.user_id || "anonymous", + created_at: now, + updated_at: now, + }; + + timers.set(timer.id, timer); + + return { + success: true, + timer, + }; + } + + throw createError({ + statusCode: 405, + statusMessage: "Method Not Allowed", + }); +}); diff --git a/src/dashboard/apps/server/server/routes/api/user.ts b/src/dashboard/apps/server/server/routes/api/user.ts new file mode 100644 index 000000000..9f0047962 --- /dev/null +++ b/src/dashboard/apps/server/server/routes/api/user.ts @@ -0,0 +1,24 @@ +import { createError, eventHandler, getHeader } from "h3"; + +export default eventHandler(async (event) => { + // Get authorization header + const authHeader = getHeader(event, "authorization"); + + if (!authHeader || !authHeader.startsWith("Bearer ")) { + throw createError({ + statusCode: 401, + statusMessage: "Unauthorized", + message: "Missing or invalid authorization header", + }); + } + + // TODO: Verify WorkOS token and return user info + // For now, return a placeholder + return { + id: "user_placeholder", + email: "user@example.com", + name: "Dashboard User", + authenticated: false, + message: "WorkOS token verification not yet implemented", + }; +}); diff --git a/src/dashboard/apps/server/server/routes/index.ts b/src/dashboard/apps/server/server/routes/index.ts new file mode 100644 index 000000000..2a66c54eb --- /dev/null +++ b/src/dashboard/apps/server/server/routes/index.ts @@ -0,0 +1,11 @@ +import { eventHandler } from "h3"; + +// Learn more: https://nitro.build/guide/routing +export default eventHandler((_event) => { + return ` + +

This is your brand new Nitro project 🚀

+

Get started by editing the server/routes/index.ts file.

+

Learn more from 📖 Nitro Documentation

+ `; +}); diff --git a/src/dashboard/apps/server/tsconfig.json b/src/dashboard/apps/server/tsconfig.json new file mode 100644 index 000000000..5202ee290 --- /dev/null +++ b/src/dashboard/apps/server/tsconfig.json @@ -0,0 +1,32 @@ +{ + // https://nitro.build/guide/typescript + // "extends": "./.nitro/types/tsconfig.json", + "compilerOptions": { + // Module resolution + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "Bundler", + "jsx": "preserve", + "jsxFactory": "h", + "jsxFragmentFactory": "Fragment", + + // Core checks + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + + // Additional safety + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "useUnknownInCatchVariables": true, + "noUnusedLocals": true, + // "noUnusedParameters": true, + + // Libs & paths + "lib": ["ESNext", "DOM"], + "baseUrl": ".", + } +} diff --git a/src/dashboard/apps/web-template/.cta.json b/src/dashboard/apps/web-template/.cta.json new file mode 100644 index 000000000..a4680c3e7 --- /dev/null +++ b/src/dashboard/apps/web-template/.cta.json @@ -0,0 +1,30 @@ +{ + "projectName": "tanstack-start", + "mode": "file-router", + "typescript": true, + "tailwind": true, + "packageManager": "pnpm", + "addOnOptions": {}, + "git": true, + "version": 1, + "framework": "react-cra", + "chosenAddOns": [ + "biome", + "nitro", + "start", + "workos", + "convex", + "compiler", + "db", + "form", + "mcp", + "shadcn", + "t3env", + "table", + "tanstack-query", + "neon", + "tRPC", + "store", + "tanchat" + ] +} \ No newline at end of file diff --git a/src/dashboard/apps/web-template/.cursorrules b/src/dashboard/apps/web-template/.cursorrules new file mode 100644 index 000000000..a561594a1 --- /dev/null +++ b/src/dashboard/apps/web-template/.cursorrules @@ -0,0 +1,100 @@ +This document serves as some special instructions when working with Convex. + +# Schemas + +When designing the schema please see this page on built in System fields and data types available: https://docs.convex.dev/database/types + +Here are some specifics that are often mishandled: + +## v (https://docs.convex.dev/api/modules/values#v) + +The validator builder. + +This builder allows you to build validators for Convex values. + +Validators can be used in schema definitions and as input validators for Convex functions. + +Type declaration +Name Type +id (tableName: TableName) => VId, "required"> +null () => VNull +number () => VFloat64 +float64 () => VFloat64 +bigint () => VInt64 +int64 () => VInt64 +boolean () => VBoolean +string () => VString +bytes () => VBytes +literal (literal: T) => VLiteral +array (element: T) => VArray +object (fields: T) => VObject, undefined> } & { [Property in string | number | symbol]: Infer }>, T, "required", { [Property in string | number | symbol]: Property | `${Property & string}.${T[Property]["fieldPaths"]}` }[keyof T] & string> +record (keys: Key, values: Value) => VRecord, Value["type"]>, Key, Value, "required", string> +union (...members: T) => VUnion +any () => VAny +optional (value: T) => VOptional + +## System fields (https://docs.convex.dev/database/types#system-fields) + +Every document in Convex has two automatically-generated system fields: + +_id: The document ID of the document. +_creationTime: The time this document was created, in milliseconds since the Unix epoch. + +You do not need to add indices as these are added automatically. + +## Example Schema + +This is an example of a well crafted schema. + +```ts +import { defineSchema, defineTable } from "convex/server"; +import { v } from "convex/values"; + +export default defineSchema( + { + users: defineTable({ + name: v.string(), + }), + + sessions: defineTable({ + userId: v.id("users"), + sessionId: v.string(), + }).index("sessionId", ["sessionId"]), + + threads: defineTable({ + uuid: v.string(), + summary: v.optional(v.string()), + summarizer: v.optional(v.id("_scheduled_functions")), + }).index("uuid", ["uuid"]), + + messages: defineTable({ + message: v.string(), + threadId: v.id("threads"), + author: v.union( + v.object({ + role: v.literal("system"), + }), + v.object({ + role: v.literal("assistant"), + context: v.array(v.id("messages")), + model: v.optional(v.string()), + }), + v.object({ + role: v.literal("user"), + userId: v.id("users"), + }), + ), + }) + .index("threadId", ["threadId"]), + }, +); +``` + +Sourced from: https://github.com/PatrickJS/awesome-cursorrules/blob/main/rules/convex-cursorrules-prompt-file/.cursorrules +# shadcn instructions + +Use the latest version of Shadcn to install new components, like this command to add a button component: + +```bash +pnpm dlx shadcn@latest add button +``` diff --git a/src/dashboard/apps/web-template/.env.example b/src/dashboard/apps/web-template/.env.example new file mode 100644 index 000000000..3bc2b0761 --- /dev/null +++ b/src/dashboard/apps/web-template/.env.example @@ -0,0 +1,4 @@ +# These will be automatically created by Neon Launchpad (https://neon.new). +# You will also need to +VITE_DATABASE_URL= +VITE_DATABASE_URL_POOLER= diff --git a/src/dashboard/apps/web-template/.gitignore b/src/dashboard/apps/web-template/.gitignore new file mode 100644 index 000000000..00a21bf52 --- /dev/null +++ b/src/dashboard/apps/web-template/.gitignore @@ -0,0 +1,14 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local +count.txt +.env +.nitro +.tanstack +.wrangler +.output +.vinxi +todos.json +mcp-todos.json \ No newline at end of file diff --git a/src/dashboard/apps/web-template/.vscode/settings.json b/src/dashboard/apps/web-template/.vscode/settings.json new file mode 100644 index 000000000..70dd163cc --- /dev/null +++ b/src/dashboard/apps/web-template/.vscode/settings.json @@ -0,0 +1,35 @@ +{ + "files.watcherExclude": { + "**/routeTree.gen.ts": true + }, + "search.exclude": { + "**/routeTree.gen.ts": true + }, + "files.readonlyInclude": { + "**/routeTree.gen.ts": true + }, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[css]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "source.organizeImports.biome": "explicit" + } +} diff --git a/src/dashboard/apps/web-template/README.md b/src/dashboard/apps/web-template/README.md new file mode 100644 index 000000000..cec584db4 --- /dev/null +++ b/src/dashboard/apps/web-template/README.md @@ -0,0 +1,387 @@ +Welcome to your new TanStack app! + +# Getting Started + +To run this application: + +```bash +pnpm install +pnpm dev +``` + +# Building For Production + +To build this application for production: + +```bash +pnpm build +``` + +## Testing + +This project uses [Vitest](https://vitest.dev/) for testing. You can run the tests with: + +```bash +pnpm test +``` + +## Styling + +This project uses [Tailwind CSS](https://tailwindcss.com/) for styling. + + +## Linting & Formatting + +This project uses [Biome](https://biomejs.dev/) for linting and formatting. The following scripts are available: + + +```bash +pnpm lint +pnpm format +pnpm check +``` + + +## Setting up WorkOS + +- Set the `VITE_WORKOS_CLIENT_ID` in your `.env.local`. + + +## Setting up Convex + +- Set the `VITE_CONVEX_URL` and `CONVEX_DEPLOYMENT` environment variables in your `.env.local`. (Or run `npx convex init` to set them automatically.) +- Run `npx convex dev` to start the Convex server. + + +## Shadcn + +Add components using the latest version of [Shadcn](https://ui.shadcn.com/). + +```bash +pnpm dlx shadcn@latest add button +``` + + +## T3Env + +- You can use T3Env to add type safety to your environment variables. +- Add Environment variables to the `src/env.mjs` file. +- Use the environment variables in your code. + +### Usage + +```ts +import { env } from "@/env"; + +console.log(env.VITE_APP_TITLE); +``` + + + + + +## Setting up Neon + +When running the `dev` command, the `@neondatabase/vite-plugin-postgres` will identify there is not a database setup. It will then create and seed a claimable database. + +It is the same process as [Neon Launchpad](https://neon.new). + +> [!IMPORTANT] +> Claimable databases expire in 72 hours. + + +# TanStack Chat Application + +Am example chat application built with TanStack Start, TanStack Store, and Claude AI. + +## .env Updates + +```env +ANTHROPIC_API_KEY=your_anthropic_api_key +``` + +## ✨ Features + +### AI Capabilities +- 🤖 Powered by Claude 3.5 Sonnet +- 📝 Rich markdown formatting with syntax highlighting +- 🎯 Customizable system prompts for tailored AI behavior +- 🔄 Real-time message updates and streaming responses (coming soon) + +### User Experience +- 🎨 Modern UI with Tailwind CSS and Lucide icons +- 🔍 Conversation management and history +- 🔐 Secure API key management +- 📋 Markdown rendering with code highlighting + +### Technical Features +- 📦 Centralized state management with TanStack Store +- 🔌 Extensible architecture for multiple AI providers +- 🛠️ TypeScript for type safety + +## Architecture + +### Tech Stack +- **Frontend Framework**: TanStack Start +- **Routing**: TanStack Router +- **State Management**: TanStack Store +- **Styling**: Tailwind CSS +- **AI Integration**: Anthropic's Claude API + + +## Routing +This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a file based router. Which means that the routes are managed as files in `src/routes`. + +### Adding A Route + +To add a new route to your application just add another a new file in the `./src/routes` directory. + +TanStack will automatically generate the content of the route file for you. + +Now that you have two routes you can use a `Link` component to navigate between them. + +### Adding Links + +To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`. + +```tsx +import { Link } from "@tanstack/react-router"; +``` + +Then anywhere in your JSX you can use it like so: + +```tsx +About +``` + +This will create a link that will navigate to the `/about` route. + +More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent). + +### Using A Layout + +In the File Based Routing setup the layout is located in `src/routes/__root.tsx`. Anything you add to the root route will appear in all the routes. The route content will appear in the JSX where you use the `` component. + +Here is an example layout that includes a header: + +```tsx +import { Outlet, createRootRoute } from '@tanstack/react-router' +import { TanStackRouterDevtools } from '@tanstack/react-router-devtools' + +import { Link } from "@tanstack/react-router"; + +export const Route = createRootRoute({ + component: () => ( + <> +
+ +
+ + + + ), +}) +``` + +The `` component is not required so you can remove it if you don't want it in your layout. + +More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts). + + +## Data Fetching + +There are multiple ways to fetch data in your application. You can use TanStack Query to fetch data from a server. But you can also use the `loader` functionality built into TanStack Router to load the data for a route before it's rendered. + +For example: + +```tsx +const peopleRoute = createRoute({ + getParentRoute: () => rootRoute, + path: "/people", + loader: async () => { + const response = await fetch("https://swapi.dev/api/people"); + return response.json() as Promise<{ + results: { + name: string; + }[]; + }>; + }, + component: () => { + const data = peopleRoute.useLoaderData(); + return ( +
    + {data.results.map((person) => ( +
  • {person.name}
  • + ))} +
+ ); + }, +}); +``` + +Loaders simplify your data fetching logic dramatically. Check out more information in the [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters). + +### React-Query + +React-Query is an excellent addition or alternative to route loading and integrating it into you application is a breeze. + +First add your dependencies: + +```bash +pnpm add @tanstack/react-query @tanstack/react-query-devtools +``` + +Next we'll need to create a query client and provider. We recommend putting those in `main.tsx`. + +```tsx +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; + +// ... + +const queryClient = new QueryClient(); + +// ... + +if (!rootElement.innerHTML) { + const root = ReactDOM.createRoot(rootElement); + + root.render( + + + + ); +} +``` + +You can also add TanStack Query Devtools to the root route (optional). + +```tsx +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; + +const rootRoute = createRootRoute({ + component: () => ( + <> + + + + + ), +}); +``` + +Now you can use `useQuery` to fetch your data. + +```tsx +import { useQuery } from "@tanstack/react-query"; + +import "./App.css"; + +function App() { + const { data } = useQuery({ + queryKey: ["people"], + queryFn: () => + fetch("https://swapi.dev/api/people") + .then((res) => res.json()) + .then((data) => data.results as { name: string }[]), + initialData: [], + }); + + return ( +
+
    + {data.map((person) => ( +
  • {person.name}
  • + ))} +
+
+ ); +} + +export default App; +``` + +You can find out everything you need to know on how to use React-Query in the [React-Query documentation](https://tanstack.com/query/latest/docs/framework/react/overview). + +## State Management + +Another common requirement for React applications is state management. There are many options for state management in React. TanStack Store provides a great starting point for your project. + +First you need to add TanStack Store as a dependency: + +```bash +pnpm add @tanstack/store +``` + +Now let's create a simple counter in the `src/App.tsx` file as a demonstration. + +```tsx +import { useStore } from "@tanstack/react-store"; +import { Store } from "@tanstack/store"; +import "./App.css"; + +const countStore = new Store(0); + +function App() { + const count = useStore(countStore); + return ( +
+ +
+ ); +} + +export default App; +``` + +One of the many nice features of TanStack Store is the ability to derive state from other state. That derived state will update when the base state updates. + +Let's check this out by doubling the count using derived state. + +```tsx +import { useStore } from "@tanstack/react-store"; +import { Store, Derived } from "@tanstack/store"; +import "./App.css"; + +const countStore = new Store(0); + +const doubledStore = new Derived({ + fn: () => countStore.state * 2, + deps: [countStore], +}); +doubledStore.mount(); + +function App() { + const count = useStore(countStore); + const doubledCount = useStore(doubledStore); + + return ( +
+ +
Doubled - {doubledCount}
+
+ ); +} + +export default App; +``` + +We use the `Derived` class to create a new store that is derived from another store. The `Derived` class has a `mount` method that will start the derived store updating. + +Once we've created the derived store we can use it in the `App` component just like we would any other store using the `useStore` hook. + +You can find out everything you need to know on how to use TanStack Store in the [TanStack Store documentation](https://tanstack.com/store/latest). + +# Demo files + +Files prefixed with `demo` can be safely deleted. They are there to provide a starting point for you to play around with the features you've installed. + +# Learn More + +You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com). diff --git a/src/dashboard/apps/web-template/components.json b/src/dashboard/apps/web-template/components.json new file mode 100644 index 000000000..6998bdfb9 --- /dev/null +++ b/src/dashboard/apps/web-template/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/styles.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/src/dashboard/apps/web-template/convex/_generated/api.d.ts b/src/dashboard/apps/web-template/convex/_generated/api.d.ts new file mode 100644 index 000000000..633bc9b60 --- /dev/null +++ b/src/dashboard/apps/web-template/convex/_generated/api.d.ts @@ -0,0 +1,26 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import type { ApiFromModules, FilterApi, FunctionReference } from "convex/server"; +import type * as todos from "../todos.js"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +declare const fullApi: ApiFromModules<{ + todos: typeof todos; +}>; +export declare const api: FilterApi>; +export declare const internal: FilterApi>; diff --git a/src/dashboard/apps/web-template/convex/_generated/api.js b/src/dashboard/apps/web-template/convex/_generated/api.js new file mode 100644 index 000000000..3f9c482df --- /dev/null +++ b/src/dashboard/apps/web-template/convex/_generated/api.js @@ -0,0 +1,22 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { anyApi } from "convex/server"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +export const api = anyApi; +export const internal = anyApi; diff --git a/src/dashboard/apps/web-template/convex/_generated/dataModel.d.ts b/src/dashboard/apps/web-template/convex/_generated/dataModel.d.ts new file mode 100644 index 000000000..2d358e14b --- /dev/null +++ b/src/dashboard/apps/web-template/convex/_generated/dataModel.d.ts @@ -0,0 +1,56 @@ +/* eslint-disable */ +/** + * Generated data model types. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import type { + DataModelFromSchemaDefinition, + DocumentByName, + TableNamesInDataModel, + SystemTableNames, +} from "convex/server"; +import type { GenericId } from "convex/values"; +import schema from "../schema.js"; + +/** + * The names of all of your Convex tables. + */ +export type TableNames = TableNamesInDataModel; + +/** + * The type of a document stored in Convex. + * + * @typeParam TableName - A string literal type of the table name (like "users"). + */ +export type Doc = DocumentByName; + +/** + * An identifier for a document in Convex. + * + * Convex documents are uniquely identified by their `Id`, which is accessible + * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids). + * + * Documents can be loaded using `db.get(id)` in query and mutation functions. + * + * IDs are just strings at runtime, but this type can be used to distinguish them from other + * strings when type checking. + * + * @typeParam TableName - A string literal type of the table name (like "users"). + */ +export type Id = GenericId; + +/** + * A type describing your Convex data model. + * + * This type includes information about what tables you have, the type of + * documents stored in those tables, and the indexes defined on them. + * + * This type is used to parameterize methods like `queryGeneric` and + * `mutationGeneric` to make them type-safe. + */ +export type DataModel = DataModelFromSchemaDefinition; diff --git a/src/dashboard/apps/web-template/convex/_generated/server.d.ts b/src/dashboard/apps/web-template/convex/_generated/server.d.ts new file mode 100644 index 000000000..4355f8141 --- /dev/null +++ b/src/dashboard/apps/web-template/convex/_generated/server.d.ts @@ -0,0 +1,142 @@ +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + ActionBuilder, + HttpActionBuilder, + MutationBuilder, + QueryBuilder, + GenericActionCtx, + GenericMutationCtx, + GenericQueryCtx, + GenericDatabaseReader, + GenericDatabaseWriter, +} from "convex/server"; +import type { DataModel } from "./dataModel.js"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const query: QueryBuilder; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const internalQuery: QueryBuilder; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const mutation: MutationBuilder; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const internalMutation: MutationBuilder; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export declare const action: ActionBuilder; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export declare const internalAction: ActionBuilder; + +/** + * Define an HTTP action. + * + * This function will be used to respond to HTTP requests received by a Convex + * deployment if the requests matches the path and method where this action + * is routed. Be sure to route your action in `convex/http.js`. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up. + */ +export declare const httpAction: HttpActionBuilder; + +/** + * A set of services for use within Convex query functions. + * + * The query context is passed as the first argument to any Convex query + * function run on the server. + * + * This differs from the {@link MutationCtx} because all of the services are + * read-only. + */ +export type QueryCtx = GenericQueryCtx; + +/** + * A set of services for use within Convex mutation functions. + * + * The mutation context is passed as the first argument to any Convex mutation + * function run on the server. + */ +export type MutationCtx = GenericMutationCtx; + +/** + * A set of services for use within Convex action functions. + * + * The action context is passed as the first argument to any Convex action + * function run on the server. + */ +export type ActionCtx = GenericActionCtx; + +/** + * An interface to read from the database within Convex query functions. + * + * The two entry points are {@link DatabaseReader.get}, which fetches a single + * document by its {@link Id}, or {@link DatabaseReader.query}, which starts + * building a query. + */ +export type DatabaseReader = GenericDatabaseReader; + +/** + * An interface to read from and write to the database within Convex mutation + * functions. + * + * Convex guarantees that all writes within a single mutation are + * executed atomically, so you never have to worry about partial writes leaving + * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control) + * for the guarantees Convex provides your functions. + */ +export type DatabaseWriter = GenericDatabaseWriter; diff --git a/src/dashboard/apps/web-template/convex/_generated/server.js b/src/dashboard/apps/web-template/convex/_generated/server.js new file mode 100644 index 000000000..33c65211a --- /dev/null +++ b/src/dashboard/apps/web-template/convex/_generated/server.js @@ -0,0 +1,89 @@ +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + actionGeneric, + httpActionGeneric, + internalActionGeneric, + internalMutationGeneric, + internalQueryGeneric, + mutationGeneric, + queryGeneric, +} from "convex/server"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const query = queryGeneric; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const internalQuery = internalQueryGeneric; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const mutation = mutationGeneric; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const internalMutation = internalMutationGeneric; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export const action = actionGeneric; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export const internalAction = internalActionGeneric; + +/** + * Define a Convex HTTP action. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument, and a `Request` object + * as its second. + * @returns The wrapped endpoint function. Route a URL path to this function in `convex/http.js`. + */ +export const httpAction = httpActionGeneric; diff --git a/src/dashboard/apps/web-template/convex/schema.ts b/src/dashboard/apps/web-template/convex/schema.ts new file mode 100644 index 000000000..0bfb44680 --- /dev/null +++ b/src/dashboard/apps/web-template/convex/schema.ts @@ -0,0 +1,14 @@ +import { defineSchema, defineTable } from "convex/server"; +import { v } from "convex/values"; + +export default defineSchema({ + products: defineTable({ + title: v.string(), + imageId: v.string(), + price: v.number(), + }), + todos: defineTable({ + text: v.string(), + completed: v.boolean(), + }), +}); diff --git a/src/dashboard/apps/web-template/convex/todos.ts b/src/dashboard/apps/web-template/convex/todos.ts new file mode 100644 index 000000000..38e414705 --- /dev/null +++ b/src/dashboard/apps/web-template/convex/todos.ts @@ -0,0 +1,39 @@ +import { v } from "convex/values"; +import { mutation, query } from "./_generated/server"; + +export const list = query({ + args: {}, + handler: async (ctx) => { + return await ctx.db.query("todos").withIndex("by_creation_time").order("desc").collect(); + }, +}); + +export const add = mutation({ + args: { text: v.string() }, + handler: async (ctx, args) => { + return await ctx.db.insert("todos", { + text: args.text, + completed: false, + }); + }, +}); + +export const toggle = mutation({ + args: { id: v.id("todos") }, + handler: async (ctx, args) => { + const todo = await ctx.db.get(args.id); + if (!todo) { + throw new Error("Todo not found"); + } + return await ctx.db.patch(args.id, { + completed: !todo.completed, + }); + }, +}); + +export const remove = mutation({ + args: { id: v.id("todos") }, + handler: async (ctx, args) => { + return await ctx.db.delete(args.id); + }, +}); diff --git a/src/dashboard/apps/web-template/convex/tsconfig.json b/src/dashboard/apps/web-template/convex/tsconfig.json new file mode 100644 index 000000000..73741270b --- /dev/null +++ b/src/dashboard/apps/web-template/convex/tsconfig.json @@ -0,0 +1,25 @@ +{ + /* This TypeScript project config describes the environment that + * Convex functions run in and is used to typecheck them. + * You can modify it, but some settings are required to use Convex. + */ + "compilerOptions": { + /* These settings are not required by Convex and can be modified. */ + "allowJs": true, + "strict": true, + "moduleResolution": "Bundler", + "jsx": "react-jsx", + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + + /* These compiler options are required by Convex */ + "target": "ESNext", + "lib": ["ES2021", "dom"], + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "isolatedModules": true, + "noEmit": true + }, + "include": ["./**/*"], + "exclude": ["./_generated"] +} diff --git a/src/dashboard/apps/web-template/db/init.sql b/src/dashboard/apps/web-template/db/init.sql new file mode 100644 index 000000000..3d5f3a63c --- /dev/null +++ b/src/dashboard/apps/web-template/db/init.sql @@ -0,0 +1,14 @@ +-- Schema for a simple to-do list +CREATE TABLE IF NOT EXISTS todos ( + id SERIAL PRIMARY KEY, + title VARCHAR(255) NOT NULL, + description TEXT, + is_completed BOOLEAN DEFAULT FALSE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- Initial data for the to-do list +INSERT INTO todos (title, description, is_completed) VALUES +('Buy groceries', 'Milk, Bread, Eggs, and Butter', FALSE), +('Read a book', 'Finish reading "The Great Gatsby"', FALSE), +('Workout', 'Go for a 30-minute run', FALSE); diff --git a/src/dashboard/apps/web-template/neon-vite-plugin.ts b/src/dashboard/apps/web-template/neon-vite-plugin.ts new file mode 100644 index 000000000..b11858529 --- /dev/null +++ b/src/dashboard/apps/web-template/neon-vite-plugin.ts @@ -0,0 +1,10 @@ +import { postgres } from "@neondatabase/vite-plugin-postgres"; + +export default postgres({ + seed: { + type: "sql-script", + path: "db/init.sql", + }, + referrer: "create-tanstack", + dotEnvKey: "VITE_DATABASE_URL", +}); diff --git a/src/dashboard/apps/web-template/src/components/Header.tsx b/src/dashboard/apps/web-template/src/components/Header.tsx new file mode 100644 index 000000000..c051d9a7c --- /dev/null +++ b/src/dashboard/apps/web-template/src/components/Header.tsx @@ -0,0 +1,366 @@ +import { Link } from "@tanstack/react-router"; +import { + ChefHat, + ChevronDown, + ChevronRight, + CircleUserRound, + ClipboardType, + Database, + Globe, + Home, + ImageIcon, + Menu, + MessagesSquare, + Network, + SquareFunction, + StickyNote, + Store, + Table, + Webhook, + X, +} from "lucide-react"; +import { useState } from "react"; +import TanChatAIAssistant from "./example-AIAssistant.tsx"; +import WorkOSHeader from "./workos-user.tsx"; + +export default function Header() { + const [isOpen, setIsOpen] = useState(false); + const [groupedExpanded, setGroupedExpanded] = useState>({}); + + return ( + <> +
+ +

+ + TanStack Logo + +

+
+ +