- TaskForm: add start_time/end_time fields; on save emits optional
block payload so PlannerView creates a PlannedBlock automatically
- PlannerView: handleSave accepts block param, calls createBlock after
task creation when time is provided
- CalendarBlock: planned blocks with task_id get draggable="true" +
@dragstart emitting blockDragStart event
- CalendarGrid: forward blockDragStart to useCalendarDnD
- useCalendarDnD: onBlockDragStart stores block_id + duration in
dataTransfer; onDrop handles both move-existing-block and
create-new-block paths
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase 1 — Contract bugs:
- Add progress_pct/budget_hours to ProjectHours schema and compute from ProjectBudget
- Add hours/pct to ToolUsage schema, compute in project_detail endpoint
- Fix ProjectDetailView to use correct nested data shape (data.project.*, data.sessions, etc.)
- Fix GenerateReportIn: rename field date → period_date; update reports router
- Fix tasks list date filter: use Query(alias='date') instead of positional arg
- Fix AzureIntegration/AzureWorkItem types: org→organization, id type, ado_id, sync_enabled
- Fix devops API payload and SettingsView to use organization field
- Fix TaskForm ADO work item selector to use wi.ado_id for display, wi.id for value
- Add light theme CSS variables in :root, keep dark in .dark class
- Remove hardcoded class='dark' from HTML, add theme persistence script
- TopBar: persist dark/light to localStorage on toggle
- DashboardView: switch monthly() → timeline() endpoint for charts
- DOW endpoint: add from/to date range filtering
Phase 2 — Planner:
- Add projects API endpoint and Pinia store
- Add project picker to TaskForm
- Fix ADO work item display (#ado_id not #id)
Phase 3 — Calendar:
- getWeekDays() accepts weekLength 5|7 parameter
- Calendar store: add weekLength ref, setWeekLength(), update fetchCurrentView range
- CalendarToolbar: add 5d/7d toggle buttons; fix dateLabel to use days[days.length-1]
- CalendarView: clicking session block navigates to project-detail/:id/:date
- project-detail route: add optional :date? param; ProjectDetailView filters by date
- DnD resize: send start_at alongside end_at (PlannedBlockIn requires both fields)
Phase 4 — AI session summaries:
- Add ai_title/ai_result columns to Session model
- Alembic migration 0006 for new columns
- New ai_session_summary service using Claude Haiku
- Session summarize endpoint: POST /api/dashboard/sessions/{id}/summarize
- Scheduler job: summarize sessions without ai_title every 10 minutes
- SessionOut schema: add ai_title/ai_result fields
- ProjectDetailView: show ai_title as primary, ai_result as subtitle; sparkle button to generate
Phase 5 — Expanded AI assistant:
- Add 14 new tools: list/create/update/delete/complete tasks, prioritize_day,
schedule_task, auto_schedule_day, list_projects, list/delete manual entries,
generate_report, search_sessions, list_work_items
- Import PlannedBlock and AzureWorkItem in assistant service
- Update SYSTEM_PROMPT to describe full agent capabilities
- Agentic loop: 5 → 10 rounds max
- AssistantWidget: add tool labels for all new tools, update quick hints
New files: DevopsView.vue, projects store/API, ai_session_summary.py, migration 0006
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Design:
- Replace purple SaaS theme with operational dark navy (#0b1020) + cyan (#57c7ff)
- Satoshi + JetBrains Mono fonts via CSS @import
- KpiCard: hero variant for Total Hours, tabular-nums for all values
- Sidebar: cyan active state instead of amber, dimmer inactive icons
- Dashboard: skeleton loading states for all charts, polished empty states
- TopBar: cyan user avatar consistent with sidebar
Fixes:
- Live Feed: SSE URL was /api/events/stream (wrong) → /api/events; pass JWT as ?token= query param
- Dashboard: default preset changed to 'today' instead of '30d'
- index.html: Cache-Control: no-cache to prevent stale asset issues
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
String(36) cannot reference UUID column users.id in PostgreSQL.
Replace with postgresql.UUID(as_uuid=False) to match existing pattern in 0003.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TaskForm: change project_id/azure_work_item_id form state from null to undefined
- CalendarView/PlannerView: accept TaskCreatePayload | TaskUpdatePayload from @save emit
- Rebuild: web assets with AssistantWidget included
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Full Vue 3 + Vite + TypeScript + Tailwind SPA replacing the vanilla JS static frontend.
Includes router, Pinia stores (auth/tasks/calendar/devops), axios API client with all
endpoints, UI components (Button/Card/Dialog/Badge/Input/etc), calendar grid with
lane-packing algorithm and DnD support, SSE live feed, and all 11 views.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents duplicate reports and Anthropic API spam when the generate
endpoint is called multiple times for the same period.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Migration 0004: composite indexes (user_id, date) on sessions and
daily_stats; (user_id, start_at, end_at) on planned_blocks and
manual_entries — speeds up calendar and monthly/dow queries
- admin POST /recompute-stats: recomputes all DailyStat records from raw
session wall-clock intervals; use once after upgrading to fix historical
data that was stored as active_hours
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents FastAPI from crashing with StaticFiles mount when the Vue
frontend hasn't been built yet (cd web && npm run build).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- calendar.py: replace fragile string-concat datetime filters with proper
datetime.combine(date, time.min/max) for PlannedBlock and ManualEntry overlap
- tasks.py list_tasks: batch-load projects + work items in 2 queries instead
of N individual lookups per task (fixes N+1 performance issue)
- ai_reports.py: use wall-clock union hours + overhead for report totals,
consistent with KPI summary endpoint; import _union_hours from aggregator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- aggregator.py: store union of (start_at, end_at) intervals, not sum of
active_hours — active_hours is Claude's estimate, not wall-clock time
- dashboard/monthly: compute from session intervals + overhead per day
instead of DailyStat.total_hours (which lacked overhead and used active_hours)
- dashboard/dow: same fix — query sessions directly, apply union + overhead
- Both monthly and dow now match the KPI summary card exactly
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
overhead now applies to union-based totals (not inflated session sums),
so the setting in UI works correctly again
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- summary/timeline: use union of session start_at/end_at intervals per day
instead of summing active_hours, so parallel sessions don't inflate totals
- projects: show raw session hours per project (correct for per-project billing)
- monthly: remove daily_overhead_hours addition
- models: change daily_overhead_hours default 2.0 → 0.0
- daily_overhead_hours setting in user profile still works but defaults to 0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When /api/dashboard/projects is called without date params (as the
Projects page does), remove the date filter so all 36 projects appear
regardless of last activity date. Explicit date params still filter
as before (dashboard summary tab).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Sidebar: Add Sign Out button below user info
- Keys API: split revoke (PATCH /{id}/revoke) and delete (DELETE /{id})
- Keys page: Revoke + Delete buttons per key; delete removes from DB
- New key flow: after creation show download setup script step
- Script embeds API key, asks for projects root folder
- Downloads cc-collector.py, merges Claude Code hook into settings.json
- Tests connection and reports result
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Apache serves /cc-dashboard/* from /var/www/html/cc-dashboard/ directly.
index.html goes to the root, CSS/JS to static/ subdirectory to match
/cc-dashboard/static/... paths referenced in index.html.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Full CSS redesign: OLED black (#0a0a0a), #FFC407 accent, Montserrat 400–900
- Bold high-contrast typography (900 weight values, -0.04em tracking)
- No glassmorphism — flat sharp surfaces with subtle borders
- KPI cards: 2px yellow top accent bar on hover + lift shadow
- Login: centered card with yellow top bar + subtle grid bg pattern
- Modals: yellow top accent line
- Active nav: solid yellow bg, black text
- Buttons: yellow CTA with glow, ghost with yellow hover
- Badges: pill with yellow tint
- Favicon: dark card with yellow CC
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Full CSS rewrite: deep dark bg (#060714), glass cards with backdrop-filter,
Fira Sans/Code fonts, indigo/violet accent palette replacing yellow
- Add animated orb background to index.html
- Update favicon to indigo gradient
- Wrap admin/settings forms in <form> tags with autocomplete attributes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>