SPEC 019 Wallet Goals - rafaelfqueiroz/allmywallet GitHub Wiki

SPEC-019 β€” Wallet Goals

Status Draft
PRD source F9 (FR-10.1–10.24)
Depends on SPEC-009, SPEC-010, SPEC-013, SPEC-014
Required by β€”
Milestone M7

Description

Wallets exist because money has purposes. SPEC-010 BR-010-02 already lets a wallet record a goal, but explicitly as decoration: "descriptive in v1; not used in any calculation." This spec promotes it β€” a goal becomes a number the product measures against.

Two kinds, matching the two questions a purpose-driven wallet raises. A growth goal asks how much have I built, measured either as the amount invested or as what it is worth today. An earnings goal asks how much is it paying me, which is the question Marina's persona exists for: a dividend wallet is not built to be large, it is built to produce income.

A goal carries an amount but no target date. That is a real simplification with a real cost, recorded here rather than discovered later: without a date there is no required-pace line and no projection, so the burn-up chart answers "how far have I come" and cannot answer "am I on track". The chart is honest about that instead of implying a schedule that was never set.

The earnings chart carries a second constraint that shaped its arithmetic: it shows exactly one calendar year and never crosses a year boundary. That rules out the 12-month moving average SPEC-014 uses, because a January point on a moving average is built from the previous February. The replacement is a year-to-date average, which resets each January and reads nothing from outside the selected year β€” so the same underlying income produces a different line on this screen than on the Earnings report. Deliberate, and labelled on both.

Business rules

Model

ID Rule
BR-019-01 A goal belongs to exactly one wallet. Portfolio-scope goals are out of scope.
BR-019-02 A wallet may hold more than one goal, of either kind, simultaneously.
BR-019-03 A goal is one of two kinds: growth or earnings. The kind is fixed at creation.
BR-019-04 A goal has an amount in BRL and no target date. This supersedes SPEC-010 BR-010-02: a wallet's goal is now calculated, not descriptive.
BR-019-05 A growth goal names its basis β€” amount invested (contributions at cost) or current value (market value). The basis is chosen per goal, so a wallet can carry one of each.
BR-019-06 An earnings goal names a period β€” monthly or yearly β€” and an amount in BRL.
BR-019-07 Goal amounts are money and obey the money rules (CR-4, AR-06–AR-10).
BR-019-08 Deleting a wallet deletes its goals. It never deletes transactions or allocations (SPEC-010 BR-010-07).

Growth goals

ID Rule
BR-019-09 Growth progress is cumulative since the wallet's first allocation and never resets. Invested amount and market value are stocks, not annual flows.
BR-019-10 The chart is a burn-up: the real line from daily valuation snapshots (SPEC-009) plus a horizontal goal line. There is no pace line and no projection, because there is no date to compute one against (BR-019-04).
BR-019-11 On the amount invested basis, progress uses allocated quantities at their cost basis at allocation (SPEC-010 BR-010-22).
BR-019-12 On the current value basis, progress uses the wallet's market value, with accrued fixed income marked estimated (CR-1) exactly as elsewhere.
BR-019-13 The growth chart is not year-scoped. BR-019-19 governs the earnings chart only.

Earnings goals

ID Rule
BR-019-14 Monthly income comes from SPEC-014's earnings projection at wallet scope. This spec computes no income of its own.
BR-019-15 A monthly goal renders as a horizontal line across the twelve months of the selected year.
BR-019-16 A yearly goal renders against cumulative income within the selected year.
BR-019-17 A year-to-date average line accompanies the monthly bars: the mean of the months elapsed within the selected year. January is January alone; December is the mean of twelve months.
BR-019-18 The year-to-date average resets at each year boundary and reads no data from outside the selected year. It is explicitly not SPEC-014's 12-month moving average, and both charts label which line they show β€” the same income produces two different lines by design, and an unlabelled difference would read as a defect.
BR-019-19 The earnings chart shows exactly one calendar year, selected by the user and defaulting to the current one. No series, figure or axis may span a year boundary.
BR-019-20 The current month's income is shown as its own figure beside the chart. Viewing a closed year it is replaced by that year's total, since a closed year has no current month.
BR-019-21 A selected year with no income renders an explicit empty state, never a row of zeros.
BR-019-22 Year selection offers only years in which the wallet existed and had allocations.

Achievement

ID Rule
BR-019-23 A goal is achieved when progress reaches or exceeds its amount. For an earnings goal, within the period it names.
BR-019-24 Achieved goals are marked with the date achieved and stay visible. Nothing is archived or deleted automatically.
BR-019-25 One email is sent on achievement where the user has opted in (SPEC-004; the consent and unsubscribe model of SPEC-018 BR-018-25–27 applies unchanged).
BR-019-26 A goal falling back below its amount keeps its achieved marker and date. The marker records that it happened, not that it still holds.
BR-019-27 Goals are current-state. Editing the amount moves the goal line only; the real line comes from snapshots and earnings and is unaffected by the edit.

