SPEC 020 User Onboarding - rafaelfqueiroz/allmywallet GitHub Wiki

SPEC-020 — User Onboarding

Status Draft
PRD source F10 (FR-11.1–11.22), F2.1 (FR-2.1–2.3)
Depends on SPEC-001, SPEC-005, SPEC-009, SPEC-010
Required by —
Milestone M8

Description

Everything this product does depends on one step the user has to perform by hand: exporting three files from B3 and uploading them. PRD R1 rates manual-import friction High likelihood, High impact — the core weakness of the v1 sourcing decision — and names guided onboarding as its mitigation. The success metric is explicit: more than 70% of signups reach a first successful import. A user who does not get through that step never sees a single thing the product was built for.

This spec was extracted from SPEC-005, which owned onboarding as F2.1 alongside the parsers. The flow reaches into authentication, the import pipeline, fixed-income contracts and wallets, so leaving it inside a spec about parsing three file formats made that spec responsible for four others' surfaces. SPEC-020 owns the sequence, the gating, the progress model and the empty states; the mechanics of each step stay with the spec that owns them and are cited rather than restated.

Two constraints shape the whole design. The first is that onboarding stores almost nothing: every step's completion is a query against data that already exists, for the same reason positions derive from the ledger — a stored flag can disagree with reality, and a user who deleted their only import would still read as onboarded. Exactly one fact is persisted, because exactly one is not derivable: that the user chose to dismiss the guide.

The second is that the guide ships no screenshots of investidor.b3.com.br. R2 already establishes that B3 changes things; the same redesign that breaks a parser silently invalidates every screenshot, and a stale screenshot is worse than none because it walks the user confidently to a button that has moved. The guidance is drawn by this project, stamped with the date it was last verified, and re-verified whenever a parser changes.

Business rules

What the flow covers

ID Rule
BR-020-01 Onboarding covers the path from first sign-in to a dashboard showing a real portfolio. It owns sequence, gating, progress and empty states; each step's mechanics belong to the spec that owns it and are cited, never restated.
BR-020-02 First successful sign-in routes to onboarding (SPEC-001 BR-001-04).
BR-020-03 Onboarding is complete at the first successfully committed import. Nothing else gates completion.
BR-020-04 The guided sequence is: export the three extracts → upload → review the staged preview → commit. Creating a first wallet is offered afterwards and is never a gate.
BR-020-05 Onboarding collects no personal data. SPEC-001 BR-001-05's limit stands unchanged: nothing beyond the Google subject ID, email, display name and picture URL. There is no registration to complete.

Progress is derived, not stored

ID Rule
BR-020-06 Every step's completion is derived by query. No onboarding progress table exists.
BR-020-07 The queries are: at least one committed import batch; any fixed-income contract with no contracted rate; any transaction with an unclassified movement type; at least one wallet.
BR-020-08 Derived state follows reality and is never latched. Deleting the only import makes onboarding incomplete again, and the dashboard returns to its empty state.
BR-020-09 The single persisted field is users.onboarding_dismissed_at, nullable. It is the only onboarding fact that is not a query, because nothing in the ledger records a decision not to proceed.
BR-020-10 No other onboarding state may be persisted. A future step that appears to need a flag needs a query instead.

Skipping and re-entry

ID Rule
BR-020-11 The guide is dismissible at any step. The user is never trapped in a wizard.
BR-020-12 Dismissal hides the guide. It never marks a step complete — the two are independent, and conflating them would let a dismissal fake an import.
BR-020-13 The guide can be reopened at any time from a help entry point, which clears onboarding_dismissed_at.
BR-020-14 A user who has dismissed the guide and still has no import continues to see the dashboard empty state. Dismissing guidance is not the same as declining to use the product.

Required gates live in the existing queue

