web changelog n stuff

This commit is contained in:
Priec
2026-08-16 15:30:16 +02:00
parent 0e1dca28c7
commit 99212252b2
4 changed files with 88 additions and 11 deletions

2
client

Submodule client updated: c72f36c3fd...e3b5d57c90

67
problems.md Normal file
View File

@@ -0,0 +1,67 @@
Scripts / computed fields
- Empty sources break the client-side evaluator. Opening an empty scripted table fails the whole load (Invalid
decimal ''), and on a new entry the computed field shows "Computed value unavailable" until the source is filled.
Design question: should empty be treated as "not ready — don't evaluate yet" instead of an error? And should the
client evaluate at all, or let the server compute on save?
- Text-column scripts are broken server-side (post_table_data.rs): the script check parse_decimal_exacts both values
regardless of column type, so even a matching text value fails. The web UI happily lets you create a script on a
text column. Design question: make the comparison type-aware, or forbid scripts on non-numeric columns at
creation?
- The "Computed values changed; review and save again" loop. When the client's computed value differs from the
server's, save loops forever with 0 rows persisted. The permission cause is fixed, but the loop still exists
whenever client and server disagree (rounding, currency, multi-step scripts). Design question: should the client
just adopt the server's computed value instead of requiring a manual confirm?
Authorization / security
- Logout doesn't revoke the JWT. A logged-out token still works for 24 h. The client also has no logout UI at all
(the function exists but is dead code), and there's a user_sessions table that nothing seems to use. Design
question: server-side session revocation (deny list or the sessions table) vs. short-lived access tokens + refresh
tokens.
- HydrateScriptDependencies can leak cross-table values (mentioned last turn): access is checked on the requested
table, not on the tables a script reads. A role with access to A but not B could pull B's rows through A's script.
Design question: authorize each dependency table, or scope scripts so they can only read tables the caller can
read?
- Import validation errors come back as HTTP 502. User-data failures ("value is required", bad decimal) are client
errors masquerading as server outages. Design question: map gRPC status → HTTP status (InvalidArgument/
FailedPrecondition → 4xx, internal → 502).
Data safety / integrity
- Posted tables can never be deleted. "Deleting tables is not allowed after data has been posted"; journal FKs are
NO ACTION so even raw SQL fails. A mistaken table is permanent. Design question: is that intended protection, or
should there be an archive-then-delete flow (the "Archive first / Update anyway" guard already exists for rows)?
- SetColumnPresentation trusts id/alias pairings. A hand-crafted POST with swapped aliases silently renames columns
across each other — export, catalog, and validation all follow the wrong names. Design question: reject any alias
that is currently another column's name in the same request.
UX / correctness
- Save errors surface inconsistently. Ctrl+S shows a full-chain dialog; Home (save_and_next_entry) only sets the
status bar with the top context. And the save-failed dialog itself truncates long messages, cutting off the actual
reason. Design question: always show the full chain in a wrapping dialog.
- "Referenced data is in use" is worded as a failure. It's a guard offering Archive/Update/Cancel, but the dialog
says the update "failed" with a FailedPrecondition code. Design question: reword as a choice, not an error.
- Link fields display :id but accept bare ids. Typing what you see (:2) fails validation. Minor, but confusing.
- Client caches table structure/validation and never refreshes on save — server-side changes don't reach an open
client until the table is reopened. table_definitions has a row_revision column, so a revision check is feasible.
Design question: refresh-on-revision-change vs. "reopen to reload".
- Analytics leaks a DataFusion planner error on SELECT count(*) (zero-column projection). Internals in the UI; a
special-case fix.
- New-profile form offers USD but the server rejects it (EUR-only books). Restrict the option or support it.
Environment / tooling
- Your client config blocks startup: form_navigation.toml has row = "first_editable", which the current binary
rejects. The default template in the source writes first_editable, so either the source template and the enum
drifted, or the file came from a different build. Worth a quick look — a fresh user could hit this.

2
server

Submodule server updated: 6e653d53a3...412af6ea3f

View File

@@ -90,6 +90,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- **`AuthService.Register` — the `role` field is gone** — the request no - **`AuthService.Register` — the `role` field is gone** — the request no
longer carries a client-chosen role; every registration lands as `guest`. longer carries a client-chosen role; every registration lands as `guest`.
The register page dropped the role input and its suggestion list. The register page dropped the role input and its suggestion list.
- **`EcbService.GetEcbPipelineStatus`** — a new `/admin/ecb` page (with a
polling `/admin/ecb/status` card) renders the recent ECB import batches and
their state. The page is gated on the caller's `ecb:*` read permission, and
the backend stays the authority: a caller who slips past the page check gets
`PermissionDenied` from the RPC.
- **`TableDefinition.GetTableCatalog`** — the form catalog now feeds the
add-table, table-definition, import/export and admin loaders, replacing
locally assembled table lists. Global tables appear in the catalog and are
selectable as link targets from any profile; a global table may only link to
other global tables.
- **Link columns are declarable** — the add-table page picks a link target
table from the profile's offered targets and writes `link(table)` for the
column type. A link is never indexed by the form: the server indexes it, and
the draft refuses a tampered `indexed` flag for one.
- **Columns can be made required** — add-table gained a required toggle that
travels with the column into `PostTableDefinition`.
- **`TablesData.GetTableDataCount`** — the CSV export asks for the row count
before downloading, so the export loop knows how many
`GetTableDataByPosition` pages to read.
### Not covered ### Not covered
@@ -97,15 +116,6 @@ The endpoints and fields below are part of the current proto surface but the
web crate does not implement them. They are listed so it stays visible what web crate does not implement them. They are listed so it stays visible what
the backend gained that this client has not wired up yet. the backend gained that this client has not wired up yet.
- **`TableDefinition.PostTableDefinition``LINK(table)` columns** — the old
per-request link UI was removed when links became columns, and the new
spelling is not implemented. The picker offers `link` (the `ListColumnTypes`
response marks it declarable), but `COLUMN_TYPE_SPELLING_LINK` is not treated
as parameterised, `relation_tables` is loaded but never rendered or applied,
and typing `link(table)` is rejected as an unknown type. A link column
cannot be declared from the web.
- **`TableDefinition.ColumnDefinition.required`** — the new field is always
sent as `false`; add-table has no required toggle.
- **`TableValidation.DisplayMask.storage_mode`** — the new `MaskStorageMode` - **`TableValidation.DisplayMask.storage_mode`** — the new `MaskStorageMode`
option is always left absent (raw); there is no formatted-storage choice in option is always left absent (raw); there is no formatted-storage choice in
the validation UI. the validation UI.