Skip to content

feat(people): add organizations and employment records - #593

Open
salmonumbrella wants to merge 1 commit into
kenn-io:mainfrom
salmonumbrella:organizations-employment-v0193-publication
Open

feat(people): add organizations and employment records#593
salmonumbrella wants to merge 1 commit into
kenn-io:mainfrom
salmonumbrella:organizations-employment-v0193-publication

Conversation

@salmonumbrella

Copy link
Copy Markdown
Contributor

What changed

  • Add first-class organizations with versioned profiles, typed custom attributes, lifecycle and merge operations, and reviewable duplicate suggestions.
  • Add current and historical employment records with primary-employment constraints and read-time person and vCard projections.
  • Keep SQLite and PostgreSQL behavior aligned, and expose the model through daemon APIs, generated clients, and organization and employment CLI commands.

Why

People can have several current or historical roles, but copied company and title fields cannot preserve that history or represent one organization consistently across people. First-class records make employment changes queryable without losing source evidence.

Usage

msgvault organization create "Example Corp" --domain example.com
msgvault employment add --person 42 --organization 7 --title "Engineer" --start 2024-01 --primary

Refs #534

@roborev-ci

roborev-ci Bot commented Aug 9, 2026

Copy link
Copy Markdown

roborev: Combined Review (538ed05)

The change is generally sound, but three medium-severity API and profile-reconciliation gaps should be addressed.

Medium

  • Missing organization attribute clear endpointinternal/api/organizations.go:281
    Organization attributes can be listed and replaced, but no route invokes SupersedeOrganizationAttributeValueContext. Clients therefore cannot clear an attribute without replacing it, and cannot remove values whose definitions are inactive. Add a DELETE/clear endpoint analogous to the person-attribute endpoint, including ordinal, expected-value, and dry-run handling, and expose it through the generated client and CLI.

  • Profile reconciliation can discard metadata changes or violate uniquenessinternal/store/organization_profile.go:455
    Reconciliation treats rows as unchanged based only on their normalized business key, silently dropping changes to writable metadata such as pref, ordinal, source fields, and vCard identity. Changing a value while preserving its vCard property identity can also insert the replacement before superseding the old row, violating the active property-identity uniqueness constraint. Compare all writable fields, explicitly match durable vCard identities, and supersede changed or removed rows before inserting replacements.

  • Organization profile request limit is too small for supported mediainternal/api/organizations.go:491
    Profile PUT uses the generic 1 MiB decoder even though inline organization media supports up to 8 MiB. Base64 payloads larger than roughly 750 KiB are rejected before reaching the store-level limit. Use a dedicated decoder sized for an 8 MiB base64 payload, similar to the person-profile decoder, and return the appropriate oversized-request response.


Reviewers: 2 done | Synthesis: codex, 16s | Total: 11m42s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant