diff --git a/Infra-Network/PROJECT-RENTCHARGE.md b/Infra-Network/PROJECT-RENTCHARGE.md index 3a31d43..3109d51 100644 --- a/Infra-Network/PROJECT-RENTCHARGE.md +++ b/Infra-Network/PROJECT-RENTCHARGE.md @@ -1,24 +1,149 @@ -# PROJECT ? Rent and Charge (Weekly and Arrears) - -Produto de cobranca semanal de aluguel e atrasos (arrears) para hostel/residencia (quartos, SAGE, staff). - -## O que o sistema faz - -- Lista residentes / quartos (ex. A27, D41) -- Valor semanal devido -- Pagamentos por semana; totais do mes; debito acumulado -- Importacao da planilha Excel de arrears -- Regras por SAGE; statements HTML/PDF -- UI: login, lista, ficha do residente - -## Stack (codigo atual) - -- Backend FastAPI: `C:\Users\mini\Documents\rent-arrears-web\backend` -- Frontend Next.js: `C:\Users\mini\Documents\rent-arrears-web\frontend` -- Legado em `C:\LAPTOP\rent-arrears-reporting-230226` e `rent-arrears-dashboard-nextjs-230226` - -Proximo: mover o app para `C:\LAPTOP\rentcharge\app` e deploy na VM 500 (porta 80 atras do Traefik). - -## Infra - -Ver `SPEC-VM500-RENTCHARGE.md`. +# PROJECT — Rent and Charge (Weekly and Arrears) + +Produto de cobrança semanal de aluguel e atrasos (arrears) para hostel/residência Granby Lifehouse (quartos, SAGE, staff). + +**Atualizado:** 2026-09-19 · **Versão:** **006.2026** +**SPEC infra:** `SPEC-VM500-RENTCHARGE.md` +**SPEC AR / Credit Book:** `SPEC-ACCOUNT-RECEIVABLES.md` +**SPEC Txn / Ticket:** `SPEC-TRANSACTION-IDS.md` +**SPEC MAP WEEK:** `SPEC-PAYMENTS-MAP-WEEK-PRINT.md` +**Sessões:** `SPEC-SESSION-2026-09-18.md` · `SPEC-SESSION-2026-09-19.md` +**App:** https://rentcharge.itecnologys.com · Forgejo: https://git.itecnologys.com/myvexx/rently + +## O que o sistema faz (escopo actual) + +- Lista residentes / quartos (padrão SAGE: filtros por coluna, `#`, Room estreita, badges NP / Name dup / Room conflict) +- Valor semanal devido via **charge bands** (RENT_35/40/41/45/65, FB_85/91, BANK_ACCOUNT, FLEXIBLE_FB) +- **Pagamentos:** fonte única = exports SAGE *Customer Invoices Due* (não o Excel de arrears) +- Totais do mês / ano; statements HTML/PDF; debit letter; agreements +- UI: Residents, Reporting (mesmo layout), Settings, ficha do residente com grelha de pagamentos +- **Account Receivables:** cash / credit sale / settlement (meals, keys, electricity); Credit Book com **over-settlement**; ROI Finance + Credit consumption; Period dashboard (due vs paid vs % + other balances) +- Utilizadores: registo público com código de e-mail, **política de senha forte**, recuperação por token (self-service e admin), edição de login, lockout, sessões revogáveis, Access Matrix RBAC e auditoria no menu Admin +- Infra: VM500 BIG + Traefik CT120 + Cloudflare Tunnel + +**Auth / Access docs:** `AUTH-USERS-SPEC.md` · `ACCESS-MATRIX.md` +**Referências de desenho:** [fastapi-fullauth](https://github.com/mdfarhankc/fastapi-fullauth) · [AuthWarden](https://github.com/timihack/authwarden) (padrões; implementação nativa RentCharge) + +## Stack + +- Backend FastAPI + SQLite (`arrears.db`) +- Frontend Next.js 15 +- Tudo do projeto: `/home/mini/rentcharge` (código, venv, sage-payments, config, archive) +- Host: BIG VM 500 — **não** big1 + +--- + +## Regras de negócio — ocupação de quarto + +### RN-01 — Um quarto físico = um residente + +1. O mesmo `room_no` físico **não pode aparecer duas vezes** na lista de ocupação. +2. Um quarto só pode ter **um** residente activo. +3. A dívida pertence à **pessoa** (SAGE ID), nunca ao quarto. + +### RN-02 — Validação de ocupação pelo último pagamento (**cash SA**) + +1. Prova operacional = **último pagamento cash** (SAGE Type **SA**, category `cash` > 0). +2. **RENTSUPP e refunds não contam** como pagamento de renda para esta regra. +3. Em conflito de quarto, prevalece quem tem o cash mais recente. + +### RN-03 — Not Present (NP##) vs nome em duplicidade + +- **A:** não pagou / saiu ou mudou → `NP01`, `NP02`, … + `last_room_no`. +- **B:** nome duplicado → badge para revisão humana; sem merge automático. + +API: `POST /api/residents/reconcile-occupancy`. + +--- + +## Regras de negócio — pagamentos SAGE (2026-09-05/06) + +### RN-PAY-01 — Fonte única + +- Exports SAGE **Customer Invoices Due** são a **única** fonte de pagamentos. +- O Excel de arrears (`JUN 2026` / `Total Arrears-2025`) **não grava** pagamentos (`excel_import._upsert_payment` = no-op). +- Endpoint: `POST /api/import/sage-payments` (`replace_all=true` apaga pagamentos anteriores). +- Código: `backend/app/services/sage_import.py`. + +### RN-PAY-02 — Semana e data + +- Semana = **segunda → domingo** (ISO). +- `period_start` / `period_end` = Mon–Sun da `payment_date`. +- Reports usam a **data de pagamento** da linha SAGE. + +### RN-PAY-03 — Type SA = cash (pago) + +| SAGE | Campo BD | Conta como pago? | +|------|----------|------------------| +| Type **SA** + Details CASH/CHQ/… | `category=cash`, `cash_paid=abs(Amount)` | **Sim** | +| Type **SA** + Details **RENTSUPP** | `category=rentsupp`, `rentsupp=abs` | **Não** (arquivo / relatório próprio) | +| Refund / Type SP / Details *REFUND* | `category=refund`, `refund_amount=abs` | **Não** (não subtrai do pago) | + +Amount no ficheiro SAGE é **negativo** → armazenar valor absoluto. + +### RN-PAY-04 — ID único + +- Coluna SAGE **No** → `payments.txn_no` (único; índice `ux_payments_txn_no`). +- Também: `txn_ref`, `sage_type`, `details`, `payment_date`, `counts_as_paid`. +- Reimport não duplica pelo mesmo `txn_no`. + +### RN-PAY-05 — Match residente + +- Match obrigatório por **SAGE A/C** ↔ `residents.sage_id`. +- Ex.: **Mapule Uwaene** = A/C **481** · band **RENT_35**. +- **Patrick McNamara** = A/C **272** · B15 · band FB_85. + +### RN-PAY-06 — Due vs pago (accounting) + +- Due semanal = charge band (`get_cap`); excess cash **não credita** semanas futuras. +- `summarize_payments` agrega **cash por semana** antes do cap; RENTSUPP/refund ignorados no pago. +- Statement / lista de pagamentos: **default só cash**; filtro UI para rentsupp / refund / all. + +### Ficheiros fonte (operador) + +`E:\Reports Week\PAYMENTS-REPORTS-BY-WEEK\2026\` + +Import consolidado (sem duplicar): + +1. `Payments_week_01_to_52_from_2025.xlsx` +2. `Payments_week_2026-total_partial.xlsx` (até ~30/08/2026) + +Cópia VM: `/home/mini/rentcharge/sage-payments/reimport/`. + +--- + +## UI (padrão SAGE) — estado 2026-09-09 + +| Ecrã | Padrão | +|------|--------| +| Residents `/` | Command bar, views, filtros por coluna, pager, export | +| Reporting `/reports` | Mesmo layout que Residents | +| Ficha Payments | Grelha SAGE; colunas **ID · Ref · SAGE · Details · Status · Amount**; search + filtros; Type default **Cash (SA)** | +| Ficha Period dashboard | Should have paid · Actually paid · Arrears/credit · % vs due · Year-end; **Other balances** (prior years · Credit Book · Agreements) | +| Account Receivables `/receivables` | Cash / Credit sale / Settlement; stamp; edit/delete com senha | +| ROI Finance | Cards + By account (Remit to ROI Finance · Credit net) · By resident | +| Credit consumption | Opening/Issued/Paid/Closing + grelha Residents; status Over-settlement | + +Detalhe canónico AR: **`SPEC-ACCOUNT-RECEIVABLES.md`**. Rules UI: `/rules` R-CB01…R-CB05. + +--- + +## Utilizadores e autenticação + +A especificação completa está em `AUTH-USERS-SPEC.md`. + +- `/login` oferece **Register new user**. +- O novo utilizador valida o cadastro com um código de seis dígitos enviado por e-mail e entra imediatamente após a validação. +- Recuperação de senha só usa e-mail verificado e token longo, de uso único. +- Sessões são mantidas no servidor, expiram por inatividade/tempo absoluto e podem ser revogadas. +- O menu **Admin** reúne contas, sessões (IP, SO, browser, duração e features) e eventos de segurança. +- O cookie do browser é `Secure`, `HttpOnly` e `SameSite=Strict`; o frontend não persiste credenciais em `localStorage`. + +--- + +## Fora de escopo (por agora) + +- Cloudflare Access na borda +- Merge automático de residentes só por nome +- Alterar `/etc/network/interfaces` do Proxmox +- Contar RENTSUPP como renda paga