ID Rule
BR-020-15 Unmet data-quality gates surface in the existing "Needs attention" queue (SPEC-010 BR-010-12). No second queue and no dedicated onboarding panel — a second surface splits "is there anything for me to do" into two places.
BR-020-16 The gates are: fixed-income contracts whose contracted rate could not be read (SPEC-009), unclassified movement types (SPEC-005), and purchases awaiting allocation (SPEC-010, already in that queue).
BR-020-17 Gates are not part of onboarding completion (BR-020-03). They persist while the underlying data is incomplete, which may be indefinitely, and that is not a failed onboarding.
BR-020-18 Each gate states what is wrong, what it prevents, and links to the one screen that resolves it. A gate that cannot say what it blocks is not worth showing.
BR-020-19 A missing fixed-income rate names its consequence plainly: that contract cannot be valued, so portfolio value is understated until it is supplied.

Export guidance

ID Rule
BR-020-20 The guide explains exporting Movimentação, Negociação and Posição from investidor.b3.com.br (FR-2.1).
BR-020-21 It advises selecting the earliest available date, so full history arrives on the first import rather than requiring a second pass (FR-2.2).
BR-020-22 Files may be uploaded together or one at a time, in any order (FR-2.3).
BR-020-23 Guidance uses diagrams authored by this project. Screenshots of investidor.b3.com.br are prohibited: no third-party interface is committed to this repository.
BR-020-24 Each diagram set carries a "verified against B3 as of <date>" stamp, visible to the user. Staleness is visible rather than silent.
BR-020-25 The stamp is re-verified whenever a B3 parser changes (SPEC-005) — a parser change is evidence that B3 has moved.
BR-020-26 The guide states that only the three B3 extracts are accepted, and that assets outside B3 custody need manual entry (SPEC-006). It never implies completeness the sourcing strategy cannot deliver (PRD §4).

Empty states

ID Rule
BR-020-27 Before the first import the dashboard shows an explicit onboarding empty state, not zeros. A portfolio displayed as R$ 0,00 is a false claim; an empty state is the truth.
BR-020-28 The four reports keep their own empty states (SPEC-012–SPEC-015). This spec does not restate them.
BR-020-29 No screen fabricates sample or demo data. A first-run user never sees numbers that are not theirs.

Language and accessibility

ID Rule
BR-020-30 All guidance is pt-BR through next-intl, with market vocabulary left in Portuguese (SPEC-016).
BR-020-31 The whole flow is completable by keyboard alone and meets WCAG 2.1 AA (SPEC-016). Diagrams carry text alternatives that convey the steps, not just a caption.

Acceptance Criteria

  • First sign-in lands on onboarding, not on an empty dashboard.
  • Onboarding reads as complete immediately after the first import commits, and not before.
  • Deleting the only import returns onboarding to incomplete and the dashboard to its empty state.
  • No onboarding progress table exists; completion is reproduced entirely by query in a test that inspects the schema.
  • users.onboarding_dismissed_at is the only onboarding column added.
  • Dismissing the guide hides it, marks no step complete, and persists across devices for the same user.
  • Reopening the guide from the help entry point clears the dismissal.
  • A dismissed guide with no import still shows the dashboard empty state.
  • A fixed-income contract with no contracted rate appears in "Needs attention", names the consequence, and links to the screen that fixes it.
  • An unclassified movement type appears in the same queue, with the same three elements.
  • No dedicated onboarding panel exists; gates are only ever in "Needs attention".
  • Unmet gates do not prevent onboarding reading as complete.
  • The guide names all three extracts and advises the earliest available date.
  • Extracts can be uploaded together or singly, in any order, and reach the same staged preview.
  • No image in the repository is a capture of investidor.b3.com.br — verified by review, recorded in the PR.
  • Every diagram set renders its "verified as of" date to the user.
  • The dashboard before any import shows an empty state and no zero-valued figures.
  • No sample or demo data appears anywhere for a new account.
  • The entire flow is completable by keyboard alone and passes axe at WCAG 2.1 AA.
  • Diagram text alternatives convey the export steps, verified by reading them with the images suppressed.
  • No personal data beyond SPEC-001 BR-001-05's four fields is collected at any point.

