1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# bokf — project state
Settled decisions live in `docs/DECISIONS.md`; this file is the live snapshot.
Read with `AGENTS.md` (rules) and `docs/TUI-GUIDELINES.md` (UI conventions).
## Status
Working self-hosted bookkeeping system, not production-proven. Backend ledger
core is complete; filing/year-end/payroll are not. TUI is usable and exercised
by `make test-pty` (golden screen-text scenarios); `make test` covers the
server/protocol/ledger, the TUI widget unit tests and the docs consistency
check.
## Open decisions
None open. Completed items that used to be listed here are archived in
`docs/DECISIONS.md`.
## Backlog (prioritized, from COMPLIANCE.md §10 and the audit)
1. ~~eSKD file generation~~ done: `report.vat_eskd`.
2. ~~Bokslut automation~~ done: `bokslut.post` + TUI Bokslut screen.
3. ~~K2 årsredovisning draft and SRU files~~ done: TUI draft + `sru.export`.
4. ~~`audit.verify` voucher chain~~ done (also attachments with `full:true`).
5. ~~`report.general_ledger` / `report.voucher_list`~~ done.
6. ~~`describe` argument schemas~~ done (`CMD_ARGS`).
7. ~~Pre-migration `VACUUM INTO` snapshot~~ done.
8. ~~Docker image + compose~~ done (no registry, no systemd unit).
9. Password change, user disable, TOTP.
10. ~~Bank import/reconciliation (CSV first)~~ phase 1 done (SEB CSV +
matching, schema v8). Next: phase 2 prefill-from-transaction and
`bank_rule.*`, then PSD2; invoicing/reskontra and AGI/payroll if
employees.
11a. Imported history years with source P&L closings: decided, no importer
change (see DECISIONS.md).
11. ~~SIE import only into an empty fiscal year~~ chronological multi-year
import works; each year must still target an empty fiscal year.
12. TUI polish: horizontal scrolling in long text fields, bracketed paste.
Original entries for the struck items are in `docs/DECISIONS.md`.
## Environment / how to run
- **Deployed**: `scripts/deploy.sh` (latest `v0.1.48`, healthy on nas).
Live daemon `tls:bokf.makandra.eu:8788`, token
`~/.config/bokf/migration-token` (scopes `read,write`; owner-only actions
like closing years must be done by the human in the TUI). Git remote
`origin` is `nas:/mnt/data/git-repos/bokf.git` (push `main` and tags).
- **Local test rig** (transient, `/tmp`): daemon
`./build/bokfd --db /tmp/opencode/bokf-local/t.db --socket
/tmp/opencode/bokf-local/sock`, org 1, login `admin`/`testpass123`.
Drive the TUI over a pty with `scripts/tui-sandbox.sh -- ./build/bokftui
--socket /tmp/opencode/bokf-local/sock --org 1 --fy 1 ...` plus a small
driver that feeds keys and an ANSI renderer (recreate if gone; arrows are
`ESC O B/A`, Tab `\t`, `^X` `\x18`, `^Enter` `ESC[27;5;13~`, F5
`ESC[15~`). Never test against the live daemon.
- Demo: db `~/bokf-demo/bokfd.db`, socket `~/bokf-demo/bokfd.sock`,
pid file `~/bokf-demo/bokfd.pid`; login `admin` / `demo1234`.
Start TUI: `cd ~/work/bokf && BOKFD_SOCKET=$HOME/bokf-demo/bokfd.sock \
BOKFD_USER=admin BOKFD_PASSWORD=demo1234 ./build/bokftui`
- Restart daemon: kill the pid file's process, then
`BOKFD_BACKUP_DIR=$HOME/bokf-demo/backup \
BOKFD_EXPORT_DIR=$HOME/bokf-demo/export setsid nohup \
./build/bokfd --db $HOME/bokf-demo/bokfd.db \
--socket $HOME/bokf-demo/bokfd.sock > $HOME/bokf-demo/daemon.log 2>&1 &`
- The user's own early instance was `/tmp/x.db` + `/tmp/bokfd.sock`
(schema v1, old binary) — recreate or migrate it with the current build if
it is still wanted.
- TUI smoke tests: drive over a pty with `script -qec`; function-key escape
sequences are timing-sensitive there (not an app bug). Arrows arrive as
application-mode sequences (`ESC O B` for Down), not `ESC [ B`, because
curses enables the keypad. `Ctrl+N/C/F` are single bytes and reliable.
Always wrap the run in `scripts/tui-sandbox.sh -- ./build/bokftui ...`: it
isolates `XDG_CONFIG_HOME`/`XDG_CACHE_HOME` so a test can never overwrite
the real `~/.config/bokf/tui.conf` or `~/.cache/bokf/tui.log`.
## Known caveats
- Developer tooling: the `g_cmd_<domain>[]` tables in `src/cmd_*.c` carry
declarative argument schemas (`CMD_ARGS`); `describe` emits them and the
dispatcher validates before the handler runs. `make check` (part of
`make test`) fails when a command or error code is missing from
`PROTOCOL.md` (`scripts/check-consistency.sh`) or when the generated
command catalogue is stale (`make gen-protocol`). `make test-asan`/
`test-ubsan` build `test_core` with sanitizers; `make test-pty` runs
`scripts/tui-golden.py` against a throwaway `/tmp` daemon; `make gate`
is the pre-push check (clean `-Werror` build in `build-gate/` + tests +
ASan).
- Never commit unless the human asks.
- SQLite files must not be backed up live with restic; use
`backup.snapshot` (`VACUUM INTO`) and point restic at the snapshots.
- Schema version is 9 (v3 moms rules; v4/v6 year info; v5 org
description/shares + board members; v7 attachments append-only triggers;
v8 bank reconciliation; v9 invoicing + widened `vouchers.source` with a
table rebuild); forward migrations are in `db.c`.
## Makandra driftstatus (org 2)
- **Org**: Makandra AB, org 2. Räkenskapsår (id): 2022=3, 2023=4, 2024=5,
2025=6, 2026=7, **2027=2 (öppet, aktuellt)**. Bokslut/AR/deklaration görs
för det år som är valt i sessionen.
- **FK2027**: importerade Kapitas-böcker + 28 bokförda verifikat (V21–V48)
för bank/skatt maj–sep 2026, samt V49 som makulerar en dubblett (V20).
1930 stämmer mot banken utom **CDON 2 409 kr** (väntar på kvittots del
2–4; bokförs när det kommer). 1630 = 40 721 (exakt enligt Skatteverket).
- **Underlag**: 279 attachment i org 2 (alla historikdokument + insamlade
underlag). Bank-/SKV-utdrag ligger i `~/Makandra AB/{bank,skatteverket}`
(Syncthing), källkorpus i `~/Downloads/Makandra AB-…/Bokföring/`.
- **Stängning**: 2022–2026 ska stängas av ägaren via **Räkenskapsår** i
TUI:n; låt FK2027 vara öppen till nästa bokslut.
- **Deklaration**: FK2026 är deklarerad av revisorn. FK2027 deklareras
våren 2027 (INK2/SRU via Bokslutshubben → Inkomstdeklaration).
- **Årshäftet**: fylls i Bokslutshubben (händelser, stämma, utdelning +
datum, medelantal, noter). OBS: `dividend_ore` för FK2027 kan vara ett
testvärde (10 000) — kontrollera före AR/deklaration.
- **Beslut/regler från bokföringsarbetet**: inga bokföringar utan
godkännande; låsta år förblir låsta (rättelser görs i aktuellt år); SIE-
importören ändras inte och importerad data "manipuleras" inte;
historikårens P&L nettar noll pga källsystemets stängningar (AR hoppar
över "Stäng"-verifikat i flerårsöversikten); utdelning bokförs vid stämman
med mallen **Utdelning** (D 2099/K 2898); pappersoriginal finns i fysisk
pärm (får refereras i efterhand, även i stängda år).
|