Goal
Make BaseOrg the sole persistence source for organization reads and writes while preserving legacy /api/org behavior through conversion utilities.
Normal application flows must no longer query, create, update, or delete records in the legacy Org collection.
Background
BaseOrgRepository currently has legacy-format options, but those options still read from and write to the old Org collection.
This creates dual-write complexity in organization creation, updates, full updates, and deletion. It also makes the old collection an active dependency rather than simply a deprecated representation.
Proposed approach
Do not create another repository.
Create a small, pure compatibility utility:
src/utils/orgCompatibility.js
It should contain focused conversion functions:
toLegacyOrg(baseOrg)
toBaseOrgInput(legacyOrg)
toBaseOrgUpdate(legacyParameters)
The utility should map these fields:
| BaseOrg field |
Legacy Org field |
long_name |
name |
authority |
authority.active_roles |
id_quota |
policies.id_quota |
created |
time.created |
last_updated |
time.modified |
Do not convert, map, or migrate legacy inUse to BaseOrg in_use. They are distinct fields with potentially different semantics.
Refactor BaseOrgRepository so it always queries and writes BaseOrg.
Legacy-format options must control only input/output conversion:
- Convert legacy input to BaseOrg input before persistence.
- Convert BaseOrg results to legacy format immediately before returning a legacy response.
- Never query or write the
Org collection because a caller requested legacy format.
Required work
- Add unit-tested conversion utilities for BaseOrg-to-legacy and legacy-to-BaseOrg transformations.
- Refactor
BaseOrgRepository to remove dependencies on OrgRepository.
- Update these methods to persist only BaseOrg data:
createOrg
updateOrg
updateOrgFull
deleteOrg
- legacy-format lookup and list methods
- Remove dual-write and dual-read logic from those methods.
- Preserve current BaseOrg responsibilities:
- discriminator and authority changes
- review-object processing
- audit history
- alias collision checks
- organization hierarchy
- user/admin membership
- transaction and session propagation
- Update direct
getOrgRepository() consumers to use getBaseOrgRepository() and BaseOrg field names:
- CVE controller
- CVE-ID controller
- middleware
- Investigate and explicitly decide how the legacy CVE-ID reservation lock will work after removal of the legacy Org collection.
- Preserve atomic reservation-lock semantics using a dedicated BaseOrg-safe lock field or mechanism, only after confirming the intended data model.
- Remove runtime production dependencies on:
src/model/org.js
src/repositories/orgRepository.js
Simplification target
After this work, each write should have one persistence path:
const baseOrgInput = isLegacyObject
? toBaseOrgInput(incomingOrg)
: incomingOrg
const savedOrg = await saveBaseOrg(baseOrgInput, options)
return isLegacyObject
? toLegacyOrg(savedOrg.toObject())
: toRegistryResponse(savedOrg.toObject())
The conversion utility is an API compatibility boundary only. It must not synchronize or persist a second organization representation.
Data migration and rollout
- Verify every legacy Org record has a matching BaseOrg record by UUID and short name.
- Produce a mismatch report for missing records, duplicate UUIDs, roles, quotas, and mapped fields.
- Resolve mismatches before enabling BaseOrg-only reads.
- Add temporary telemetry or assertions proving normal request traffic no longer reads or writes
Org.
Acceptance criteria
- All
/api/org reads, creates, updates, and deletes use BaseOrg only.
- Legacy API responses retain:
name
authority.active_roles
policies.id_quota
time.created
time.modified
- Registry API responses and schemas remain unchanged.
- Organization creation, update, full update, and deletion no longer write to
Org.
- CVE and CVE-ID authorization, quota calculation, reassignment, and reservation locking work with BaseOrg-only data.
- Reservation locking remains atomic and has an explicitly approved BaseOrg-compatible implementation.
- Integration tests cover:
- legacy
/api/org CRUD with only BaseOrg seeded
- legacy response field conversion
- CVE-ID reservation locking
- role-based authorization
- no Org collection mutation during legacy-route operations
- Existing integration suite passes.
Goal
Make
BaseOrgthe sole persistence source for organization reads and writes while preserving legacy/api/orgbehavior through conversion utilities.Normal application flows must no longer query, create, update, or delete records in the legacy
Orgcollection.Background
BaseOrgRepositorycurrently has legacy-format options, but those options still read from and write to the oldOrgcollection.This creates dual-write complexity in organization creation, updates, full updates, and deletion. It also makes the old collection an active dependency rather than simply a deprecated representation.
Proposed approach
Do not create another repository.
Create a small, pure compatibility utility:
src/utils/orgCompatibility.jsIt should contain focused conversion functions:
toLegacyOrg(baseOrg)toBaseOrgInput(legacyOrg)toBaseOrgUpdate(legacyParameters)The utility should map these fields:
long_namenameauthorityauthority.active_rolesid_quotapolicies.id_quotacreatedtime.createdlast_updatedtime.modifiedDo not convert, map, or migrate legacy
inUseto BaseOrgin_use. They are distinct fields with potentially different semantics.Refactor
BaseOrgRepositoryso it always queries and writesBaseOrg.Legacy-format options must control only input/output conversion:
Orgcollection because a caller requested legacy format.Required work
BaseOrgRepositoryto remove dependencies onOrgRepository.createOrgupdateOrgupdateOrgFulldeleteOrggetOrgRepository()consumers to usegetBaseOrgRepository()and BaseOrg field names:src/model/org.jssrc/repositories/orgRepository.jsSimplification target
After this work, each write should have one persistence path:
The conversion utility is an API compatibility boundary only. It must not synchronize or persist a second organization representation.
Data migration and rollout
Org.Acceptance criteria
/api/orgreads, creates, updates, and deletes use BaseOrg only.nameauthority.active_rolespolicies.id_quotatime.createdtime.modifiedOrg./api/orgCRUD with only BaseOrg seeded