8000 Move collection linking into a transactional operation with typed refusals · Issue #542 · jra3/mulm · GitHub
[go: up one dir, main page]

Skip to content

Move collection linking into a transactional operation with typed refusals #542

Closed

Description

@jra3

Problem

src/routes/collection.ts owns the collection-link operation: ownership checks, already-linked checks, catalogue lookup, duplicate detection, and the SQL update. These rules are coupled to Express and the read/check/write sequence is not one transaction. Collection and CARES routes also distinguish business refusals by matching error-message text, so changing wording can change HTTP behavior.

Proposed change

  1. Add a collection operation accepting entry id, acting member id, and target Species id. Inside a queued transaction, read current ownership/link state, check current duplicates, and update the row. Reads participating in that decision must use the transaction connection rather than the global read-only connection.
  2. Continue using the catalogue's interface to resolve Species; do not copy its table SQL into the route or collection module. Reject stale/missing Species without leaving a partially linked entry.
  3. Define typed collection refusal codes such as missing, forbidden, already-linked, and duplicate; map them to the existing route response contract. Extend the same approach to the touched CARES operations without forcing both domains into a universal error hierarchy.
  4. Keep HTTP parsing, status/HTMX headers, and rendering in adapters. Reuse the existing message partial for touched responses rather than constructing repeated HTML strings with interpolated error text.
  5. Review add/re-add/link writers together for the current-entry duplicate invariant. Queuing only link while another competing writer bypasses the queue does not establish atomicity. If a new unique index is needed, first audit existing duplicates and propose an explicit data-preserving migration; do not silently delete them.

Acceptance criteria and tests

  • The linking rules are callable/testable without Express and the route contains no direct link SQL.
  • Missing entry/Species, non-owner, already-linked entry, duplicate current entry, and success have explicit tests and stable refusal codes.
  • Concurrent attempts cannot create two current entries for the same member/Species through the affected writers.
  • Failure leaves names, link, notes, photos, and CARES registration unchanged. Success preserves existing linking semantics.
  • Real route tests assert status/HTMX response behavior and escaped error output.
  • Existing collection and CARES visibility/registration tests, typecheck, and lint pass.

Related and boundaries

Coordinate with #468, which already owns the collection PATCH regression test and double-read cleanup; this ticket primarily owns linking and shared refusal handling. Preserve the #454/#465 rule: ordinary note edits do not unlink a Species and a CARES registration belongs to the member/Species, not the collection entry. Upload compensation is a separate ticket. No generic repository framework is needed.

Review baseline

Source review at 78e0f1b2ff157e289c237d533f1406302d95118e. Repository typechecking and the focused specialty-award/level-progress tests passed during the review; these are not reproductions of the new failure scenarios above. Full database and E2E suites were not run.

Related proposals from this review

Activity

  1. added
    enhancementNew feature or request
    databaseDatabase schema, migrations, and data integrity
    testingTesting, test coverage, and quality assurance
    priority:mediumMedium priority - important but not urgent
    ready-for-agentFully specified, ready for an AFK agent
    on Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    databaseDatabase schema, migrations, and data integrityenhancementNew feature or requestpriority:mediumMedium priority - important but not urgentready-for-agentFully specified, ready for an AFK agenttestingTesting, test coverage, and quality assurance

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0