Claude Haiku wraps JSON in ```json ... ``` blocks, causing json.loads to fail
silently. The except clause swallowed the error, leaving ai_title empty for all
303 sessions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All CC Dashboard projects that have a non-empty job_number now appear
in the OMG list automatically. Existing entries are preserved (INSERT
only where no entry with that job_number exists for the user).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Static assets were built before the auth fix commit (13:29 vs 14:14),
so the deployed container ran old code that registered the router before
awaiting authStore.init() — causing page refresh to redirect to login.
Also adds migration 0011 to set job_number=2940884 for Oliver client
projects that had no job number assigned.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move app.use(router) after await authStore.init() so the beforeEach guard
sees the correct isAuthenticated state on page load
- Fix backfill_session_costs._root_prefix: remove underscore→dash replacement
that caused paths like /Users/ai_leed/... to not match ~/.claude/projects/ folders
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When init() restores session from cookie and user's current URL is /login,
the guard was calling next() without checking isAuthenticated — leaving the
user on the login page despite having a valid session. Now redirects to
dashboard if already authenticated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Narrow path "/cc-dashboard/api/auth" caused matching issues depending on
how the reverse proxy presents headers to the browser. Using "/" is safe
since the cookie is HttpOnly and the server validates the token type.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On conflict update now skips active_hours if incoming value is 0,
preventing the cost-backfill script from clobbering existing session
hours with its sentinel 0.0 value.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cookie was set with path="/api/auth" but browser-visible URL is
"/cc-dashboard/api/auth/..." — browser never sent the cookie back.
Fix: derive path from BASE_PATH so it matches the full proxy-prefixed URL.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Auto-create/update OmgEntry when Project.job_number changes (PATCH /api/projects);
delete stale entry on clear; sync name/client when those fields change too
- Backfill script: scripts/backfill_omg_from_projects.py
- Projects List-view: add OMG # column with link to /omg?highlight=<job_number>;
Grid-view badge also made clickable; OmgView supports ?highlight= deep-link with scroll+highlight
- AzureWorkItem: add omg_number column (migration 0009), extracted from
fields_json[Custom.OMGDeliverableNumber] on sync; DevOps table shows OMG # column
with CC-project link when matched; toolbar badge shows count of items without OMG #
- Session no longer lost on F5: refresh_token moved to HttpOnly+SameSite=Lax cookie;
authStore.init() restores session on app start; axios interceptor retries on 401
via cookie refresh before logging out; POST /api/auth/logout clears cookie
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
OMG page:
- Form now has "Fill from project" dropdown that auto-fills name/client/job#
from any cc-dashboard project (projects loaded in parallel on mount)
- Job # placeholder updated to show numeric format
DevOps Work Items:
- Count "19" moved into the section heading next to "Work Items" title
- DataTable toolbar (separate row with count+filter) hidden via showToolbar=false
- DataTable: add showToolbar prop (default true) to control toolbar visibility
ADO sync:
- Fetch all fields from ADO API (fields=None) to capture custom fields
including "OMG Deliverable Number" in fields_json
- Expose fields_json in AzureWorkItemOut schema for frontend inspection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On the OMG page, each entry now shows a "CC Project" column that finds
the matching cc-dashboard project by job_number and links to its detail page.
Projects are loaded in parallel with OMG entries on mount.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wrap 'Mark done', 'Edit project', 'Generate AI summary' buttons and inline-editable OMG spans with Tooltip component; replace priority dot title attr in KanbanCard; also adds focus-visible ring to 'Mark done' button.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace focus: with focus-visible: on Microsoft sign-in button for consistent ring pattern; error message already uses text-destructive correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Apply space-y-8 rhythm to admin page sections (no destructive actions currently present in this view — no confirm dialog needed yet).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show 3 skeleton rows while SSE is not yet connected, replace emoji empty state with EmptyState component (Radio+Zap icons), add focus-visible ring to Clear button, slightly increase event row padding.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace inline 'Drop here' placeholder in KanbanColumn with EmptyState component, remove title attr in favour of aria-label on add-task button, add focus-visible ring.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace window.confirm with ConfirmDialog for block delete, upgrade view/week-length toggles to SegmentedControl, swap inline SVG nav arrows for lucide ChevronLeft/Right with ghost icon Button, add focus-visible ring to planner toggle.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace two separate <input type="date"> fields for export range with
a single DateRangePicker component; format() from date-fns bridges
Date <-> string for exportFrom/exportTo refs
- Use space-y-8 between card sections, space-y-2 between label + input
- Add explicit focus-visible:ring-2 on raw Button usages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace "No data" / "No sessions" / "No tools" terse text with EmptyState
components (FileText, Wrench, CalendarDays icons)
- Add Skeleton placeholders for header, chart, and grid during loading
- Replace raw <input> elements in edit mode with shared Input component
- Replace raw save/cancel buttons in edit mode with Button component
- Upgrade summarize button touch target from h-6/w-6 to h-8/w-8
- Add focus-visible rings on interactive buttons and links
- Use space-y-8 between top-level sections, space-y-2 for label+input pairs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace window.confirm for key revoke with ConfirmDialog + confirmText prop
requiring user to type the key label before confirmation
- Replace terse "No API keys" text with EmptyState component (Key, Plus, Shield icons)
- Add focus-visible ring on Revoke button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace raw h-7 w-7 action buttons with Button size="icon" (40px)
- Replace raw inline <input> elements with shared Input component
- Replace handleDelete/window.confirm guard with ConfirmDialog + pendingDeleteId ref
- Wrap action buttons in Tooltip with descriptive content
- Upgrade empty state to EmptyState component
- Add focus-visible rings on interactive elements
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove Planka: docker-compose services, apache /board/ proxy, env vars, custom CSS dir
- Add Kanban board at /tasks: 4 columns (To Do / Doing / Testing / Done),
native HTML5 drag-and-drop, card modal (TaskForm reuse), per-column "+" button
- Add 'testing' status to Task model validator and frontend union type
- Add GET /api/tasks/{id} endpoint (was missing, frontend already called it)
- Enrich DevOps clone: live-fetches description, AC, assignee, iteration,
comments and attachments from ADO; renders as Markdown in task.notes
- Add /omg page: standalone project/client/job# registry with inline editing
and create/edit/delete dialog; backed by new omg_entries table (migration 0008)
- Add omg router to main.py; add OMG + Tasks to sidebar and router
- Fix dead /planner link on Dashboard -> /tasks
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Sidebar: white background, orange gradient logo, orange active pill
- TopBar: glassmorphism (white/80 + backdrop-blur-xl)
- AppLayout: warm gradient background mesh
- DataTable: new reusable component with column sort, filter, resize
- DevopsView: rebuilt with DataTable; connection shows "all assigned work items"
- ADO work item URLs: use org-level URL (no project in path)
- CalendarBlock: planned blocks show task title instead of project name
- Reports export: replaced <a download> with fetch+blob to send JWT auth header
- Sidebar Tasks: fixed path /board/ (trailing slash for Apache ProxyPass)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Default 30d window hid projects inactive for >30 days (e.g. Enterprise Ai Hub
Nexus, last session 2026-04-01). Project detail now returns all history unless
explicit from/to params are passed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tasks Today shows pending tasks for today with quick-complete.
ADO Priority Items shows top 5 open items sorted by priority.
Falls back to a connect prompt when no DevOps integration is configured.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>