Files
HOA_Financial_Platform/PLAN.md
olsch01 07d15001ae fix: improve AI health score accuracy and consistency
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>
2026-03-06 12:44:12 -05:00

7.2 KiB
Raw Permalink Blame History

Phase 2 Bug Fix & Tweaks - Implementation Plan

1. Admin Panel: Tenant Creation, Contract/Plan Fields, Disable/Archive

Database Changes

  • Add contract_number VARCHAR(100) and plan_level VARCHAR(50) DEFAULT 'standard' to shared.organizations (live DB ALTER + init SQL)
  • Add archived to the status CHECK constraint: ('active', 'suspended', 'trial', 'archived')
  • Add to Organization entity: contractNumber, planLevel columns

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 include contract_number, plan_level in 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_id to create() INSERT and update() UPDATE queries
    • Update findAll() to JOIN assessment_groups and return assessment_group_name

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-groups query
    • 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' to assessment_groups table (live DB ALTER + tenant-schema DDL)
  • CHECK constraint: ('monthly', 'quarterly', 'annual')

Backend Changes

  • assessment-groups.service.ts:
    • Add frequency to create() INSERT
    • Add frequency to update() dynamic sets
    • Update findAll() and getSummary() 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

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")

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
  • 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 print CSS 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)

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