6.8 KiB
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 · 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
- O mesmo
room_nofísico não pode aparecer duas vezes na lista de ocupação. - Um quarto só pode ter um residente activo.
- A dívida pertence à pessoa (SAGE ID), nunca ao quarto.
RN-02 — Validação de ocupação pelo último pagamento (cash SA)
- Prova operacional = último pagamento cash (SAGE Type SA, category
cash> 0). - RENTSUPP e refunds não contam como pagamento de renda para esta regra.
- 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=trueapaga 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 dapayment_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; índiceux_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_paymentsagrega 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):
Payments_week_01_to_52_from_2025.xlsxPayments_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.
/loginoferece 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,HttpOnlyeSameSite=Strict; o frontend não persiste credenciais emlocalStorage.
Fora de escopo (por agora)
- Cloudflare Access na borda
- Merge automático de residentes só por nome
- Alterar
/etc/network/interfacesdo Proxmox - Contar RENTSUPP como renda paga