Files
komp_ac/web/CHANGELOG.md
2026-08-16 15:30:16 +02:00

13 KiB

Changelog

All notable changes to the komp_ac web crate — the Axum SSR/HTMX web frontend for the komp_ac gRPC backend — are documented in this file.

This changelog tracks only the gRPC endpoints the web crate consumes (the browser never calls gRPC directly; Axum proxies to the backend through these clients) and the extent to which each is used by the pages that mount them. Other, non-API changes are intentionally out of scope.

The format is based on Keep a Changelog.


[Unreleased]

Added

  • Role, user and permission administration/permissions consumes ListRoles, AddRole, RemoveRole, ListUsers, AssignUserRole, ListRolePermissions, ListGrantableObjects, GrantPermission and RevokePermission. Direct and inherited grants are distinguished, and the action controls come from each grantable object returned by the backend.
  • Table-family permissions in table definition — selecting a table shows its grant matrix for every editable data role. Creating a table redirects to that table in the definition workspace so its initial grants can be assigned immediately.
  • Password management/password consumes ChangePassword for the signed-in user, while the user table consumes ResetUserPassword for administrator resets allowed by the backend role hierarchy.
  • TableDefinition.ListColumnTypes — called by the add-table and table-definition loaders. The whole response is consumed: name, group, declarable, compound, spelling, requires_currency, creation_only, allows_quantity_ledger and sql_type are each read by a rule that used to be hardcoded in crate::schema. The column vocabulary is now the backend's, so a type it adds is offered by both screens without a change here.

