Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 79x 362x 473x 171x 112x | // DAL capability map: role model core (purses-89g).
// ownerId is the SOLE owner source; membership.role is a display label only.
export type Role = "owner" | "curator";
export type Operation =
| "collection:read"
| "collection:manage"
| "collection:purge"
| "collection:audit"
| "members:read"
| "members:manage"
| "invitations:read"
| "invitations:manage"
| "items:read"
| "items:write"
| "items:purge"
| "photos:write"
| "sessions:write"
| "preferences:write";
// Compile-exhaustive map: every Operation has a minimum required Role.
// owner satisfies all operations; curator satisfies only curator-level ones.
export const CAPABILITIES: Record<Operation, Role> = {
"collection:read": "curator",
"members:read": "curator",
"items:read": "curator",
"items:write": "curator",
"photos:write": "curator",
"sessions:write": "curator",
"preferences:write": "curator",
"invitations:read": "owner",
"collection:manage": "owner",
"collection:purge": "owner",
"collection:audit": "owner",
"members:manage": "owner",
"invitations:manage": "owner",
"items:purge": "owner",
};
// owner satisfies every role (including owner); curator satisfies curator only.
export function roleSatisfies(effective: Role, required: Role): boolean {
return effective === "owner" || effective === required;
}
// Resolve the caller's effective role for a collection.
// collection.ownerId is canonical and sole — membership.role is never read here.
// Returns "owner" if the caller is the collection owner, "curator" if they have
// a membership row, null if they are not a member at all.
export function resolveEffectiveRole(
collection: { ownerId: string },
membership: { id: string } | null,
userId: string,
): Role | null {
if (collection.ownerId === userId) return "owner";
if (membership) return "curator";
return null;
}
|