Task: Let a member set and clear their default party

Table of Contents

This page documents a task in the Implement the membership journeys in ores.web story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

A member can set the party quick sign-in uses, and can clear it, from the browser.

2. Status

Field Value
State DONE
Parent story Implement the membership journeys in ores.web
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-09

3. Acceptance

  • iam.v1.ops.set_my_default_party still stores a party the member works in, and refuses one they do not.
  • An empty party_id clears the stored default, and clearing a default that is not set succeeds without writing.
  • The browser reaches the write over POST /api/me/default-party, parsed at the boundary.
  • The C++ tests cover storing, clearing and clearing twice; the BFF tests cover storing, clearing, the refusal and a caller with no session.
  • check_component_drift.py --component iam reports no drift, clang-format is clean, and the three TypeScript packages typecheck.

4. Plan

  1. Make clearing expressible: an empty party_id is unambiguous, because a party id is a UUID. Record the rule on the message.
  2. Take an optional party in the service, so "no default" is a value it can store, and make it idempotent for a default that is already clear.
  3. Skip the membership check on a clear, because clearing names no party, and leave the check in place for a set.
  4. Wire the browser path: the wire seam, the BFF route and the web client.
  5. Test the service at the database and the route end to end.

5. Measurements

What Value Command Commit
IAM core suite after this change see * Result bash build/evidence/run_case.sh ores.iam.core.tests (branch tip)
BFF membership cases 6 npm test --workspace @ores/bff -- membership (branch tip)

6. Notes

  • Clearing needed no new subject. The journey's candidate was a nullable body or a clear-default-party subject. The request already carries a string party id, and a party id is a UUID, so an empty string is unambiguous and the smallest change that makes "no default" expressible. The prototype drew Clear default as unavailable; after this it is a real control.
  • The membership check stays where it is. It is the guard that stops a member storing a party they cannot act for, and it is the reason the screen may offer only the account's own parties. A clear skips it because it names no party.
  • Changing the service signature did not move its callers. The parameter is now std::optional<boost::uuids::uuid>; the existing tests and the handler pass a plain uuid, which converts.

7. Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
     

8. PRs

PR Title
#2981 [iam] Let a member clear the default party

9. Review

Comment summary File Decision Notes
       

10. Result

Done 2026-10-09.

A member can set the party quick sign-in uses and clear it again, from the browser:

Layer What landed
Message set_my_default_party_request states that an empty party_id clears the default.
Service set_my_default_party takes an optional party, so "no default" is a value it can store, and clearing an unset default succeeds without a write.
Handler A clear skips the membership check, because it names no party; a set keeps it, so a member cannot store a party they cannot act for.
Browser setMyDefaultParty in the wire seam, POST /api/me/default-party, and api.setMyDefaultParty().
Tests One C++ case for the clear and its idempotence, three BFF cases for the write, the clear and the refusal.

Verification. The IAM core suite passes, 260 cases and 796 assertions. The BFF membership tests pass, 6 cases. check_component_drift.py --component iam reports no drift, clang-format over the changed C++ is clean, and the three TypeScript packages typecheck.

The database was recreated for this build: main had moved with a SQL change (the pgtap hotfix), so the recorded schema fingerprint no longer matched. That is an environment condition and not this change.

Emacs 29.3 (Org mode 9.6.15)