Out of Scope

  • Collecting profile or registration data of any kind (BR-020-05). There is nothing to complete.
  • CSV or any non-B3 file format. SPEC-005's exclusion stands; onboarding guides the .xlsx extracts only.
  • Parsing, preview and commit mechanics — SPEC-005.
  • Editing fixed-income contracts — SPEC-009. Onboarding surfaces the gap and links there.
  • Wallet creation mechanics — SPEC-010.
  • Import reminders and staleness nudges — already specified as FR-4.1–4.3 in SPEC-005. Onboarding is the first run, not the ongoing habit.
  • Email onboarding sequences, drip campaigns or re-engagement mail.
  • Feature tours beyond the first import. Reports, wallets, balancing, opportunity and goals are discovered in the product, not walked through.
  • Any stored onboarding state beyond the dismissal timestamp (BR-020-10).

Decision Logs

# Decision Alternatives considered Rationale
DL-020-01 Extracted from SPEC-005 into its own spec. Expand F2.1 inside SPEC-005; a pure index spec that owns nothing The flow spans authentication, import, fixed income and wallets. Owning it inside the import spec would make a spec about parsing three file formats responsible for four other specs' surfaces. A pure index was rejected because then nothing owns the question of what a half-finished onboarding looks like — which is most of the actual design.
DL-020-02 Complete at the first successful import. All required gates cleared; complete at first import plus a second tracked gate-clearance metric Matches the PRD's stated metric exactly. Gate clearance depends on how messy a given user's extracts happen to be, so folding it into completion would make the number measure B3's data quality as much as this flow's effectiveness.
DL-020-03 Progress derived by query, stored nowhere. An onboarding_progress table written as each step completes Identical reasoning to positions deriving from the ledger (DM-4): stored state can disagree with reality. A user who deletes their only import would still read as onboarded, and the dashboard would offer a portfolio that no longer exists. Deriving costs a few queries and cannot drift.
DL-020-04 One exception: users.onboarding_dismissed_at. Browser storage only; make the guide non-dismissible Dismissal is the only onboarding fact that is not a query. Browser storage forgets it on a second device, in a private window and after clearing site data — which reads as the product ignoring an instruction the user gave. Making the guide non-dismissible removes the contradiction but traps a user who wants to look around before committing data. One nullable column on an existing row is the smallest possible exception.
DL-020-05 Gates reuse the "Needs attention" queue. A dedicated onboarding panel; a first-run checklist widget SPEC-010 BR-010-12 already established one queue for pending allocations and unclassified imports, and these gates are the same kind of thing. A second surface would compete with it for the same question, and a user with items in both would have no way to know which mattered.
DL-020-06 Project-authored diagrams with a verification stamp; screenshots prohibited. Real screenshots of investidor.b3.com.br, as FR-2.1 literally asks; text steps plus a deep link only R2 already establishes that B3 changes its exports. The same redesign silently invalidates a screenshot, and a stale screenshot is worse than none — it walks the user confidently to a control that moved, at the step the PRD calls the riskiest in the product. Screenshots also put another company's interface in this repository. Text alone was rejected as the weakest guidance available for that same step.
DL-020-07 No sample or demo data, ever. Seed a demo portfolio so a new account looks alive This product's entire value is that its numbers are correct. A first-run user seeing figures that are not theirs is the fastest available way to destroy that, and any demo rows inside a tenant immediately become data that must be exported, deleted and reasoned about under SPEC-004.
DL-020-08 No profile fields collected during onboarding. Collect preferences, base currency or tax residency while the user is already in a form SPEC-001 BR-001-05 caps stored personal data at what Google supplies, with the words "Nothing else". Every added field becomes a subject-access, correction and deletion obligation under SPEC-004, and none has a demonstrated need. Notification opt-in already has its own consent path in SPEC-018.
⚠️ **GitHub.com Fallback** ⚠️