# SPEC — Residents hub (`/people`) **Produto:** Rently / RentCharge **Data:** 2026-09-13 **Status:** implementado **Operador:** Roger **Relacionados:** `SPEC-SYSTEM-DASHBOARD.md` · Statement service · `SPEC-STATEMENT-PUBLIC-URL.md` --- ## Problema A pesquisa do header enviava para o **Dashboard**, que não é uma vista de residente. Existiam listas em Control of Rent / Arrears / Maps, mas **não** um hub de consulta/seleção/edição rápida. ## Solução | Item | Valor | |------|--------| | Rota | `/people` | | Menu | **Residents** (antes de Control of Rent Payments) | | Header search | → `/people?q=…` | | Layout | Header estilo ROI Finance; lista à esquerda; painel à direita | ## Painel do residente seleccionado - Rent arrears / debt **YTD** (mesmas regras do Statement) - Semanas pagas / overdue no ano (semanas de calendário, incl. sem linha SAGE) - Credit Book (débito/crédito) - Acordos abertos - Último pagamento - Quick edit: room, notes, active - Links: full record `/residents/{id}`, Statement, Add new resident ## Regra de cálculo (obrigatória) **Não** somar só semanas com ficheiro SAGE. Usar `build_statement` / `fetchStatementJson` YTD (`01-01` → hoje), igual ao Statement impresso. Exemplo validado: **John J** D59 SAGE 411 → **£513** (não £62). Backend: `enrich_resident` sem `date_from/to` também usa Statement YTD para `total_debt` / `year_debit`. ## Ficheiros - `frontend/src/app/people/page.tsx` - `frontend/src/components/AppShell.tsx`, `frontend/src/lib/access.ts`, `frontend/src/lib/api.ts` (`fetchStatementJson`) - `backend/app/main.py` (`enrich_resident`) ## Critério de aceite 1. Pesquisa header → Residents hub. 2. John J e amostra de 3 residentes: debt = Statement YTD. 3. Prod + test (mesmo frontend). ## Profile status (007.2026) Flags Temporary / Deceased / In custody / In treatment on the full resident record (`/residents/{id}`) and Settings edit — with audit stamps. See `SPEC-RESIDENT-PROFILE-STATUS.md`.