obsidian-vault/Infra-Network/SPEC-MONEY-PRIVACY.md
Roger 06acaff8a8 docs: RentCharge 007.2026 money privacy + profile status
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 18:19:56 +00:00

42 lines
1.6 KiB
Markdown

# SPEC — Money privacy (eye button)
**Produto:** Rently / RentCharge
**Data:** 2026-09-19
**Status:** implemented (prod + test)
**Versão:** 007.2026
**Operador:** Roger
**Relacionados:** `SPEC-SYSTEM-DASHBOARD.md` · `SPEC-SESSION-2026-09-19.md`
---
## Purpose
Operators often work in open offices. Euro amounts start **hidden** (`€ ••••`). One control (header + page toolbars) reveals or hides **all** sensitive amounts together. After **30 seconds** idle, amounts hide again.
## UI
| Control | Location |
|---------|----------|
| Show € / Hide € | AppShell header (all authenticated pages) |
| Same button | Page toolbars (Dashboard, Residents, Mapa, Receivables, …) |
## Technical contract
1. Module flag: `frontend/src/lib/moneyFormat.ts` — `euro()`, `privacyMoneyLabel()`, `setMoneyHiddenFlag()`.
2. Flag changes **notify** subscribers (`subscribeMoneyHidden`).
3. React: `useMoneyPrivacyRender()` / `useMoneyPrivacy()` use `useSyncExternalStore` so components re-render when the eye toggles.
4. **Why not only AppShell?** Next.js App Router does not re-render the page slot when a Client layout updates state. Every page that displays euros must subscribe (or use a child that does).
## Rules
- Print / statement handouts use `euroVisible()` (never masked).
- Counts and percentages are not masked.
- Default on load: **hidden**.
## Acceptance
1. Dashboard: eye toggles amounts.
2. `/residents`, `/mapa`, `/receivables`, resident detail: same toggle updates amounts without navigation.
3. Idle ~30s → amounts hide again.
4. Prod (`:3000`) and test (`:3010`) behave the same.