- Parent companies show a violet badge with subsidiary count, clickable to open modal
- Modal lists each subsidiary with policy count, task count, and claims advocate, click to navigate
- Child companies show a blue badge with parent name, clickable to navigate to parent page
- Both badges update reactively with state
- Sort by Date or Priority (asc/desc toggle)
- Hide completed/NA/cancelled tasks by default
- Show Completed toggle button
- Show Archived button for old tasks
- Richer task cards with status badges, priority pills, overdue highlighting
- Tab count shows active tasks only
- Sort by Client, Date, Type (Group/Policy/Client), Level (priority)
- Click to sort asc/desc with arrow indicators
- Filter dropdowns for Type and Level with Clear button
- Applied after card filter and status tab filter
The 'Assigned' tab, overdue count, and card filters were only excluding
COMPLETED tasks. NA and CANCELLED tasks with old due dates were showing
as overdue. Now all three terminal statuses are excluded from active views.
Top-level OR and AND keys on the same where object conflicted — consolidated
all suppression conditions into a single AND array in both the SSR page
query and the /api/tasks route.
- GET /api/admin/shape-import/browse: lists sites, drives, and folders via Graph API
- ShapeImportPanel: cascading Site / Document Library / Folder selects
with loading states, error display, and Reset to default
- folderPath stored on ShapeImportRun, passed through to runShapeImport
- discoverFiles accepts dynamic folderPath instead of hardcoded path
- Prisma: added folderPath field to ShapeImportRun model
- New DB tables: shape_import_runs, shape_import_logs (raw SQL applied)
- src/lib/shape-import/run-import.ts: importable core logic extracted from CLI script
- POST /api/admin/shape-import: starts run async, returns runId immediately
- GET /api/admin/shape-import: lists last 20 runs
- GET /api/admin/shape-import/[id]: polls log lines and run status
- /admin/shape-import page: drive ID config, dry run / execute (with confirmation),
live log panel (2s poll), stats summary, run history with log replay
- Admin index: added SHAPE Historical Import card
- Notes moved to collapsible panel just below header
- Auto-expanded if client has notes, collapsed if empty
- Shows preview snippet when collapsed
- Claims Advocate, Designations, Team Members, Related Companies
consolidated into new 'Assignment' tab
- Removed 4 standalone cards from main scroll area
This was the 4th location missing the filter — the API endpoint had no
suppression at all, so old/dead tasks showed when admins viewed other users' tasks.
Prisma NOT:[condA, condB] means exclude only if BOTH match, and OR at the
same level overrode the NOT entirely. Restructured to:
- NOT (single object) for dead policy exclusion
- OR for group expiry check (null group OR recent renewal)
- AND > OR for recent-or-terminal filter
Fixed in all 3 locations: tasks page, client tasks API, client detail SSR.
- Update page title, metadata, sign-in header, nav bar brand name
- Update dev account emails from ondeck.local to horizon.local
- Update comments in permissions.ts and types/index.ts
- Update NEXTAUTH_URL to https://horizon.seubert.cloud
- Update systemd timer service URL and log path
- Add /api/cron/sync route secured by x-cron-secret header
- Bypass NextAuth middleware for /api/cron/* routes
- Add CRON_SECRET to .env
- Fix FK violation: pass undefined instead of 'system' for triggered_by
- Systemd timer (ondeck-sync.timer) runs daily at 2 AM via curl