Conversation
BREAKING CHANGE: remove auto incremental ids from user, group and permissions and add a virtual uid property that returns string value of documents object id
Execution.spec.ts, processProgram.spec.ts and code.spec.ts didn't exist when issue-361 (ID -> UID) branched, so they were written against the old userId: number shape. Update them to match the merged-in string-based uid now that main has been merged in.
POST /SASLogon/login and GET /SASjsApi/session still returned the old `id` field, while the rest of the ID->UID migration (#363) standardized on `uid`. Not functionally broken - Mongoose provides a built-in `id` virtual by default (_id.toHexString()) that happened to resolve to the same value as the new `uid` virtual - but it's an inconsistent public API surface, and relying on that coincidence wasn't the intent of the migration. Neither of these files was touched by any of issue-361's own commits, so this predates the merge rather than being caused by it. - web.ts: login response and session storage now source from user.uid explicitly - session.ts: SessionResponse dropped its Omit<UserResponse, 'uid'> + id override in favor of just extending UserResponse - verifyTokenInDB.ts: token-refresh path, same fix - login.tsx / appContext.tsx: updated to read the corrected field Verified with a real end-to-end request (genuine app boot, real MongoDB, real CSRF handshake) - not just type-checking - to confirm the actual HTTP response bodies carry uid, not id.
There was a problem hiding this comment.
Hermes Agent Code Review
Verdict: Request Changes
This PR replaces numeric auto-increment IDs with MongoDB _id-based UIDs (24-char hex strings) across the entire server codebase. The core approach is sound, but there are several critical issues that need to be addressed before merging.
Critical
-
permission.tsline 341 —select: 'groupId name description'not updated to'uid name description': InupdatePermission, the group populate select still saysgroupIdwhile every other select in the PR was changed touid. The response will have a missing/nulluidfor the group object on PATCH permission. Should be.populate({ path: 'group', select: 'uid name description' }). -
desktop.tsline 6 — regex/^\/SASjsApi\/user\/[0-9]*$/only matches numeric IDs: UIDs are now 24-char hex strings. In desktop mode, GET/PATCH to/SASjsApi/user/{uid}will be blocked bydesktopRestrict, breaking desktop user profile access entirely. This line wasn't modified in the PR but is now broken by the ID→UID change. Update to/^\/SASjsApi\/user\/[0-9a-fA-F]{24}$/. -
seedDB.ts—ALL_USERS_GROUPname changed from'AllUsers'to'all-users'without migration: Existing deployments will get a duplicate group — new users join'all-users'while existing users remain in'AllUsers'. Permissions referencing the old group name are orphaned. The comment on line 27 still says'AllUsers'. Either add a migration to rename the existing group, or keep the original name. -
Merge regression reverting PR #388: The
issue-361branch was based on a commit before the #388 fix (return 200 with log on SAS session failure). The merge into main reverted the fix —processProgram.tsnow throws onSessionState.failedinstead of resolving,Execution.tswraps it inSessionExecutionErrorproducing a 400, and tests were reverted to expect the old throwing behavior.
Warnings
- swagger.yaml
SessionResponsestill usesidnotuid— Code returnsuidbut committed swagger showsid. Same for/SASLogon/loginuser object. - Inconsistent param naming in
UserController—getUseruses@Path() uidbutupdateUser/deleteUseruse@Path() userIdwith stale@example userId 1234. - Missing
uidValidationonPOST /:groupUid/:userUidandDELETE /:groupUid/:userUidroutes ingroup.ts. group.ts@example userId "12ByteString"should be@example userUidfor theaddUserToGroupmethod.
Looks Good
- Core approach of using MongoDB
_idasuidvirtual is sound - Clean removal of
Countermodel andgetSequenceNextValue - Good
uidValidationwith Joi (24-char hex) security addition - Frontend changes are consistent and complete
- Test files properly updated throughout
Reviewed by Hermes Agent (GitHub App)
| .populate({ | ||
| path: 'group', | ||
| select: 'groupId name description -_id' | ||
| select: 'groupId name description' |
There was a problem hiding this comment.
Critical: The group populate select here still says 'groupId name description', but every other select in this PR was changed to 'uid name description'. On a PATCH /SASjsApi/permission response, the group object will have a missing/null uid field. Should be:
.populate({ path: 'group', select: 'uid name description' })Reviewed by Hermes Agent (GitHub App)
|
|
||
| export const ALL_USERS_GROUP = { | ||
| name: 'AllUsers', | ||
| name: 'all-users', |
There was a problem hiding this comment.
Critical: The ALL_USERS_GROUP name was changed from 'AllUsers' to 'all-users' without a migration. Existing deployments will get a duplicate group — new users join 'all-users' while existing users remain in 'AllUsers'. Permissions referencing the old group name are orphaned.
Also, the comment on line 27 still says 'AllUsers'.
Either add a migration to rename the existing group, or keep the original name.
Reviewed by Hermes Agent (GitHub App)
BREAKING CHANGE: remove auto incremental ids from user, group and permissions and add a virtual uid property that returns string value of documents object id
Issue
Closes #361.
While addressing #359, the auto-incrementing sequence counter used for
User,Group, andPermissionIDs was found to be broken on Cosmos DB(it set every ID to
1). More generally, sequencing via a shared counterdocument is not a good fit: it's a bottleneck on every
insert and a source of race conditions under concurrent writes.
Intent
Replace auto-incremental numeric IDs with a string
uidacrossUser,Group, andPermission, and make the API consistently exposeuidinstead of
idwherever these entities appear in a response.Implementation
uidproperty to theUser,Group, andPermissionMongoose models, returning
this._id.toString(). No new field is storedand no data migration is required — every document already has
_id,old and new alike.
Countermodel andgetSequenceNextValueutility are gone, along with the bottleneck/racecondition they caused.
identifier — including login (
POST /SASLogon/login), session(
GET /SASjsApi/session), and theuser/group/permissionendpoints— to consistently return
uid.restoration on page load) to read
uidinstead ofid.This is a breaking change for any existing client relying on numeric
IDs from this API — endpoints now return an opaque string identifier
instead.
Checks
npm run lint:fix).npm test).