@company-semantics/contracts 44.4.0 → 44.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -98,6 +98,37 @@ describe("resource-keys: system-scoped internalAdmin* types", () => {
|
|
|
98
98
|
});
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
+
describe("resource-keys: userMd (user-scoped singleton)", () => {
|
|
102
|
+
const USER_ID = "55555555-5555-4555-8555-555555555555";
|
|
103
|
+
const key: ResourceKey = { type: "userMd", userId: USER_ID };
|
|
104
|
+
|
|
105
|
+
it("toQueryKey produces [type, userId] with no doc identity", () => {
|
|
106
|
+
const qk = toQueryKey(key);
|
|
107
|
+
expect(qk).toEqual(["userMd", USER_ID]);
|
|
108
|
+
// A per-user singleton: the user IS the identity, so there is no third
|
|
109
|
+
// segment even though the payload is a work item (ADR-BE-487).
|
|
110
|
+
expect(qk).toHaveLength(2);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("roundtrips through fromQueryKey", () => {
|
|
114
|
+
const parsed = fromQueryKey(toQueryKey(key));
|
|
115
|
+
expect(parsed).toEqual(key);
|
|
116
|
+
expect("orgId" in parsed).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("matchesResourceKey is user-scoped: rejects another user's doc", () => {
|
|
120
|
+
const otherUser = "66666666-6666-4666-8666-666666666666";
|
|
121
|
+
expect(matchesResourceKey(toQueryKey(key), key)).toBe(true);
|
|
122
|
+
expect(matchesResourceKey(["userMd", otherUser], key)).toBe(false);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("does not collide with the other user-scoped keys", () => {
|
|
126
|
+
const viewerKey: ResourceKey = { type: "viewer", userId: USER_ID };
|
|
127
|
+
expect(matchesResourceKey(toQueryKey(viewerKey), key)).toBe(false);
|
|
128
|
+
expect(matchesResourceKey(toQueryKey(key), viewerKey)).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
101
132
|
describe("resource-keys: companyMdAccessRequests (per-doc identity)", () => {
|
|
102
133
|
const DOC_ID = "22222222-2222-4222-8222-222222222222";
|
|
103
134
|
const key: ResourceKey = {
|
package/src/resource-keys.ts
CHANGED
|
@@ -84,6 +84,12 @@ export type ResourceKey =
|
|
|
84
84
|
| { type: "dismissedBanners"; userId: string }
|
|
85
85
|
| { type: "userOrgs"; userId: string }
|
|
86
86
|
| { type: "sessions"; userId: string }
|
|
87
|
+
// The viewer's personal doc (`/api/me/md`) — a per-user singleton, so it is
|
|
88
|
+
// keyed by userId alone with no doc identity segment. Its PAYLOAD is a work
|
|
89
|
+
// item, lazily materialized on first read (ADR-BE-487), but the resource is
|
|
90
|
+
// "this user's personal doc", not "work item <id>": a future generic
|
|
91
|
+
// `workItem` key would be a different resource with a different identity.
|
|
92
|
+
| { type: "userMd"; userId: string }
|
|
87
93
|
| { type: "viewer"; userId: string };
|
|
88
94
|
|
|
89
95
|
/**
|
|
@@ -131,6 +137,7 @@ const USER_SCOPED_TYPES = [
|
|
|
131
137
|
"dismissedBanners",
|
|
132
138
|
"userOrgs",
|
|
133
139
|
"sessions",
|
|
140
|
+
"userMd",
|
|
134
141
|
"viewer",
|
|
135
142
|
] as const;
|
|
136
143
|
|
|
@@ -186,6 +193,7 @@ export function toQueryKey(key: ResourceKey): readonly string[] {
|
|
|
186
193
|
case "dismissedBanners":
|
|
187
194
|
case "userOrgs":
|
|
188
195
|
case "sessions":
|
|
196
|
+
case "userMd":
|
|
189
197
|
case "viewer":
|
|
190
198
|
return [key.type, key.userId] as const;
|
|
191
199
|
|