Commit Graph
16 Commits
Author SHA1 Message Date
jakob 9452962c1c config: implement loading, defaults, masking, and validation
- Config::load / load_with read the TOML file; port fields accept
  either a TOML int or a string (real configs use both)
- empty strings resolve to defaults: db 3306, web 8080,
  $HOME/.config/rpn state dir, <state>/backups backup dir; an
  explicit state dir steers the backup default
- show() masks the password; validate_database() enforces
  host/user/name for commands that touch the database
- resolve_config_path() implements the documented lookup order
2026-09-08 18:49:52 +02:00
jakob a81dd6f543 config: add failing tests for load, resolution, defaults, masking
Tests define the API for the config module:
- Config::load_with(path, home) / Config::load(path) read the TOML file
  (database/web/state/backup sections per config.template.toml)
- empty strings resolve to built-in defaults: db port 3306, web port
  8080, state dir $HOME/.config/rpn, backup dir <state>/backups
  (backup follows an explicitly set state dir)
- port may be written as a TOML int or a string in real configs;
  non-numeric strings are a ConfigError
- resolve_config_path(): --config flag > $RUSTYRPN_CONFIG >
  cwd/config.toml; --env=dev|test only affects that last default slot
- Config::show() renders the effective config with the password masked
- Config::validate_database() requires host/user/name

Also adds the toml crate (forced by the TOML config decision).
2026-09-08 18:17:00 +02:00
jakob e81ef6b351 workspace: scaffold Cargo workspace with rpn-core and rpn-cli
First code in the repo. Workspace root is Application/ per readme;
members are src/core (crate rpn-core) and src/cli (binary rpnc).
Crate names are prefixed to avoid clashing with the std `core`
crate; directory names follow the readme layout.

Dependencies (versions pinned in Cargo.lock):
- core: sqlx (mysql, runtime-tokio, chrono, rust_decimal), chrono,
  csv, thiserror, serde/serde_json, tracing, plus sha2 (SHA-256
  file checksums required by schema.sql), rust_decimal (exact
  DECIMAL(10,2) money, forced by the "money is DECIMAL
  everywhere" decision), tokio and tempfile as dev deps.
- cli: clap (derive), tokio, tracing-subscriber (env-filter),
  anyhow, serde/serde_json, chrono, csv.

The extra crates beyond the readme stack (sha2, rust_decimal,
tracing-subscriber, tempfile-dev) are direct consequences of
already-committed decisions; flag for maintainer review.

No feature logic yet: rpnc is an empty shell, the domain modules
land in the TDD slices that follow.
2026-09-08 17:56:45 +02:00
jakob f3d6580f55 readme: pin MSRV to 1.85 (first edition-2024 release)
Resolves the "1.8x (TBD)" placeholder. Edition 2024 shipped in
Rust 1.85, so that is the floor for the workspace.
2026-09-08 17:41:21 +02:00
jakob d1af440966 schema: correct slim-projection count in header comment
The transactions table keeps 9 of the 16 source fields; the dropped
list also includes Card type (equals Card number in all samples, per
readme). Header said 10 and omitted Card type.
2026-09-08 14:57:29 +02:00
jakob a34898e6c1 Cosmetic: Fix indentation in cli.md 2026-09-08 12:57:52 +02:00
jakob 8e3207b139 Document v1 domain schema; clarify transaction read and import verify
Move the untracked 'schema draft.sql' to Documentation/schema.sql: the
agreed v1 fuel-domain schema (files, customers, batches, cards,
transactions, invoices, invoice_items), design decisions recorded in the
header: NULL-able cleartext card PINs, slim ledger projection (10 of 16
source fields, the files table is the canonical archive), string customer
business key, unified DECIMAL SEK money, full invoice traceability,
cli.md status values.

cli.md: transaction read takes <date> <receipt> -- the register's
receipt counter repeats across days (9,990 distinct receipts in the
138k-row sample), the day+receipt pair is the ledger dedup key, verified
unique in all samples. File import step 5 clarified as an internal
consistency check, since source files carry no totals of their own.
Invoice business key corrected to invoice number.

readme.md: point the database bullet at Documentation/schema.sql.
2026-09-02 16:38:07 +02:00
jakob 52bb11f58f readme: add receipt reissue feature to roadmap (low priority) 2026-09-02 13:07:00 +02:00
jakob 7e643f3190 readme: note CLI spec location and state/backup defaults
- In development: the CLI command structure is specified in
  Documentation/cli.md
- Config: daemon state and database backups default to ~/.config/rpn
  (backups in its backups/ subdirectory), overridable in config
2026-09-02 11:37:04 +02:00
jakob 2a0bba5be7 Add web, state, and backup sections to config template
- [web]: port and public fqdn for the daemon (Caddy proxies from a
  separate jail); port defaults to 8080
- [state]: daemon pidfile and logs directory, default ~/.config/rpn
- [backup]: timestamped dumps for rpnc db backup, default
  ~/.config/rpn/backups; rpnc db restore looks here by default
- cli.md: document the optional positional path and the directory
  defaults for db backup/restore
2026-09-02 11:37:04 +02:00
jakob 2b1cbb2500 Redesign CLI command structure after design review
Reframe the implementation notes as design decisions (no code exists
yet) and resolve the open design questions:

- card: contract fuel card only; retail rows carry no card
- customer delete also guards against invoices and cards
- invoice: outgoing fuel only; add explicit send (draft -> sent);
  --all fans out to one invoice per customer; document statuses
- VAT: amounts stored inclusive, 25% base/VAT split at invoice time
- file import: v1 = epsilon TSV only; one DB transaction per import;
  batch-total mismatch aborts with exit code 1
- file export --format raw is source-faithful; raw errors elsewhere
- batch: document derived nature; update = manual reconciliation;
  list gains --from/--to/--year filters
- daemon status is local-only (no external check); pidfile/logs under
  a configured state directory
- db: --force on reset/restore; timestamped backups in configured dir;
  status reports migration version
- add config show, --version, --config precedence, exit-code table,
  business-key ID semantics, and status values
2026-09-02 11:37:04 +02:00
jakob 6ea85df167 Import command wip structure plan
Copy a draft for command structure from a previous attempt at writing
this application.
2026-09-02 11:35:03 +02:00
jakob 0dfc720f47 Create readme.md
Create an initial guiding document for both human and AI.
2026-08-25 13:11:24 +02:00
jakob 77354d4ba8 Add config.template.toml 2026-08-25 13:11:24 +02:00
jakob 5acf79235d Update .gitignore 2026-08-25 13:11:24 +02:00
jakob b34dac23f6 Create .gitignore 2026-08-19 10:04:12 +02:00