docs: split roadmap out of readme into Documentation/roadmap.md

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.
This commit is contained in:
hermes
2026-10-08 12:35:58 +02:00
parent 8e03af1307
commit a350afc053
3 changed files with 177 additions and 53 deletions
+18 -14
View File
@@ -1,12 +1,14 @@
# AGENTS.md — working rules for coding agents on RustyRPN # AGENTS.md — working rules for coding agents on RustyRPN
readme.md is the single source of truth for design decisions and roadmap. readme.md is the single source of truth for design decisions. The
Read at minimum these sections before starting work: roadmap lives in Documentation/roadmap.md.
Read at minimum these before starting work:
- §Workflow — the TDD loop you are expected to follow - readme.md §Workflow — the TDD loop you are expected to follow
- §General guidelines for AI — hard prohibitions - readme.md §General guidelines for AI — hard prohibitions
- §Data formats — input formats, edge cases, and where test fixtures live - readme.md §Data formats — input formats, edge cases, and where test
- §Roadmap and status of functionality — what is green, red, or unstarted fixtures live
- Documentation/roadmap.md — what is green, red, or unstarted
## Environment ## Environment
@@ -18,17 +20,18 @@ Read at minimum these sections before starting work:
`src/cli` (rpn-cli, binary `rpnc`). `src/server` and `src/web` are `src/cli` (rpn-cli, binary `rpnc`). `src/server` and `src/web` are
planned but not scaffolded yet. planned but not scaffolded yet.
## Current state (verify against readme.md roadmap; update both when it changes) ## Current state (verify against Documentation/roadmap.md; update both when it changes)
- core/config: implemented, tests green. - core/config: implemented, tests green.
- core/db: tests committed and RED (they reference functions that do not - core/db: tests committed and RED (they reference functions that do
exist yet — the crate does not compile its test target). The first task not exist yet — the crate does not compile its test target). The first
is the minimal implementation to turn them green. Do not weaken or task is the minimal implementation to turn them green. Do not weaken or
rewrite these tests to make them pass; they encode agreed behaviour. rewrite these tests to make them pass; they encode agreed behaviour.
- cli: `fn main() {}`. Command surface specified in Documentation/cli.md. - cli: `fn main() {}`. Command surface specified in Documentation/cli.md.
- feature/epsilon-parser: branch exists, zero commits. Needs workflow - feature/epsilon-parser: does not exist yet. Create it from `main`
step 2 (spec + test checklist agreed with the maintainer) before any when parser work starts (a stale early pointer was deleted
failing test is written. 2026-10-08). Workflow step 2 (spec + test checklist agreed with the
maintainer) must complete before any failing test is written.
## Test data ## Test data
@@ -58,6 +61,7 @@ Read at minimum these sections before starting work:
`cargo clippy` clean for files you touched. `cargo clippy` clean for files you touched.
2. Every checklist item from the task's spec verified — by a test or by 2. Every checklist item from the task's spec verified — by a test or by
a command you actually ran, not by inspection alone. a command you actually ran, not by inspection alone.
3. readme.md roadmap updated in the same branch. 3. Documentation/roadmap.md updated in the same branch (and readme.md
if a design decision changed).
4. A short summary for the maintainer: what changed, what is still red, 4. A short summary for the maintainer: what changed, what is still red,
suggested next step. suggested next step.
+147
View File
@@ -0,0 +1,147 @@
# 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
1. A2 → green baseline for everything.
2. B1 spec discussion (maintainer gate) → B1 → B2 → B3 → B4: the
fuel-sales vertical slice usable from the CLI.
3. C1/C2/D1 extend into rentals + bookkeeping.
4. 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.
+12 -39
View File
@@ -271,9 +271,11 @@ Use a test-driven-development inspired approach, specifically the following work
5.3 Create a git commit per passing test 5.3 Create a git commit per passing test
5.4 Iterate for each test until they all pass 5.4 Iterate for each test until they all pass
6. Verify everything on the checklist has been completed 6. Verify everything on the checklist has been completed
7. Update roadmap 7. Update roadmap (Documentation/roadmap.md)
- this file is the source of truth - roadmap.md tracks what is done, in flight, or planned
- any task that changes a decision (stack, format, workflow) updates it in the same commit - readme.md is the source of truth for design decisions: any task
that changes a decision (stack, format, workflow) updates it in
the same commit
8. Provide a short list of suggestions for improvements and include a suggested global next step 8. Provide a short list of suggestions for improvements and include a suggested global next step
### General guidelines for AI ### General guidelines for AI
@@ -296,42 +298,13 @@ Use a test-driven-development inspired approach, specifically the following work
- Be concise - Be concise
## Roadmap and status of functionality ## Roadmap and status of functionality
### Active
* core/config — done (loading, resolution, defaults, masking, validation; The roadmap lives in Documentation/roadmap.md: per-item status (done /
tests green, commit 9452962) red / spec / idea), dependencies, acceptance criteria, and near-term
### In development ordering. Workflow step 7 updates that file; this document remains the
* core/db — tests committed and RED (connection URL, migration splitting, source of truth for design decisions (stack, formats, workflow) —
embedded schema v1, backup/restore; commit 676e55e). Next step: minimal a task that changes a decision updates readme.md, a task that changes
implementation until green; do not alter the tests' intent. *what is built next* updates roadmap.md.
* cli
* command structure specified in Documentation/cli.md
* ingest tab-separated .txt files containing transactions from automated gas station into a MariaDB
* feature branch feature/epsilon-parser is open but empty: no
spec/checklist yet (workflow step 2 pending); sanitized
fixtures are ready (data/fixtures/epsilon)
* create invoices from data in database
### Future / planned
* cli
* ingest xlsx files containing car rental transactions exported from tsdrms
* prepare bookkeeping voucher to be entered into Fortnox accounting/bookkeeping software suite
* ingest pdf files containing monthly settlement data from Enterprise
* spa
* website for car rental firms to check details regarding invoices
* receipt reissue for retail fuel sales (low priority)
* customer requests a receipt for a past fuel purchase (forgot to take it, or a printing issue)
* identifies the transaction by date + last 4 digits of the card number
* consumer cards are stored masked (e.g. `549543******5778`), so the last 4 digits are available for lookup
* creates a new receipt from a template
* sends it to the customer by e-mail
* to-do-application for employees
* car registry for RPN
* cars directly owned
* leased cars
* keeps track of costs associated with each car
* keeps track of yearly car inspections (besiktning)
* keeps track of general car status
* winter or summer tyres
* active, broken, being repaired (i.e. general status)
## Glossary ## Glossary
- aktiebolag: limited company - aktiebolag: limited company