Changed

  • Permissions moved out of the admin panel into their own nav section, split in three/admin/permissions is gone; the pages are /permissions/roles (which roles exist), /permissions/users (who holds them) and /permissions/grants (what a role may do). No new gRPC endpoint is consumed: the same GrantPermission and RevokePermission calls now come from one POST /permissions/grants/apply, which issues one call per object|action pair so a shortcut — a whole row, a whole profile, everything — is a longer list rather than a different request. Shortcuts grant the wildcard objects ListGrantableObjects already returns (data:*, data:<profile>/*, journal:*, ecb:*), so they keep covering profiles and tables created later, and AddRole may be followed by a starter set of those grants in the same submission. Revoking tolerates the NOT_FOUND a pair the role does not hold directly answers with, which is what makes "remove all of this" idempotent.
  • Web authorization follows permission objects, not role names — structural pages check their struct:<area>/manage permission from GetAuthorization, so inherited superadmin authorization works and data roles are no longer treated as administrators. Login redirects structural users to the admin workspace and data users to analytics.
  • Analytics and import/export use the caller's visible data — profile-tree discovery is authenticated, export is limited to readable tables, and import is limited to tables for which the snapshot carries insert.
  • Permission mutations keep the browser session — grants, role changes and assignments now reload the live authorization state without replacing the identity-only JWT. The permissions workspace reloads in place and shows the updated effective policy.
  • The column-type picker is the server's list — it no longer carries its own. Types the web crate never offered are now reachable: numeric and the ACCOUNTING_TRANSFER compound column. Server-generated companion types (phone_country, iban_bban, the transfer connectors) are listed by the endpoint but never offered, and are refused if one is posted anyway.
  • Creation-only types are refused on the append panel by rule, not by namePOST /admin/table-definition/columns used to exclude accounting alone; it now excludes every type the response marks creation_only, which is what AddTableColumns rejects.
  • Compound columns are staged as the backend expands them — a compound column takes its type's name, cannot be indexed, and is not offered as a row display column, since no column of that name survives the expansion.
  • Currency and quantity-ledger rules come from the responserequires_currency decides which types carry a currency (previously MONEY and ACCOUNTING by name), and allows_quantity_ledger both validates the choice and writes the hint under the input.
  • GetProfileDetails columns show the SQL type behind them — the workspace's column list renders sql_type from the catalog beside each logical type, including for the companion columns the backend generates.
  • TableDefinition.GetProfileTreedepends_on is one entry per link — each dependency now carries the target table_name and the column_name holding the reference. Both the admin panel and the table-definition workspace render each entry as table (column), so a table that points at one target twice shows as two links.
  • AuthService.Register — the role field is gone — the request no longer carries a client-chosen role; every registration lands as guest. 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

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 the backend gained that this client has not wired up yet.

  • TableValidation.DisplayMask.storage_mode — the new MaskStorageMode option is always left absent (raw); there is no formatted-storage choice in the validation UI.
  • TableScript.ScriptDependency.link_column / name_in_script — the new dependency fields are not read; the web only surfaces the id and warnings PostTableScript returns.
  • TablesData account as a string — accounting-enabled tables now take a slash-delimited account path instead of the account_id reference, and the structure endpoint exposes the column as account. The bulk-import and CSV-export paths treat columns generically and were not changed; the web has no accounting data-entry surface of its own.

[v0.8.38] — 2026-08-05

The web crate wires up seven gRPC services and calls the following endpoints. Coverage notes describe which pages exercise each call and how deeply its response is consumed.

Auth (AuthServiceClient)

  • AuthService.Login — called by POST /login. Exchanges identifier and password for an access token; the token and expires_in are written into the analytics_token HTTP-only cookie that every subsequent gRPC call is signed with. Fully covered end-to-end.
  • AuthService.Register — called by POST /register. Submits the full RegisterRequest surface (username, email, password, password_confirmation, role, timezone, phone_country). Only the success/error message is shown; it does not create a session.
  • AuthService.GetAuthorization — called by every admin page loader (/admin, table-definition, add-table, add-logic, add-validation, import/export). Returns the caller's role; the web crate uses it for two things: gating the admin panel to role == "admin" and rendering the navbar with the current role. Response fields beyond role are not used.

Table definition (TableDefinitionClient)

  • TableDefinition.GetProfileTree — called by the analytics, admin, table definition, add-table, add-logic, and add-validation loaders. Populates the profile selectors (profile name + table count) and, in the admin panel, the per-profile table list including depends_on and row_display_columns. Response is consumed fairly deeply.
  • TableDefinition.PostTableDefinition — called by POST /admin/tables (add-table page). Creates a table from the draft; the returned success, sql, and message are surfaced. Full form → endpoint mapping.
  • TableDefinition.GetProfileDetails — called by the table-definition workspace loader. Returns per-table columns (name, type, currency, quantity-ledger, rounding, generated/read-only behaviors and generated_from for Steel scripts), scripts (target column/type/description/source), row display columns, and table kind. The most deeply consumed definition endpoint.
  • TableDefinition.GetColumnAliasRenameHistory — called by the table-definition workspace loader. Returns rename history entries (table, old/new column names, timestamp); only those four fields are rendered.
  • TableDefinition.AddTableColumns — called by POST /admin/table-definition/columns. Adds columns to an existing table.
  • TableDefinition.SetColumnPresentation — called by POST /admin/tables/presentation. Atomically changes column aliases and order.
  • TableDefinition.DeleteTable — called by POST /admin/table-definition/delete. Deletes a table definition.
  • TableDefinition.CopyProfile — called by POST /admin/table-definition/copy. Copies a profile.
  • TableDefinition.CreateInvoiceTemplateTable — called by POST /admin/table-definition/invoice-template. Creates a table from the invoice template contract.

Table script (TableScriptClient)

  • TableScript.PostTableScript — called by POST /admin/logic (add-logic page). Creates a Steel table script; the returned id and warnings are surfaced to the user.

Table validation (TableValidationServiceClient)

  • TableValidationService.UpdateFieldValidation — called by POST /admin/validation. Creates/updates a field validation.
  • TableValidationService.UpsertValidationRule — called by POST /admin/validation/rules. Creates/updates a reusable validation rule.
  • TableValidationService.ApplyValidationSet — called by POST /admin/validation/sets. Applies a validation set.
  • TableValidationService.UpsertValidationSet — called by POST /admin/validation/sets. Creates/updates a reusable validation set.

Each validation POST maps the submitted form into the corresponding request and renders only the returned success/message.

Table structure (TableStructureServiceClient)

  • TableStructureService.GetTableStructure — called by the admin panel, CSV import, and CSV export. Returns table structures used three ways: the admin column browse (name, type, nullable, primary key, quantity-ledger), import header validation, and export column ordering. Only the structure for the selected/imported/exported tables is requested at a time.

Tables data (TablesDataClient)

  • TablesData.PostTableDataBulk — called by POST /admin/import. Chunked bulk insert of parsed CSV rows into a table, with per-chunk requests.
  • TablesData.GetTableDataByPosition — called by POST /admin/export.csv. Reads table rows by position for CSV download, one request per table.

Analytics (AnalyticsServiceClient)

  • AnalyticsService.GetAnalyticsCatalog — called by POST /api/catalog. Returns the live public analytics catalog for a profile (tables, columns, types, links); rendered in the sidebar and used to generate starter queries and LLM schema context.
  • AnalyticsService.ExecuteAnalyticsQuery — called by POST /api/query. Runs a read-only analytics SQL query; the result columns/rows feed the ECharts charts and table view.
  • The analytics profile selector is fed by TableDefinition.GetProfileTree (see above), not by a dedicated analytics profile endpoint.