- type
- concept
- created
- Mon Apr 06 2026 02:00:00 GMT+0200 (Central European Summer Time)
- updated
- Mon Apr 06 2026 02:00:00 GMT+0200 (Central European Summer Time)
- sources
- wiki/concepts/portfolio-command-center, wiki/concepts/slug-based-urls
- tags
- feature portfolio units ui
- aliases
- units-list, units-page
Units Page
Overview
Previously, units were only accessible by drilling into property detail → building grid → clicking a unit. This page gives a portfolio-wide view of all units in a single filterable table.
URL: /units (sidebar → Portfolio → Units)
KPI Cards
Four summary cards at top:
- Total Units — 6,666 (occupied + vacant counts)
- Occupancy — 93.9% (6,258 / 6,666)
- Avg Rent — $1,189/mo (lease avg vs market avg)
- Monthly Revenue — $6.7M from active leases
Filters
Server-side filtering via query params:
- Search — ILIKE across unit_number, property name, tenant first/last name (300ms debounce)
- Property — dropdown of 33 properties (lightweight
/api/units/propertiesendpoint) - Lifecycle Status — Active, Month-to-Month, Notice, Vacant
- Bedrooms — Studio, 1-4 BR
Table Columns
| Column | Source | Notes |
|---|---|---|
| Unit | unit_number |
Bold, primary color |
| Property | property_name |
Muted |
| Building | building_name |
Hidden on mobile |
| Bed/Bath/Sqft | Unit fields | Condensed format |
| Rent | lease_rent or market_rent |
Tabular nums, right-aligned |
| Status | lifecycle_status |
Color-coded pill |
| Tenant | tenant_first + tenant_last |
Hidden on small screens |
Pagination: 50 units/page, server-side via LIMIT/OFFSET.
Lifecycle Status Display
| Status | Color | Source |
|---|---|---|
| Active | Green (#16a34a) | tenant_lease_lifecycle.lease_status = 'active' |
| Month-to-Month | Amber (#b45309) | lease_status = 'month_to_month' |
| Notice | Red (#b91c1c) | lease_status = 'notice' |
| Vacant | Muted | units_unit.status = 'available' |
| Occupied (no lifecycle) | Neutral | status = 'occupied' but no lifecycle record (1,641 units) |
Available Unit Data (DB)
All data below is joinable to units_unit via tenant_lease.unit_id or units_maintenance.unit_id.
Ledger Entries (tenant_ledger_entry)
- 112,601 records (827 open/unpaid)
- Linked via
lease_id→tenant_lease→unit_id - Fields:
trans_type(Charge/Payment),charge_code,charge_amount,trans_date,is_open,description - Common charge codes:
rent(17,849 charges),ubtrash(9,325),Depwaive(5,406),tllins(4,165),ubwater(3,286),petrent(2,634) - Payments: 36,692 general + 18,059 rent-specific, avg $1,327
Recurring Charges (tenant_recurring_charge)
- 48,679 total (21,502 active)
- Linked via
lease_id→tenant_lease→unit_id - Fields:
charge_code,charge_description,amount,start_date,end_date,is_active - Top active charges: Rent Income (4,626 @ avg $1,250), Trash (4,425 @ $27), Deposit Waiver (2,056 @ $19), Monthly Rent (1,725 @ $1,058), Pest Control (1,725 @ $5), Water/Sewer (1,725 @ $45), TLL Insurance (1,629 @ $20), Pet Rent (805 @ $40)
Maintenance (units_maintenance)
- 46 records (39 open/active)
- Linked directly via
unit_id - Fields:
title,description,priority(emergency/urgent/high/medium/low),status(open/in_progress/approved/pending_review/work_completed/etc.),requested_date,estimated_cost,actual_cost,assigned_vendor_id - Status breakdown: request_received (6), in_progress (8), approved (4), triaged (4), quotes_requested (4), quotes_received (3), pending_review (2), open (4), work_completed (4), completed (7)
Work Order Lifecycle (work_order_lifecycle)
- 96 records — extended WO tracking with vendor assignment, scheduling, completion notes, tenant sign-off, vendor rating
- Linked via
work_order_idto maintenance
Risk Scores (unit_risk_score)
- 80 records — AI-generated risk assessments
- Linked directly via
unit_id - Fields:
score(0-100),level(low/medium/high),top_risk_factor,factor_breakdown(JSON),predicted_next_issue,predicted_issue_date - Examples: "Fire suppression maintenance overdue" (35/medium), "Roof membrane wear" (61/high), "Aging HVAC system" (18/low)
Renewal Recommendations (renewal_recommendation)
- 2,801 records — AI-generated renewal strategies
- Linked via
unit_id,lease_id,tenant_id - Fields:
churn_score,churn_risk_level,current_rent,market_rent,recommended_rent,rent_increase_pct,rent_strategy,rent_reasoning,recommended_term_months,recommended_lease_start/end
Collection Cases (collection_case)
- 15 records — active collection tracking
- Fields:
tenant_name,unit_number,property_name,outstanding_balance,days_overdue,status,escalation_level,payment_probability_score,ai_case_summary
Additional Tables (empty or minimal)
units_charge(0 records),units_charge_template(0),units_lease_charge(0),scheduled_charges(0)
Data Coverage
- 6,666 total units, 33 properties
- 6,258 occupied, 408 vacant
- 4,617 have lifecycle records (3,468 active, 1,146 MTM, 3 notice)
- 1,641 occupied units lack lifecycle records — shown as "Occupied"
API Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/api/units/stats |
GET | KPI card data (counts, averages, totals) |
/api/units/properties |
GET | Property dropdown options |
/api/units |
GET | Paginated, filtered unit list with JOINs |
The enhanced /api/units endpoint joins:
units_unit → properties → properties_building → tenant_lease → tenant_lease_lifecycle → tenants
Unit Detail Tabs
The unit detail page (unit-detail.component.ts) has 5 functional tabs, each showing tab-specific content via @switch(activeTab()):
Overview (default)
- 6 KPI mini cards (Monthly Rent, Market Rent, Deposit, SQFT, Lease Start, Lease End)
- Recent Charges table (top 5, with "View All" → Financials tab)
- Open Maintenance (top 4, with "View All" → Maintenance tab)
- Floor Plan SVG (generated from bed/bath/sqft)
- Recurring Charges summary with monthly total
Tenant
- Contact info: name, email, phone, mobile
- Emergency contact: name, phone
- Additional details: pets, vehicle, parking (shown if present)
- Lease details: number, rent, deposit, period
- Empty state for vacant units
Financials
- 4 KPI cards: Balance, Open Charges, Monthly Recurring, Market Rent
- Recurring Charges table with code, description, amount, active/inactive, monthly total footer
- ALL Ledger Entries table (sorted by date desc): date, type (Charge/Payment pills), description, amount (payments in gold), status (Open/Posted)
Maintenance
- 3 KPI cards: Open count, Completed count, Total Cost
- ALL Work Orders (sorted by date desc): title, priority pill, status pill, requested/completed dates
- Color coding: emergency/urgent=red, high=amber, completed=green check icon
Compliance
- Risk Score card (if exists): circular score badge (0-100), level pill, top risk factor, predicted next issue
- Assets table: name, tag, category, condition pill, status pill
- Lease Compliance: number, lifecycle status, period, remaining days, deposit
Computed Signals Added
totalRecurring— sum of active recurring chargestotalOpenCharges— sum of open ledger entriestotalMaintenanceCost— sum of WO costscompletedWorkOrders— filtered completed/closedsortedWorkOrders— sorted by date descsortedLedger— sorted by date desc
Implementation Files
| File | Role |
|---|---|
src/app/features/units/units.component.ts |
Units list page (OnPush, signals) |
src/app/features/properties/unit-detail.component.ts |
Unit detail page with 5 functional tabs |
src/app/core/services/property.service.ts |
UnitListItem, UnitListStats, UnitDetail interfaces + service methods |
src/app/app.routes.ts |
Route /units → lazy-loaded UnitsComponent |
src/app/layouts/sidebar/sidebar.component.ts |
"Units" nav item under Portfolio |
server.js |
3 API endpoints (stats, properties, units) |
Row Navigation
Clicking a row navigates via slug-based URL:
/property-management/{slugify(property_name)}/units/{unit_number}
Reuses existing UnitDetailComponent and by-name resolution endpoint.
Relationship to F1.4
This page is the foundation for the wiki/concepts/portfolio-command-center (F1.4). Future additions:
- AI action queue (renewal/collections/maintenance recommendations)
- Bulk execution (approve/reject/defer across units)
- Risk score column
- Collections status column
Sources
- wiki/concepts/portfolio-command-center — F1.4 spec this page builds toward
- wiki/concepts/slug-based-urls — URL routing architecture
Related
- wiki/concepts/lifecycle-state-engine — the 4 lifecycle states displayed
- wiki/concepts/renewal-intelligence — future AI column
- wiki/concepts/smart-collections — future AI column
- wiki/concepts/payment-calendar — similar page pattern (KPIs + table + filters)
- wiki/entities/unitcycle — the platform