SPEC 004 LGPD Data Rights - rafaelfqueiroz/allmywallet GitHub Wiki

SPEC-004 — LGPD Compliance & Data Subject Rights

Status Draft
PRD source §8.2 (FR-8.6–8.22)
Depends on SPEC-001, SPEC-003, SPEC-005 (CPF stripping at parse)
Required by SPEC-018, SPEC-019 (notification consent)
Milestone M6 (with FR-8.7 pulled forward into M1)

Description

The LGPD programme: minimisation, legal bases, consent records, data-subject rights, retention and incident response.

One legal point drives the design and must not be got wrong. Investment holdings are not "dados pessoais sensíveis" under LGPD Art. 5, II — that category is racial/ethnic origin, religious belief, political opinion, union membership, health, sex life, genetic and biometric data. Financial holdings are ordinary personal data. Building a compliance programme on the mistaken premise that they are sensitive leads to the wrong controls in the wrong places. This product nonetheless applies protection equivalent to the sensitive tier by choice, because the impact of disclosure is high.

One requirement is scheduled earlier than the rest. FR-8.7 — CPF stripping — belongs to M1, not M6. B3 extracts contain the user's CPF, and once it has been written to a database and a backup, "we don't store it" stops being true. It must be correct the first time an extract is parsed.

Business rules

Minimisation

ID Rule
BR-004-01 Personal data collected is limited to: Google subject ID, email, display name, profile picture URL, and the investment data the user imports or enters.
BR-004-02 The CPF present in B3 extracts is stripped at parse time and never persisted — not in the ledger, not in ImportRow.raw_payload, not in logs, not in error reports. The application has no functional need for it, therefore it is not collected.
BR-004-03 Uploaded source files are not retained after a batch is committed or cancelled. Only parsed, CPF-free rows persist.
BR-004-04 Application logs, error reports and traces contain no personal data. Import diagnostics log structural facts (unmapped movement-type strings, row counts) and never values.

Legal basis & consent

ID Rule
BR-004-05 Processing basis is documented per data category: contract execution (Art. 7, V) for investment data required to deliver the service; consent (Art. 7, I) for optional email — reminders, opportunity state changes (SPEC-018) and goal achievement (SPEC-019) — and any future analytics.
BR-004-06 Consent is granular, opt-in, and separately revocable per purpose. Bundled consent is prohibited.
BR-004-07 Each consent decision is recorded in Consent with purpose, timestamp and the policy version in force at that moment.
BR-004-08 Revoking optional consent never degrades core functionality.

Data subject rights (Art. 18)

ID Rule
BR-004-09 Deletion is self-service from settings. Access is revoked immediately; all tenant-scoped data is irreversibly removed within the configured window (default 30 days). Confirmed by email.
BR-004-10 Deletion cascades to every tenant-scoped table. A table added later without a deletion path is a defect.
BR-004-11 Access and portability are self-service: a complete export of personal and investment data in machine-readable form (JSON + CSV), obtainable without contacting support.
BR-004-12 Correction is satisfied by manual transaction management (SPEC-006) and profile editing.
BR-004-13 A plain-language privacy policy lists data collected, purposes, legal bases, retention periods and all subprocessors.
BR-004-14 Rights requests requiring manual handling are answered within 15 days (Art. 19).

Retention, security & incident response

ID Rule
BR-004-15 Active-account data is retained while the account exists. Audit logs are retained for a configured period (default 12 months).
BR-004-16 Backups purge deleted-user data within one backup cycle, and that cycle length is stated in the privacy policy.
BR-004-17 Operator access to personal data is recorded in AuditLog.
BR-004-18 A subprocessor inventory is maintained (hosting, database, email, market data, error tracking), each assessed for LGPD adequacy and published.
BR-004-19 Documented incident response: containment, ANPD notification and affected-user notification per Art. 48.
BR-004-20 A named data protection contact is published (Art. 41).

Acceptance Criteria

  • Parsing a real B3 extract containing a CPF results in no CPF anywhere: verified by searching the database, ImportRow.raw_payload, logs and error reports for the value.
  • The uploaded source file is absent from storage after commit and after cancellation.
  • An induced parser error produces a report containing no personal data.
  • A user exports all their data self-service and receives valid JSON and CSV covering profile, transactions, wallets, allocations and consents.
  • A user deletes their account self-service; access is revoked immediately.
  • After the deletion window, no row referencing that user remains in any tenant-scoped table — verified by automated test that enumerates tables rather than checking a hardcoded list.
  • Adding a new tenant-scoped table without a deletion path fails CI.
  • Consent is granular: the user can decline reminder emails while using every core feature.
  • Revoking consent is recorded with a timestamp and the policy version.
  • The privacy policy is reachable pre-signup and lists every subprocessor actually in use.
  • Operator access to personal data appears in AuditLog.
  • Retention windows are configurable within a validated lawful range and cannot be set to an unlawful value (SPEC-002, BR-002-04).
  • The incident response runbook exists and names the ANPD notification path.

Out of Scope

  • Technical tenant isolation (SPEC-003).
  • Formal DPIA / RIPD documentation, unless required by counsel.
  • Appointing a formal DPO — a published contact satisfies Art. 41 at this scale.
  • GDPR, CCPA or other non-Brazilian regimes.
  • Cookie consent banners beyond what strictly-necessary-only requires (no non-essential cookies are set).
  • Legal review of the privacy policy text — drafted here, reviewed by counsel outside this spec.
  • Data residency guarantees.

Decision Logs

# Decision Alternatives considered Rationale
DL-004-01 Financial holdings treated as ordinary personal data legally, sensitive-tier protection operationally. Classify as "dados sensíveis" for safety Misclassifying is not a harmless over-caution: it puts the compliance programme on a false premise and misdirects controls. The honest position — ordinary data, elevated protection by choice — is both accurate and defensible.
DL-004-02 CPF stripped at parse, never stored. Store it for future IR reporting The app has no function needing it today. Storing "just in case" converts a nice-to-have into a permanent breach liability and a data-subject-rights obligation. If IR reporting (PRD Q3) is later built, collecting CPF then is a deliberate, scoped decision with its own review.
DL-004-03 CPF stripping scheduled in M1, not M6 with the rest of LGPD. Deliver the whole programme in M6 Every other LGPD control can be retrofitted. This one cannot: once a CPF is in a database and a backup, it is there, and "we never stored it" becomes false retroactively. It must be right at first parse.
DL-004-04 Source files deleted after commit. Retain for re-processing and support Retention would help debugging parser issues. But the file is the single richest personal-data object in the system and the only place a raw CPF ever exists. Parsed, CPF-free rows are enough to reconstruct anything needed.
DL-004-05 Deletion and export are self-service, not support-mediated. Email support, fulfil manually within 15 days Manual fulfilment is lawful but slow, error-prone, and requires an operator to access personal data to satisfy a privacy request — a contradiction. Self-service is stronger compliance and less operational load.
DL-004-06 Deletion verified by enumerating tables, not by checking a list. Test against a maintained list of tables A hardcoded list silently goes stale the moment someone adds a table, and the failure surfaces only when a regulator or user asks. Enumeration fails loudly at CI time instead.