Implement Workstream J: Org procedures (backend)

Add complete organization management procedures:
- orgs.list, create, get, update, delete, leave
- orgs.members.list, updateRole, remove
- orgs.invites.list, create, cancel, accept
- orgs.sites.list

Key features:
- Role-based access control (owner > admin > member)
- Transaction-protected owner count checks to prevent race conditions
- Privilege escalation prevention (only owners can invite owners)
- Graceful constraint violation handling with friendly error messages
- Email sending for org invitations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
RevIQ
2026-01-09 16:50:29 +08:00
parent 2d445cc47b
commit 9cf95095c3
8 changed files with 765 additions and 73 deletions

View File

@@ -34,6 +34,22 @@ import {
} from "./procedures/me/sessions.js";
import { setPassword } from "./procedures/me/set-password.js";
import { updateProfile } from "./procedures/me/update-profile.js";
import {
invitesAccept,
invitesCancel,
invitesCreate,
invitesList,
membersList,
membersRemove,
membersUpdateRole,
orgsCreate,
orgsDelete,
orgsGet,
orgsLeave,
orgsList,
orgsUpdate,
sitesList,
} from "./procedures/orgs/index.js";
import {
createAuthenticationOptions as createAuthOptions,
createRegistrationOptions as createRegOptions,
@@ -176,79 +192,11 @@ const setupProfile = os.me.setupProfile
// - listSessions, revokeSession, revokeAllSessions
// - getDeviceInfo, trustDevice, listTrustedDevices, untrustDevice, revokeAllTrustedDevices
// Orgs procedures (all require auth)
const orgsList = os.orgs.list.use(authMiddleware).handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const orgsCreate = os.orgs.create.use(authMiddleware).handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const orgsGet = os.orgs.get.use(authMiddleware).handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const orgsUpdate = os.orgs.update.use(authMiddleware).handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const orgsDelete = os.orgs.delete.use(authMiddleware).handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const orgsLeave = os.orgs.leave.use(authMiddleware).handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
// Orgs members procedures
const membersList = os.orgs.members.list
.use(authMiddleware)
.handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const membersUpdateRole = os.orgs.members.updateRole
.use(authMiddleware)
.handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const membersRemove = os.orgs.members.remove
.use(authMiddleware)
.handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
// Orgs invites procedures
const invitesList = os.orgs.invites.list
.use(authMiddleware)
.handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const invitesCreate = os.orgs.invites.create
.use(authMiddleware)
.handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const invitesCancel = os.orgs.invites.cancel
.use(authMiddleware)
.handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
const invitesAccept = os.orgs.invites.accept
.use(authMiddleware)
.handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
// Orgs sites procedures
const sitesList = os.orgs.sites.list.use(authMiddleware).handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
});
// Orgs procedures - imported from ./procedures/orgs/index.js
// - orgsList, orgsCreate, orgsGet, orgsUpdate, orgsDelete, orgsLeave
// - membersList, membersUpdateRole, membersRemove
// - invitesList, invitesCreate, invitesCancel, invitesAccept
// - sitesList
// Admin orgs procedures (require superuser - for now just auth, will add superuser middleware later)
const adminOrgsList = os.admin.orgs.list