Allow recurring costs and confirmations to remain unassigned when created from a purchase without a post. Add browser backup retention and restore controls, with coverage and documentation updates.
144 lines
6.9 KiB
Markdown
Executable File
144 lines
6.9 KiB
Markdown
Executable File
# Product
|
|
|
|
<!-- impeccable:product-schema 1 -->
|
|
|
|
## Platform
|
|
|
|
web
|
|
|
|
## Users
|
|
|
|
One person: the owner of the money, managing their own budget. They are leaving
|
|
a spreadsheet, so they already know their own categories, already think in
|
|
months, and value speed of entry over guidance. They tolerate rough edges in
|
|
exchange for the tool doing exactly what they mean.
|
|
|
|
Confirmed permanently single-user. One person, one browser, one dataset. There
|
|
are no accounts, no second role, and no shared or household use planned.
|
|
|
|
## Product Purpose
|
|
|
|
Envelope budgeting for a single person, replacing a spreadsheet.
|
|
|
|
Money is divided each month into named envelopes ("posts"). Unspent allocation
|
|
carries into the next month; overspending carries forward as debt. The app
|
|
answers two questions at a glance: how much is left in this envelope, and did I
|
|
overspend.
|
|
|
|
Success is that the owner stops maintaining a spreadsheet, and that a month's
|
|
purchases can be entered fast enough not to be a chore.
|
|
|
|
## Positioning
|
|
|
|
Two things a general budgeting app does not do:
|
|
|
|
- **Envelope rollover is the whole model, not a feature.** Every figure derives
|
|
from one left-fold across months, so a balance is always the honest
|
|
consequence of every prior month.
|
|
- **The data never leaves the browser and never needs an account.** IndexedDB is
|
|
the only store. That is a deliberate product position, not a missing backend.
|
|
|
|
## Operating Context
|
|
|
|
The owner records spending after the fact, often in batches — a grocery trip is
|
|
twenty lines entered in one sitting, not twenty separate visits. Income arrives
|
|
monthly and varies, so it is entered per month rather than assumed.
|
|
|
|
Purchases frequently belong to more than one envelope (food bought at a social
|
|
event), and larger purchases are spread across several months deliberately
|
|
rather than absorbed by one.
|
|
|
|
Money is handled in DKK, USD and EUR, with DKK as the base.
|
|
|
|
## Capabilities and Constraints
|
|
|
|
Confirmed and in place:
|
|
|
|
- Nested budget folders organize posts, bills, and optionally individual
|
|
purchases. A single-post bill starts beneath that post but can be moved
|
|
independently. Folder Bills due reports scheduled bill prices for the selected
|
|
month; posts alone hold envelope balances. A purchase's separate row never
|
|
changes which posts its splits charge.
|
|
- Posts (envelopes) with monthly allocation, created and archived by the owner.
|
|
Posts are archived, never deleted, because purchases reference them.
|
|
- A post with no applicable allocation rule still records spending and shows its
|
|
balance, but is not labelled overspent. An explicit zero allocation is a
|
|
budget rule and can be overspent.
|
|
- Allocation is either a fixed amount or a percentage of that month's income.
|
|
- A purchase can be split across several posts, by percentage or by fixed
|
|
amounts, and can also be spread across future months as a payment plan. The
|
|
two compose.
|
|
- A purchase may have no post. It remains visible in its month and counts in
|
|
Spent, while leaving envelope balances unchanged.
|
|
- Per-month income, entered directly, varying month to month.
|
|
- Multi-currency (DKK/USD/EUR) against a user-maintained exchange-rate table,
|
|
with an optional on-demand fetch that fails soft and is never required.
|
|
- JSON export/import and ODS (spreadsheet) export, both generated in the
|
|
browser. On each app start, a separate browser-stored session backup is made
|
|
before editing is available; recent daily, weekly and monthly checkpoints can
|
|
be downloaded or restored from Settings. These checkpoints share the browser
|
|
origin with the live data, so JSON export is still needed for protection
|
|
against losing browser storage.
|
|
- Offline-capable installable PWA. Currently deploys as one static artifact to
|
|
both GitHub Pages (under a subpath) and a self-hosted Docker image.
|
|
- Recurring costs — a bill that repeats every N months, every N days, or
|
|
every N weeks on a weekday, optionally split across posts like any purchase.
|
|
A cost may have no post: it remains expected without moving an envelope's
|
|
projected balance, and confirming it records unassigned spending. A cost is
|
|
anchored one of two ways: `calendar` holds a fixed grid of due dates, so
|
|
paying two months at once still leaves nothing due until the one after; a
|
|
cost anchored to its **last charge** has no grid at all and can be charged
|
|
any number of times in one cycle, its next due date always one cycle after
|
|
whichever charge was most recent — a phone plan that recharges early when
|
|
its data runs out is the case this exists for. Each due date on the
|
|
calendar model is a projected occurrence the owner confirms into a real
|
|
purchase; a recurring cost can also be tagged onto a purchase, or created
|
|
from one, while it is being entered, rather than only from Settings. The
|
|
month view shows what is still expected alongside a second, projected
|
|
balance per post, so a known bill is visible before it is paid without
|
|
touching the reconciled figure a bank statement is checked against.
|
|
|
|
Terminology: an envelope is called a **post**. A **finance plan** is a purchase
|
|
spread across months. An **override** is a one-month exception to a post's
|
|
allocation. A **recurring cost** is a bill expected to repeat; each due date it
|
|
projects is an **occurrence**; **confirming** an occurrence turns it into a
|
|
real purchase.
|
|
|
|
Undecided: nothing outstanding at the product level.
|
|
|
|
## Brand Commitments
|
|
|
|
The product is called **Budget 2.0**. No logo, wordmark, or brand assets exist,
|
|
and none have been commissioned.
|
|
|
|
## Evidence on Hand
|
|
|
|
None, and none may be invented. This is a personal tool: there are no
|
|
customers, testimonials, case studies, usage statistics, press, pricing, or
|
|
third-party integrations. Any future surface must not manufacture them.
|
|
|
|
The only real content is the owner's own budget data, which never leaves their
|
|
browser and is therefore never available as example material. Illustrative data
|
|
must be visibly synthetic.
|
|
|
|
## Product Principles
|
|
|
|
1. **Over-budget is always allowed.** The app reports the truth and never
|
|
blocks, clamps, or hides overspending. A negative balance is a normal value.
|
|
2. **Changing an allocation must never destroy history.** Adjusting what a post
|
|
gets going forward leaves what it got before intact and still visible.
|
|
3. **Splitting a purchase across posts must stay easy.** It is a routine act,
|
|
not an advanced feature, and must not be buried behind extra steps.
|
|
4. **The data stays portable and in the owner's hands.** Export is always
|
|
available and always complete; nothing traps a budget inside the app.
|
|
5. **Entry speed is a feature.** Recording a month of spending is the most
|
|
repeated act in the product, and friction there is the reason spreadsheets
|
|
get abandoned.
|
|
|
|
## Accessibility & Inclusion
|
|
|
|
No condition-specific requirement was established by the owner. The existing
|
|
implementation holds itself to WCAG AA contrast, visible keyboard focus, and
|
|
respecting reduced-motion preferences; keyboard-first entry is a stated goal of
|
|
the fast-entry flow rather than only an accessibility accommodation.
|