seubert-claims/ondeck/ARCHITECTURE.md
lorentz a4dfa0db59 Fix: open overdue tasks no longer hidden by 7-day age cutoff
RCA: the dueDate >= cutoff filter was incorrectly excluding open tasks
more than 7 days overdue. The cutoff now only applies to terminal tasks
(COMPLETED/CANCELLED/NA) to suppress ancient clutter. Open tasks of any
age are always returned.

Fixes tasks/page.tsx and clients/[id]/page.tsx.
2026-05-19 03:24:14 +00:00

5.4 KiB

Horizon — Architecture

Overview

Next.js 15 App Router application. All pages are server or client components under src/app/(dashboard)/. Data access goes exclusively through Next.js API route handlers (src/app/api/), which use Prisma to talk to Postgres.

Directory map

src/
├── app/
│   ├── (dashboard)/          # Authenticated layout + all pages
│   │   ├── layout.tsx        # Shell: sidebar, nav, session guard
│   │   ├── dashboard/        # Home/summary page
│   │   ├── clients/          # Client list + detail ([id]/)
│   │   ├── policies/         # Policy list + detail ([id]/)
│   │   ├── tasks/            # Task list (page-client.tsx) + detail ([id]/)
│   │   ├── admin/            # Admin-only pages (users, roles, designations, sync)
│   │   └── manager/          # Manager pages (templates, metrics)
│   ├── api/                  # API route handlers
│   │   ├── auth/             # NextAuth endpoints
│   │   ├── clients/          # CRUD + notes, contacts, members
│   │   ├── tasks/            # CRUD + notes, assignments
│   │   ├── policies/         # CRUD + policy groups
│   │   ├── policy-groups/    # Renewal group management
│   │   ├── sync/             # Shape import sync
│   │   ├── users/            # User management
│   │   ├── roles/            # Role management
│   │   ├── templates/        # Task templates
│   │   ├── designations/     # Client designations
│   │   ├── metrics/          # Dashboard metrics
│   │   ├── cron/             # Scheduled jobs (notifications, etc.)
│   │   └── dashboard/        # Dashboard summary data
│   ├── auth/                 # Sign-in / error pages (unauthenticated)
│   └── layout.tsx            # Root layout (providers, theme)
├── components/
│   ├── ui/                   # shadcn/ui primitives (Button, Dialog, Input, etc.)
│   ├── clients/              # Client-specific components
│   ├── tasks/                # Task card, task edit modal
│   ├── policies/             # Policy components
│   ├── renewal-groups/       # Policy group components
│   ├── notifications/        # Notification bell + panel
│   ├── admin/                # Admin UI components
│   ├── manager/              # Manager UI components
│   ├── layout/               # Sidebar, header, nav
│   └── providers/            # SessionProvider, ThemeProvider
├── lib/
│   ├── auth.ts               # NextAuth config (Entra ID + local credentials)
│   ├── db.ts                 # Prisma client singleton
│   ├── entra.ts              # Microsoft Graph API helpers
│   ├── utils.ts              # Shared utilities (cn(), formatters)
│   ├── hooks/                # Custom React hooks
│   ├── sync/                 # Shape import sync logic
│   ├── shape-import/         # Shape file parsing
│   └── tasks/                # Task business logic helpers
├── middleware.ts              # Auth middleware (protects all dashboard routes)
└── types/                    # Shared TypeScript types

Data models (key entities)

Model Description
User Staff accounts; synced from Entra ID
Role / UserRole RBAC roles (Admin, Manager, AE, Claims, etc.)
Client Insurance clients; synced from AMS via Shape import
ClientContact Contacts per client
ClientMember Which staff are assigned to a client
Designation Client classification labels (color-coded)
Policy Insurance policies linked to clients
PolicyGroup Renewal groups grouping policies
Task Work items linked to client/policy/policy group
TaskAssignment Which users are assigned to a task
TaskNote Notes on tasks with status snapshots
TaskTemplate Reusable task templates for automation
SyncLog History of Shape import runs
AuditLog Field-level change tracking
Notification In-app notifications per user
ShapeImportRun Shape file import run tracking

Auth flow

  1. middleware.ts checks NextAuth session on every request under /(dashboard).
  2. Unauthenticated users are redirected to /auth/signin.
  3. Production: Microsoft Entra ID OAuth. Entra group memberships map to Horizon roles via EntraGroupRoleMapping.
  4. Dev: local credentials provider (see src/lib/auth.ts).

Task completion flow

  • UI: src/app/(dashboard)/tasks/page-client.tsx (task detail page) and src/components/tasks/task-card.tsx (list card)
  • Dialog collects: completion date, ImageRight filing confirmation, optional reminder date
  • PATCH /api/tasks/[id] sets completedAt, completedBy, imageRightFiled, reminderDate

Sync / data import

  • Client and policy data synced from Zywave/Applied AMS via Shape file import
  • Shape import logic: src/lib/shape-import/ and src/lib/sync/
  • Triggered manually from Admin UI or via scheduled cron (src/app/api/cron/)
  • Sync history tracked in SyncLog and AuditLog

Deployment

  • Production: Docker Compose at /opt/stacks/horizon
  • Image built from this directory's Dockerfile (Next.js standalone output)
  • DB: Postgres 17 in horizon-db container
  • Reverse proxy: Pangolin → https://horizon.seubert.cloud