Story: Server-side UUID generation for all entities

Table of Contents

This page documents a story in Product backlog — inbox, carried unfinished from Sprint 24 at close. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

Goal

Clients must never generate primary-key UUIDs. Today, every entity with a UUID primary key (Book, Portfolio, the CRM entities, and many more) has an Add dialog that calls boost::uuids::random_generator()() client-side in setCreateMode() (part of the shared ores.cpp.qt.detail_dialog_impl.org codegen template) and submits that id in the create request. This is a trust/integrity smell – key assignment is a server responsibility – and surfaced concretely while investigating why a CRM entity's id field was editable in the UI (see the cross-rates matrix task).

Move id assignment to the server: the create request either omits the id or the server ignores/overwrites whatever the client sent, the server generates the real UUID during the save, and returns the created entity (with its real id) in the response. The client shows a nil UUID (00000000-0000-0000-0000-000000000000) as a placeholder while in create mode, never a client-chosen value, and never allows editing it.

Scoped to primary-key UUIDs only – other client-generated UUIDs (e.g. request correlation ids) are unaffected and out of scope.

Status

Field Value
State BACKLOG
Carried from Sprint 24 (unfinished at close)
Now Not yet started.
Waiting on Nothing.
Next Break the story into tasks.
Last touched 2026-07-21

Acceptance

  • The shared Qt detail-dialog codegen template (ores.cpp.qt.detail_dialog_impl.org) no longer calls boost::uuids::random_generator()() in setCreateMode() for any UUID-primary-keyed entity – the id field shows a nil UUID placeholder and stays read-only in create mode (never user-editable, matching the fix already landed for the CRM entities this session).
  • Every UUID-primary-keyed entity's save/create path is audited: the server-side create handler generates the id (or a shared repository helper does, consistently across entities) rather than trusting whatever the client sent – a malicious or buggy client submitting a client-chosen id must not be able to make it stick.
  • The save response includes the server-assigned id, and the client updates its in-memory copy from that response so the newly created row is immediately usable (e.g. selectable in a dynamic combo) without a manual reload.
  • This is a codegen template + repository/service change applied once and regenerated everywhere, not N hand-patches across entities.
  • Explicitly out of scope: non-primary-key UUIDs (correlation ids, etc.) – those remain client-generated.

Tasks

Task State Start End Description
         

Decisions

Out of scope

Emacs 29.3 (Org mode 9.6.15)