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>
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>
- 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>
- 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>
ai_reports.py:
- Daily context now includes tasks_done_detail/in_progress_detail with
actual hours and notes for each task
- New prompt structure: Sessions Summary / Tasks Completed / In Progress
/ Blockers / Tomorrow's Plan — replaces generic "motivating summary"
- Fallback markdown updated to match new context shape
reports.py:
- GET /api/reports/{id}/export?format=md|html returns file download
with proper Content-Disposition header
ReportsView.vue:
- "↓ Markdown" and "↓ HTML" download links shown in expanded report
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend: POST /api/devops/work-items/{id}/clone creates a Task with
today's date, copies title and priority from ADO work item.
Frontend DevopsView: + icon button on each row, spinner while cloning,
success/error toasts on completion.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ADO client: query_work_items_account + get_work_items_batch_account
use org-level URLs, removing the project-scoped URL that 400'd on
projects with spaces in their names
- sync.py: switched to account-scope methods, added System.CreatedDate
and Microsoft.VSTS.Common.Priority to FIELDS list
- AzureWorkItem model: @property team_project/priority/created_date
derived from fields_json (no migration needed)
- AzureWorkItemOut schema: exposed the 3 new derived fields
- DevopsView: table layout with Project / Priority / Created / State columns
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend TaskOut doesn't include tags field; TaskCard.vue read
task.tags.length causing TypeError on undefined. Making tags optional
in the Task type and using optional chaining is the correct fix since
the tags feature is unused (always empty).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sidebar is always dark regardless of app theme. text-foreground resolves
to dark color in light theme, making nav items invisible on dark sidebar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Calendar: popover now shows Edit/Delete buttons for planned blocks; Edit pre-populates TaskForm; Delete calls deleteBlock API + removes from store. Sessions show read-only label. CalendarView handles ?date= query param from Dashboard chart click.
- Projects: grid/list view toggle with localStorage persistence
- Project detail: Daily Breakdown section (per-day hours + sessions, clickable → filtered view); always-visible 'All time' link; sessions not double-sliced (backend limit bumped 50→200); date-filtered view shows full summaries without line-clamp
- Planner: fixed mount race — onMounted now calls fetchForDate(today) instead of fetchAll()
- DevOps: inline connect form on /devops when not connected; form extracted to DevopsConnectForm.vue shared with Settings
- Reports: added break-words, pre-wrap and overflow-x: auto on prose pre/code blocks to prevent text overflow
- Sidebar: increased text contrast (text-foreground/60 for inactive items, text-foreground/40 for icons)
- Dashboard: KpiCard supports 'to' prop via RouterLink; Projects count + Top Project KPIs link to /projects; Projects list rows link to project detail; Hours by Day bars click → /calendar?date=
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- New POST /api/auth/microsoft endpoint validates Azure ID token via JWKS
- Removed POST /api/auth/login and /change-password
- Added azure_oid + nullable password_hash to users (migration 0007)
- Auto-provisions all @oliver.agency accounts on first SSO login
- Case-insensitive email matching links existing vadymsamoilenko@ account
- DEV_AUTH_BYPASS flag for local development without MSAL
- Frontend: MSAL loginPopup replaces email/password form
- Added scripts/grant_admin.py for role management
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Dashboard charts: use pixel heights (not %) and items-end so bars align
to bottom correctly and are visible at proper scale
- logout(): remove non-existent POST /api/auth/logout call; JWT is stateless,
client-side token clear is sufficient
- Include rebuilt src/static/ assets so server serves updated frontend bundle
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>
- 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>
- 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>
- 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>