The readme served two roles: design-decision source of truth and
work-status tracker. The status section grew into a plan the
orchestrator must navigate, so it moves to its own file with task
IDs, dependency edges, statuses, and per-item acceptance criteria.
readme.md remains authoritative for decisions (stack, formats,
workflow); workflow step 7 and AGENTS.md pointers now name
roadmap.md for status. Cross-references verified.
Also records: stale feature/epsilon-parser branch pointer (676e55e,
2 behind main) deleted locally; recreate from main when B1 starts.
6.2 KiB
Roadmap and status of functionality
This file is the roadmap. Design decisions that a roadmap item depends on are still owned by readme.md (the source of truth); this file tracks what is done, in flight, and planned, with status, dependencies, and acceptance criteria per item.
Status legend:
- ✅ done — implemented, tests green, merged to main
- 🔴 red — tests committed and failing (TDD in progress)
- 🟡 spec — specified, no code or tests yet
- ⚪ idea — planned, not specified
| ID | Area | Item | Status | Depends on |
|---|---|---|---|---|
| A1 | core | config: load, resolve, defaults, mask, validate | ✅ | — |
| A2 | core | db: connection URL, migration split/embed, backup/restore | 🔴 | A1 |
| B1 | core+cli | epsilon parser: file → rows → batch aggregates | 🟡 | A2 |
| B2 | cli | file import / file list: ingest + idempotency |
🟡 | B1 |
| B3 | cli | customer / card CRUD (batch, card, customer) |
🟡 | A2 |
| B4 | cli | invoice creation from batch data (invoice prepare) |
🟡 | B2, B3 |
| C1 | core | tsdrms xlsx parser (GL journal, cutoff partitioning) | ⚪ | A2 |
| C2 | core | subfranchise PDF statement parser | ⚪ | A2 |
| D1 | core | Fortnox voucher mapping (port spreadsheet → TOML) | ⚪ | C1 |
| E1 | server | axum API + sessions + roles | ⚪ | A2 |
| E2 | web | Leptos SPA (invoice portal for rental firms) | ⚪ | E1 |
| F1 | cli | daemon start/stop/status | ⚪ | E1 |
| G1 | spa | receipt reissue (retail fuel, by date + last4) | ⚪ | E2 |
| G2 | spa | to-do application for employees | ⚪ | E1 |
| G3 | core | car registry (owned/leased, costs, besiktning, status) | ⚪ | A2 |
Track A — foundations
A1 core/config ✅
Loading (--config flag → $RUSTYRPN_CONFIG → ./config.toml,
--env selects dev/test variants in the last slot only), built-in
defaults, secret masking for config show, validation. Tests green
(commit 9452962).
A2 core/db 🔴 — next task
12 unit tests committed red (commit 676e55e): connection_url
(percent-encoded credentials, with/without database),
split_statements (comment/string-aware), MIGRATION_V1 (embeds
Documentation/schema.sql as v1), backup_command /
restore_command (mariadb-dump/mariadb via MYSQL_PWD, never argv),
backup_filename (timestamped).
Scope: implement minimal green path. Pure functions — no live
database, no new dependencies. Do not alter the tests' intent.
Accept: cargo test green workspace-wide; fmt + clippy clean.
Track B — fuel station data (epsilon)
B1 epsilon parser 🟡
Branch feature/epsilon-parser to be created from main when work
starts (a stale earlier pointer was deleted 2026-10-08). Workflow
step 2 (spec + test checklist agreed with maintainer) is pending —
no failing test may be written before it. Fixtures ready:
data/fixtures/epsilon (batches 9405–9412, cumulative slice).
Sketch: 16-field TSV per readme §Data formats; filename batch number
must match every row; M/d/yyyy h:mm:ss AM/PM dates; rust_decimal
amounts; Quality 0 zero-value rows preserved; batch aggregates
(totals per quality, row count, date range) for the batches table.
B2 file ingest & idempotency 🟡
files table: filename = natural key + content hash (sha2, already a
core dep). Re-ingesting the same file must be a no-op. Open decision
(maintainer): test against scratch MariaDB vs mocked repo layer.
Open decision: Amount == Volume × Price — hard error or reported
warning.
B3 customers & cards 🟡
Contract cards = epsilon rows with non-empty customer number; stored unmasked as delivered (personal data rule: schema.sql / cli.md). CRUD per Documentation/cli.md; delete blocked while referenced.
B4 invoice creation 🟡
From batch/card data into invoices + invoice_items; Fortnox
export format TBD (depends on D1 decision).
Track C — rental data (tsdrms / Enterprise)
C1 tsdrms xlsx parser ⚪
GL journal (double-entry pairs), calamine-class crate needed —
ask before adding dependency. Critical quirk: monthly files
partition by Cutoff Date, not Transaction Date. Floats round to 2
decimals on ingest. Fixtures ready: data/fixtures/tsdrms.
C2 subfranchise PDF parser ⚪
Text-based 1-page statements; PDF text-extraction crate chosen when
the feature starts. Parse defensively (layout verified on 6 samples
only); European number format incl. (x,yy) negatives; line items by
pattern, not exact string. Fixtures ready as extracted text:
data/fixtures/subfranchise.
Track D — bookkeeping
D1 Fortnox voucher mapping ⚪
First task is porting the Apple Numbers mapping
(data/other_resources/, gitignored — read, never modify) into a
versioned TOML table in-repo before writing code against it.
Depends on C1 data model.
Track E — server & SPA
E1 axum API ⚪
JSON API, argon2id login, MariaDB-backed sessions behind HttpOnly/Secure/SameSite=Lax cookie, rate-limited, no user enumeration, roles director/employee/customer (customer queries scoped to session's company). New deps (axum, sqlx already partly in place) — ask before adding.
E2 Leptos SPA ⚪
Served by the same binary as the API.
Track F — deployment
F1 daemon 🟡→⚪
rpnc daemon start|status|stop per cli.md (pidfile + logs under
state dir; local-only status checks). Caddy reverse proxy and FreeBSD
jail packaging are out of scope for the repo (readme §Technology).
Track G — later features
G1 receipt reissue ⚪ (low priority)
Identify by date + last 4 (masked consumer cards make last4 available); render template; e-mail to customer.
G2 employee to-do app ⚪
G3 car registry ⚪
Owned/leased cars, per-car costs, besiktning tracking, status (active/broken/repair), tyre seasons.
Near-term ordering
- A2 → green baseline for everything.
- B1 spec discussion (maintainer gate) → B1 → B2 → B3 → B4: the fuel-sales vertical slice usable from the CLI.
- C1/C2/D1 extend into rentals + bookkeeping.
- E/F make it multi-user; G fills in.
Maintenance rules
- Every task updates this file in its own branch (workflow step 7); decision changes go to readme.md in the same commit.
- Status changes commit with the merge, not before.
- AGENTS.md §Current state must agree with this file; update both.