Acceptance Criteria

  • A wallet can carry a growth goal and an earnings goal at the same time, each charted separately.
  • A growth goal on the amount invested basis reconciles to the wallet's total contributions at cost.
  • A growth goal on the current value basis reconciles to the wallet's Portfolio Value for the same date (cross-report, SPEC-013).
  • The growth chart shows a real line and a flat goal line, and no pace or projection line anywhere.
  • The growth chart spans the wallet's whole life and does not reset in January.
  • Accrued fixed income inside a current-value goal is marked estimated.
  • The earnings chart shows one calendar year; switching year redraws it entirely.
  • No earnings series, tooltip or axis label references a month outside the selected year.
  • The year-to-date average at January equals January's income; at December it equals the mean of the twelve months.
  • The same wallet and period produce a different average line here than on the Earnings report, and each chart names which average it shows.
  • Viewing the current year shows the current month's income; viewing a closed year shows that year's total in its place.
  • A year with no income shows an empty state rather than twelve zero bars.
  • Total earnings for a selected year equal the Earnings report's total for the same wallet and year (cross-report, SPEC-014).
  • Reaching a goal marks it achieved with the date, keeps it visible, and sends exactly one email when opted in.
  • A goal that dips back below its amount retains the achieved marker and its original date.
  • Raising a goal amount moves only the goal line; every historical point on the real line is unchanged.
  • Deleting a wallet removes its goals and leaves every transaction intact.
  • Charts are reachable as text or table (SPEC-016 BR-016-16).

Out of Scope

  • Target dates, pace lines, projections and "on track" verdicts β€” see DL-019-01.
  • Portfolio-scope goals. Wallet-scoped in v1.
  • Inflation-adjusted goal amounts (IPCA-indexed targets) β€” see DL-019-08.
  • Contribution scheduling, reminders or automatic aporte planning.
  • Any recommendation about how to reach a goal β€” SPEC-015 BR-015-06 applies here as everywhere.
  • Cross-year earnings views (BR-019-19). The Earnings report (SPEC-014) remains the place to see income across years.
  • Goal templates or suggested amounts. The product originates no number.

Decision Logs

# Decision Alternatives considered Rationale
DL-019-01 A goal has an amount but no target date. Date required, with a required-pace line; date optional One chart shape, one empty state, no projection arithmetic. The cost is recorded: a burn-up chart normally exists to answer "is my current rate enough", and without a date this one cannot. Adding an optional date later is additive β€” the goal line stays and a pace line joins it β€” so nothing here forecloses it.
DL-019-02 The earnings chart shows one calendar year and never crosses the boundary. A rolling twelve-month window; a multi-year view Income is read by calendar year in Brazil, which is also how it is declared for IR. A rolling window makes "how much did I receive in 2026" a question the chart cannot answer directly.
DL-019-03 Year-to-date average, resetting each January. SPEC-014's 12-month moving average computed across the boundary; no average line at all BR-019-19 forbids reading data outside the selected year, and a 12-month moving average necessarily does. The consequence is accepted deliberately: the line smooths least in Q1, which is exactly where an irregular payer looks worst. Dropping the line entirely was worse β€” DL-014-02 already established that raw monthly bars hide the trend.
DL-019-04 Growth goals stay cumulative; year scoping applies to earnings only. Year-scope both charts Invested amount and market value are stocks. Resetting them each January would restart the burn-up at zero against an unchanged goal, making a R$ 100.000 target unreachable by construction in any single year. A year-scoped growth goal is a coherent product β€” an annual contribution target β€” but a different one from what this spec defines.
DL-019-05 Achieved goals are marked and stay visible; the marker survives a dip. Auto-archive on achievement; no achieved state at all Auto-archiving hides the moment the user most wants to see, and creates an awkward reversal case when the value falls back. Treating the marker as a record of an event rather than a current status makes the dip case trivial and honest.
DL-019-06 SPEC-010 BR-010-02 promoted from descriptive to calculated. Keep the descriptive text field and add goals as a separate concept Two fields both called "goal" on the same wallet, one decorative, is a trap. The existing text becomes the goal's name.
DL-019-07 Wallet scope only. Portfolio-level goals as well The wallet is the unit of purpose in this product β€” a portfolio-level goal is the sum of purposes, which is the number SPEC-013 already reports. Adding a second scope doubles the surface for a question already answered.
DL-019-08 No inflation adjustment. IPCA-indexed goal amounts, shown in real terms A real-terms target is meaningful over a decade and near-meaningless over a year, so it belongs with target dates rather than without them. Deferred as a pair: if DL-019-01 is ever revisited, this should be revisited in the same change.