Address 4 issues identified in AI feature audit: 1. Reduce temperature from 0.3 to 0.1 for health score calculations to reduce 16-40 point score volatility across runs 2. Add explicit cash runway classification rules to operating prompt preventing the model from rating sub-3-month runway as "positive" 3. Pre-compute total special assessment income in both operating and reserve prompts, eliminating per-unit vs total confusion ($300 vs $20,100) 4. Make YTD budget comparison actuals-aware: only compare months with posted journal entries, show current month budget separately, and add prompt guidance about month-end posting cadence Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7.2 KiB
7.2 KiB
Phase 2 Bug Fix & Tweaks - Implementation Plan
1. Admin Panel: Tenant Creation, Contract/Plan Fields, Disable/Archive
Database Changes
- Add
contract_number VARCHAR(100)andplan_level VARCHAR(50) DEFAULT 'standard'toshared.organizations(live DB ALTER + init SQL) - Add
archivedto the status CHECK constraint:('active', 'suspended', 'trial', 'archived') - Add to Organization entity:
contractNumber,planLevelcolumns
Backend Changes
- admin.controller.ts: Add two new endpoints:
POST /admin/tenants— Creates org + first user + tenant schema in one call. Accepts: org name, email, address, contractNumber, planLevel, plus first user's email/password/firstName/lastName. Calls OrganizationsService.create() then sets up the user.PUT /admin/organizations/:id/status— Sets status to 'active', 'suspended', or 'archived'
- auth.module.ts: Import OrganizationsModule so AdminController can inject OrganizationsService
- auth.service.ts: In
login(), after loading user with orgs, check if the default org's status is 'suspended' or 'archived' → throw UnauthorizedException("Your organization has been suspended/archived") - users.service.ts: Update
findAllOrganizations()query to includecontract_number, plan_levelin the SELECT
Frontend Changes
- AdminPage.tsx:
- Add "Create Tenant" button → opens a modal with: org name, address, email, phone, contract number, plan level (select: standard/premium/enterprise), first admin email, first admin password, first/last name
- Orgs table: add Contract #, Plan Level columns
- Orgs table: add Status dropdown/buttons (Active/Suspended/Archived) per row with confirmation
- Show status colors: active=green, trial=yellow, suspended=orange, archived=red
2. Units/Homeowners: Delete + Assessment Group Binding
Backend Changes
- units.controller.ts: Add
@Delete(':id')route - units.service.ts:
- Add
delete(id)method — checks for outstanding invoices first, then deletes - Add
assessment_group_idtocreate()INSERT andupdate()UPDATE queries - Update
findAll()to JOIN assessment_groups and returnassessment_group_name
- Add
Frontend Changes
- UnitsPage.tsx:
- Add delete button (trash icon) per row with confirmation dialog
- Add Assessment Group dropdown (Select) in create/edit modal, populated from
/assessment-groupsquery - Show assessment group name in table
- When an assessment group is selected and no manual monthly_assessment is set, auto-fill from the group's regular_assessment
3. Assessment Groups: Frequency Field
Database Changes
- Add
frequency VARCHAR(20) DEFAULT 'monthly'toassessment_groupstable (live DB ALTER + tenant-schema DDL) - CHECK constraint:
('monthly', 'quarterly', 'annual')
Backend Changes
- assessment-groups.service.ts:
- Add
frequencytocreate()INSERT - Add
frequencytoupdate()dynamic sets - Update
findAll()andgetSummary()income calculations to adjust by frequency:- monthly → multiply by 1 (×12/year)
- quarterly → amounts are per quarter, so monthly = amount/3
- annual → amounts are per year, so monthly = amount/12
- Summary labels should change to reflect "Monthly Equivalent" for mixed frequencies
- Add
Frontend Changes
- AssessmentGroupsPage.tsx:
- Add frequency Select in create/edit modal: Monthly, Quarterly, Annual
- Show frequency badge in table
- Update summary cards: labels → "Monthly Equivalent Operating" etc.
- Assessment amount label changes based on frequency ("Per Month" / "Per Quarter" / "Per Year")
4. UI Streamlining: Sidebar Grouping, Rename, Logo
Sidebar Restructure
Group nav items into labeled sections:
Dashboard
─── FINANCIALS ───
Accounts (renamed from "Chart of Accounts")
Budgets
Investments
─── ASSESSMENTS ───
Units / Homeowners
Assessment Groups
─── TRANSACTIONS ───
Transactions
Invoices
Payments
─── PLANNING ───
Capital Projects
Reserves
Vendors
─── REPORTS ───
(collapsible with sub-items)
─── ADMIN ───
Year-End
Settings
─── PLATFORM ADMIN ─── (superadmin only)
Admin Panel
Logo
- Copy SVG to
frontend/src/assets/logo.svg - In AppLayout.tsx: Replace
<Title order={3} c="blue">HOA LedgerIQ</Title>with an<img>tag loading the SVG, sized to fit the 60px header (height ~40px with padding) - SVG will be served directly (Vite handles SVG imports natively), no PNG conversion needed since browsers render SVG natively and it's cleaner
5. Capital Projects: PDF Table Export, Kanban Default, Future Category
Frontend Changes
- CapitalProjectsPage.tsx:
- Change default viewMode from
'table'to'kanban' - PDF export: temporarily switch to table view for print, then restore. Use
@media printCSS to always show table layout regardless of current view - Add "Future" column in kanban: projects with
target_year = 9999(sentinel value) display as "Future" - Update the form: Target Year select should include a "Future (Beyond 5-Year)" option that maps to year 9999
- Kanban year list: always include current year through +5, plus "Future" if any projects exist there
- Table view: group "Future" projects under a "Future" header
- Title: "Capital Projects" (remove "(5-Year Plan)" since we now have Future)
- Change default viewMode from
Backend
- No backend changes needed — target_year=9999 works with existing schema (integer column, no constraint)
File Change Summary
| File | Action |
|---|---|
db/init/00-init.sql |
Add contract_number, plan_level, update status CHECK |
backend/src/modules/organizations/entities/organization.entity.ts |
Add contractNumber, planLevel columns |
backend/src/modules/organizations/dto/create-organization.dto.ts |
Add contractNumber, planLevel fields |
backend/src/modules/auth/admin.controller.ts |
Add POST /admin/tenants, PUT /admin/organizations/:id/status |
backend/src/modules/auth/auth.module.ts |
Import OrganizationsModule |
backend/src/modules/auth/auth.service.ts |
Add org status check on login |
backend/src/modules/users/users.service.ts |
Update findAllOrganizations query |
backend/src/modules/units/units.controller.ts |
Add DELETE route |
backend/src/modules/units/units.service.ts |
Add delete(), assessment_group_id support |
backend/src/modules/assessment-groups/assessment-groups.service.ts |
Add frequency support + adjust income calcs |
backend/src/database/tenant-schema.service.ts |
Add frequency to assessment_groups DDL |
frontend/src/assets/logo.svg |
New — copy from /Users/claw/Downloads/logo_house.svg |
frontend/src/components/layout/AppLayout.tsx |
Replace text with logo |
frontend/src/components/layout/Sidebar.tsx |
Restructure with grouped sections |
frontend/src/pages/admin/AdminPage.tsx |
Create tenant modal, status management, new columns |
frontend/src/pages/units/UnitsPage.tsx |
Delete, assessment group dropdown |
frontend/src/pages/assessment-groups/AssessmentGroupsPage.tsx |
Frequency field |
frontend/src/pages/capital-projects/CapitalProjectsPage.tsx |
Kanban default, table PDF, Future category |
| Live DB | ALTER TABLE commands for contract_number, plan_level, frequency, status CHECK |