Coverage for apps/core_los/dashboard_schemas.py: 100%
66 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 14:06 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 14:06 +0000
1"""Ninja schemas for GET /api/dashboard.
3These shapes aren't 1:1 with any single model instance — they're pre-aggregated
4dicts/lists built by the view (design.md D6) — so they're plain ``Schema``, not
5``ModelSchema``.
6"""
8from __future__ import annotations
10from datetime import date, datetime
11from decimal import Decimal
13from ninja import Schema
16class LoanRef(Schema):
17 loan_guid: str
18 loan_number: str
19 borrower_name: str
22class LockItem(LoanRef):
23 expires_at: datetime
24 rate: Decimal
27class PipelineBuckets(Schema):
28 prospect: int
29 processing: int
30 closing: int
31 funded: int
34class FundedYtd(Schema):
35 purchase_count: int
36 purchase_volume: Decimal
37 refinance_count: int
38 refinance_volume: Decimal
41class LenderSpreadItem(Schema):
42 lender_id: str
43 count: int
44 volume: Decimal
47class RateAlertItem(LoanRef):
48 rate: Decimal
51class BirthdayItem(LoanRef):
52 date: date
55class AnniversaryItem(LoanRef):
56 date: date
59class MiDropItem(LoanRef):
60 ltv: Decimal
63class UpcomingEvents(Schema):
64 birthdays: list[BirthdayItem]
65 loan_anniversaries: list[AnniversaryItem]
66 early_payoffs: list[RateAlertItem]
67 mi_drop_eligible: list[MiDropItem]
70class RecentLoan(LoanRef):
71 stage: str
72 updated_at: datetime
75class DashboardCounts(Schema):
76 loan: int
77 appraisal: int
78 closing: int
81class DashboardWidgets(Schema):
82 locks_expiring: list[LockItem]
83 locks_expired: list[LockItem]
84 conditions_pending: int
85 needs_pending: int
86 leads_new: int
87 funded_ytd: FundedYtd
88 lender_spread: list[LenderSpreadItem]
89 upcoming_events: UpcomingEvents
90 recent_loans: list[RecentLoan]
91 counts: DashboardCounts
92 contingencies: int
93 rate_alerts: list[RateAlertItem]
96class DashboardResponseOut(Schema):
97 scope: str
98 pipeline_volume: Decimal
99 in_process: int
100 funded: int
101 tasks_due: int
102 by_pipeline: PipelineBuckets
103 widgets: DashboardWidgets