@powerhousedao/service-offering 1.0.0-dev.16 → 1.0.0-dev.18

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.
@@ -8,51 +8,54 @@ export interface RemoteBuilderProfile {
8
8
  name: string | null;
9
9
  slug: string | null;
10
10
  icon: string | null;
11
+ description: string | null;
11
12
  };
12
13
  }
13
- /**
14
- * Fetches all available remote drives
15
- */
16
- export declare function fetchRemoteDrives(): Promise<string[]>;
17
- /**
18
- * Fetches drive ID by slug
19
- */
20
- export declare function fetchDriveIdBySlug(slug: string): Promise<string | null>;
21
- /**
22
- * Fetches all builder profiles from a specific drive
23
- */
24
- export declare function fetchBuilderProfilesFromDrive(driveId: string, options?: {
25
- silent?: boolean;
26
- }): Promise<RemoteBuilderProfile[]>;
27
14
  /**
28
15
  * Fetches a single builder profile by document ID
29
16
  */
30
- export declare function fetchBuilderProfileById(docId: string, driveId?: string): Promise<RemoteBuilderProfile | null>;
17
+ export declare function fetchBuilderProfileById(docId: string): Promise<RemoteBuilderProfile | null>;
31
18
  /**
32
- * Fetches all builder profiles from all available remote drives.
33
- * This aggregates profiles from multiple drives into a single list.
19
+ * Fetches all builder profiles using BuilderProfile_findDocuments.
34
20
  */
35
21
  export declare function fetchAllRemoteBuilderProfiles(): Promise<RemoteBuilderProfile[]>;
36
22
  /**
37
23
  * Fetches multiple builder profiles by their IDs.
38
- * Tries to find them across all available remote drives.
39
24
  */
40
25
  export declare function fetchRemoteBuilderProfilesByIds(phids: string[]): Promise<Map<string, RemoteBuilderProfile>>;
26
+ export interface SetOpHubMemberInput {
27
+ name: string | null;
28
+ phid: string | null;
29
+ }
30
+ /**
31
+ * Sets the operational hub member on a builder profile document.
32
+ *
33
+ * @param docId - The builder profile document ID (PHID)
34
+ * @param input - The operational hub member data (name and phid of the op hub)
35
+ * @returns true if successful, false otherwise
36
+ */
37
+ export declare function setOpHubMemberOnBuilderProfile(docId: string, input: SetOpHubMemberInput): Promise<boolean>;
38
+ interface RemoteResourceTemplateService {
39
+ id: string;
40
+ title: string;
41
+ isSetupFormation: boolean;
42
+ description: string | null;
43
+ displayOrder: number | null;
44
+ optionGroupId: string | null;
45
+ }
41
46
  export interface RemoteResourceTemplate {
42
47
  id: string;
43
- name: string;
44
- documentType: string;
45
- /** Resolved operator/builder name (from builder profile in the same drive) */
46
- operatorName: string | null;
48
+ name: string | null;
49
+ operatorName?: string | null;
47
50
  state: {
48
51
  id: string | null;
49
52
  operatorId: string | null;
50
- title: string;
51
- summary: string;
53
+ title: string | null;
54
+ summary: string | null;
52
55
  description: string | null;
53
56
  thumbnailUrl: string | null;
54
57
  infoLink: string | null;
55
- status: string;
58
+ status: string | null;
56
59
  lastModified: string | null;
57
60
  targetAudiences: Array<{
58
61
  id: string;
@@ -67,27 +70,11 @@ export interface RemoteResourceTemplate {
67
70
  categoryLabel: string;
68
71
  selectedOptions: string[];
69
72
  }>;
70
- services: Array<{
71
- id: string;
72
- title: string;
73
- description: string | null;
74
- displayOrder: number | null;
75
- isSetupFormation: boolean;
76
- optionGroupId: string | null;
77
- }>;
73
+ services: RemoteResourceTemplateService[];
78
74
  };
79
75
  }
80
- /** Raw response shape from GraphQL (without enriched operatorName) */
81
- type RawRemoteResourceTemplate = Omit<RemoteResourceTemplate, "operatorName">;
82
- /**
83
- * Fetches resource template documents from a specific drive
84
- */
85
- export declare function fetchResourceTemplatesFromDrive(driveId: string, options?: {
86
- silent?: boolean;
87
- }): Promise<RawRemoteResourceTemplate[]>;
88
76
  /**
89
- * Fetches all resource templates from all available remote drives.
90
- * Also resolves operator names by fetching builder profiles from each drive.
77
+ * Fetches all resource template documents from the remote Switchboard.
91
78
  */
92
79
  export declare function fetchAllRemoteResourceTemplates(): Promise<RemoteResourceTemplate[]>;
93
80
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"graphql-client.d.ts","sourceRoot":"","sources":["../../../../editors/service-offering-editor/utils/graphql-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graphql-client.d.ts","sourceRoot":"","sources":["../../../../editors/service-offering-editor/utils/graphql-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAwHH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC;CACH;AAyCD;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAOtC;AAED;;GAEG;AACH,wBAAsB,6BAA6B,IAAI,OAAO,CAC5D,oBAAoB,EAAE,CACvB,CAUA;AAED;;GAEG;AACH,wBAAsB,+BAA+B,CACnD,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CA+B5C;AASD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAMD;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,OAAO,CAAC,CAWlB;AAkDD,UAAU,6BAA6B;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,eAAe,EAAE,KAAK,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;YACX,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;SACtB,CAAC,CAAC;QACH,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,YAAY,EAAE,KAAK,CAAC;YAClB,EAAE,EAAE,MAAM,CAAC;YACX,WAAW,EAAE,MAAM,CAAC;YACpB,aAAa,EAAE,MAAM,CAAC;YACtB,eAAe,EAAE,MAAM,EAAE,CAAC;SAC3B,CAAC,CAAC;QACH,QAAQ,EAAE,6BAA6B,EAAE,CAAC;KAC3C,CAAC;CACH;AAmED;;GAEG;AACH,wBAAsB,+BAA+B,IAAI,OAAO,CAC9D,sBAAsB,EAAE,CACzB,CAYA"}
@@ -54,99 +54,74 @@ async function graphqlRequest(query, variables, options) {
54
54
  return null;
55
55
  }
56
56
  }
57
- // Query to get all available drives
58
- const GET_DRIVES_QUERY = `
59
- query GetDrives {
60
- drives
61
- }
62
- `;
63
- // Query to get drive ID by slug
64
- const GET_DRIVE_ID_BY_SLUG_QUERY = `
65
- query GetDriveIdBySlug($slug: String!) {
66
- driveIdBySlug(slug: $slug)
67
- }
68
- `;
69
- // Query to get builder profile documents from a drive
70
- const GET_BUILDER_PROFILES_QUERY = `
71
- query GetBuilderProfiles($driveId: String!) {
72
- BuilderProfile {
73
- getDocuments(driveId: $driveId) {
57
+ // Query to find all builder profile documents
58
+ const FIND_BUILDER_PROFILES_QUERY = `
59
+ query FindBuilderProfiles {
60
+ BuilderProfile_findDocuments(search: {}) {
61
+ items {
74
62
  id
63
+ name
75
64
  state {
76
- name
77
- slug
78
- icon
65
+ global {
66
+ id
67
+ name
68
+ slug
69
+ icon
70
+ description
71
+ }
79
72
  }
80
73
  }
74
+ totalCount
81
75
  }
82
76
  }
83
77
  `;
84
- // Query to get a single builder profile by ID
78
+ // Query to get a single builder profile by identifier
85
79
  const GET_BUILDER_PROFILE_QUERY = `
86
- query GetBuilderProfile($docId: PHID!, $driveId: PHID) {
87
- BuilderProfile {
88
- getDocument(docId: $docId, driveId: $driveId) {
80
+ query GetBuilderProfile($identifier: String!) {
81
+ BuilderProfile_document(identifier: $identifier) {
82
+ document {
89
83
  id
84
+ name
90
85
  state {
91
- name
92
- slug
93
- icon
86
+ global {
87
+ id
88
+ name
89
+ slug
90
+ icon
91
+ description
92
+ }
94
93
  }
95
94
  }
96
95
  }
97
96
  }
98
97
  `;
99
- /**
100
- * Fetches all available remote drives
101
- */
102
- export async function fetchRemoteDrives() {
103
- const data = await graphqlRequest(GET_DRIVES_QUERY);
104
- return data?.drives ?? [];
105
- }
106
- /**
107
- * Fetches drive ID by slug
108
- */
109
- export async function fetchDriveIdBySlug(slug) {
110
- const data = await graphqlRequest(GET_DRIVE_ID_BY_SLUG_QUERY, { slug });
111
- return data?.driveIdBySlug ?? null;
112
- }
113
- /**
114
- * Fetches all builder profiles from a specific drive
115
- */
116
- export async function fetchBuilderProfilesFromDrive(driveId, options) {
117
- const data = await graphqlRequest(GET_BUILDER_PROFILES_QUERY, { driveId }, options);
118
- return data?.BuilderProfile?.getDocuments ?? [];
98
+ function toRemoteProfile(item) {
99
+ return {
100
+ id: item.id,
101
+ state: {
102
+ name: item.state.global.name,
103
+ slug: item.state.global.slug,
104
+ icon: item.state.global.icon,
105
+ description: item.state.global.description,
106
+ },
107
+ };
119
108
  }
120
109
  /**
121
110
  * Fetches a single builder profile by document ID
122
111
  */
123
- export async function fetchBuilderProfileById(docId, driveId) {
124
- const data = await graphqlRequest(GET_BUILDER_PROFILE_QUERY, { docId, driveId });
125
- return data?.BuilderProfile?.getDocument ?? null;
112
+ export async function fetchBuilderProfileById(docId) {
113
+ const data = await graphqlRequest(GET_BUILDER_PROFILE_QUERY, { identifier: docId });
114
+ const item = data?.BuilderProfile_document?.document;
115
+ return item ? toRemoteProfile(item) : null;
126
116
  }
127
117
  /**
128
- * Fetches all builder profiles from all available remote drives.
129
- * This aggregates profiles from multiple drives into a single list.
118
+ * Fetches all builder profiles using BuilderProfile_findDocuments.
130
119
  */
131
120
  export async function fetchAllRemoteBuilderProfiles() {
132
121
  try {
133
- const drives = await fetchRemoteDrives();
134
- if (!drives.length) {
135
- return [];
136
- }
137
- // Fetch profiles from all drives in parallel (silent to avoid console spam)
138
- const profilePromises = drives.map((driveSlug) => fetchBuilderProfilesFromDrive(driveSlug, { silent: true }).catch(() => []));
139
- const profileArrays = await Promise.all(profilePromises);
140
- // Flatten and dedupe by ID
141
- const profileMap = new Map();
142
- for (const profiles of profileArrays) {
143
- for (const profile of profiles) {
144
- if (!profileMap.has(profile.id)) {
145
- profileMap.set(profile.id, profile);
146
- }
147
- }
148
- }
149
- return Array.from(profileMap.values());
122
+ const data = await graphqlRequest(FIND_BUILDER_PROFILES_QUERY);
123
+ const items = data?.BuilderProfile_findDocuments?.items ?? [];
124
+ return items.map(toRemoteProfile);
150
125
  }
151
126
  catch {
152
127
  return [];
@@ -154,16 +129,13 @@ export async function fetchAllRemoteBuilderProfiles() {
154
129
  }
155
130
  /**
156
131
  * Fetches multiple builder profiles by their IDs.
157
- * Tries to find them across all available remote drives.
158
132
  */
159
133
  export async function fetchRemoteBuilderProfilesByIds(phids) {
160
134
  if (!phids.length) {
161
135
  return new Map();
162
136
  }
163
137
  try {
164
- // First, get all profiles from all drives
165
138
  const allProfiles = await fetchAllRemoteBuilderProfiles();
166
- // Filter to only the ones we need
167
139
  const result = new Map();
168
140
  for (const profile of allProfiles) {
169
141
  if (phids.includes(profile.id)) {
@@ -187,101 +159,106 @@ export async function fetchRemoteBuilderProfilesByIds(phids) {
187
159
  return new Map();
188
160
  }
189
161
  }
190
- // ============================================================
191
- // Resource Template queries
192
- // ============================================================
193
- const GET_RESOURCE_TEMPLATES_QUERY = `
194
- query GetResourceTemplates($driveId: String!) {
195
- ResourceTemplate {
196
- getDocuments(driveId: $driveId) {
162
+ // Mutation to set operational hub member on a builder profile
163
+ const SET_OP_HUB_MEMBER_MUTATION = `
164
+ mutation BuilderProfile_setOpHubMember($docId: PHID!, $input: BuilderProfile_SetOpHubMemberInput!) {
165
+ BuilderProfile_setOpHubMember(docId: $docId, input: $input)
166
+ }
167
+ `;
168
+ /**
169
+ * Sets the operational hub member on a builder profile document.
170
+ *
171
+ * @param docId - The builder profile document ID (PHID)
172
+ * @param input - The operational hub member data (name and phid of the op hub)
173
+ * @returns true if successful, false otherwise
174
+ */
175
+ export async function setOpHubMemberOnBuilderProfile(docId, input) {
176
+ try {
177
+ const data = await graphqlRequest(SET_OP_HUB_MEMBER_MUTATION, { docId, input });
178
+ return data?.BuilderProfile_setOpHubMember ?? false;
179
+ }
180
+ catch (error) {
181
+ console.warn("[graphql-client] Failed to set op hub member:", error);
182
+ return false;
183
+ }
184
+ }
185
+ // ── Resource Template queries ──
186
+ const FIND_RESOURCE_TEMPLATES_QUERY = `
187
+ query FindResourceTemplates {
188
+ ResourceTemplate_findDocuments(search: {}) {
189
+ items {
197
190
  id
198
191
  name
199
- documentType
200
192
  state {
201
- id
202
- operatorId
203
- title
204
- summary
205
- description
206
- thumbnailUrl
207
- infoLink
208
- status
209
- lastModified
210
- targetAudiences {
211
- id
212
- label
213
- color
214
- }
215
- setupServices
216
- recurringServices
217
- facetTargets {
218
- id
219
- categoryKey
220
- categoryLabel
221
- selectedOptions
222
- }
223
- services {
193
+ global {
224
194
  id
195
+ operatorId
225
196
  title
197
+ summary
226
198
  description
227
- displayOrder
228
- isSetupFormation
229
- optionGroupId
199
+ thumbnailUrl
200
+ infoLink
201
+ status
202
+ lastModified
203
+ targetAudiences {
204
+ id
205
+ label
206
+ color
207
+ }
208
+ setupServices
209
+ recurringServices
210
+ facetTargets {
211
+ id
212
+ categoryKey
213
+ categoryLabel
214
+ selectedOptions
215
+ }
216
+ services {
217
+ id
218
+ title
219
+ isSetupFormation
220
+ description
221
+ displayOrder
222
+ optionGroupId
223
+ }
230
224
  }
231
225
  }
232
226
  }
227
+ totalCount
233
228
  }
234
229
  }
235
230
  `;
236
- /**
237
- * Fetches resource template documents from a specific drive
238
- */
239
- export async function fetchResourceTemplatesFromDrive(driveId, options) {
240
- const data = await graphqlRequest(GET_RESOURCE_TEMPLATES_QUERY, { driveId }, options);
241
- return data?.ResourceTemplate?.getDocuments ?? [];
231
+ function toRemoteResourceTemplate(item) {
232
+ const g = item.state.global;
233
+ return {
234
+ id: item.id,
235
+ name: item.name,
236
+ state: {
237
+ id: g.id,
238
+ operatorId: g.operatorId,
239
+ title: g.title,
240
+ summary: g.summary,
241
+ description: g.description,
242
+ thumbnailUrl: g.thumbnailUrl,
243
+ infoLink: g.infoLink,
244
+ status: g.status,
245
+ lastModified: g.lastModified,
246
+ targetAudiences: g.targetAudiences ?? [],
247
+ setupServices: g.setupServices ?? [],
248
+ recurringServices: g.recurringServices ?? [],
249
+ facetTargets: g.facetTargets ?? [],
250
+ services: g.services ?? [],
251
+ },
252
+ };
242
253
  }
243
254
  /**
244
- * Fetches all resource templates from all available remote drives.
245
- * Also resolves operator names by fetching builder profiles from each drive.
255
+ * Fetches all resource template documents from the remote Switchboard.
246
256
  */
247
257
  export async function fetchAllRemoteResourceTemplates() {
248
258
  try {
249
- const drives = await fetchRemoteDrives();
250
- if (!drives.length) {
251
- return [];
252
- }
253
- // For each drive, fetch templates AND builder profiles in parallel
254
- const perDrivePromises = drives.map(async (driveSlug) => {
255
- const [templates, profiles] = await Promise.all([
256
- fetchResourceTemplatesFromDrive(driveSlug, { silent: true }).catch(() => []),
257
- fetchBuilderProfilesFromDrive(driveSlug, { silent: true }).catch(() => []),
258
- ]);
259
- // Build a profileId → name map for this drive
260
- const profileNameMap = new Map();
261
- for (const profile of profiles) {
262
- if (profile.state.name) {
263
- profileNameMap.set(profile.id, profile.state.name);
264
- }
265
- }
266
- // Enrich templates with operator name
267
- return templates.map((t) => ({
268
- ...t,
269
- operatorName: t.state.operatorId
270
- ? (profileNameMap.get(t.state.operatorId) ?? null)
271
- : null,
272
- }));
273
- });
274
- const templateArrays = await Promise.all(perDrivePromises);
275
- // Flatten and dedupe by ID
276
- const templateMap = new Map();
277
- for (const templates of templateArrays) {
278
- for (const template of templates) {
279
- if (!templateMap.has(template.id)) {
280
- templateMap.set(template.id, template);
281
- }
282
- }
283
- }
284
- return Array.from(templateMap.values());
259
+ const data = await graphqlRequest(FIND_RESOURCE_TEMPLATES_QUERY, undefined, { silent: true });
260
+ const items = data?.ResourceTemplate_findDocuments?.items ?? [];
261
+ return items.map(toRemoteResourceTemplate);
285
262
  }
286
263
  catch {
287
264
  return [];
package/dist/style.css CHANGED
@@ -394,6 +394,9 @@
394
394
  .left-\[calc\(100\%-1\.125rem\)\] {
395
395
  left: calc(100% - 1.125rem);
396
396
  }
397
+ .isolate {
398
+ isolation: isolate;
399
+ }
397
400
  .z-10 {
398
401
  z-index: 10;
399
402
  }
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/resources-services/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAyD/D,eAAO,MAAM,YAAY,GACvB,UAAU,YAAY,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CA4gBxB,CAAC"}
1
+ {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/resources-services/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAyD/D,eAAO,MAAM,YAAY,GACvB,UAAU,YAAY,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CA+hBxB,CAAC"}
@@ -10,12 +10,15 @@ export const getResolvers = (subgraph) => {
10
10
  Query: {
11
11
  resourceTemplates: async (_, args) => {
12
12
  const { id, status, operatorId } = args.filter || {};
13
+ const deletedDriveDocIds = await getDeletedDriveDocIds(reactorClient);
13
14
  // If filtering by specific id, try to fetch directly
14
15
  if (id) {
15
16
  try {
16
17
  const doc = await reactorClient.get(id);
17
18
  if (doc &&
18
- doc.header.documentType === "powerhouse/resource-template") {
19
+ doc.header.documentType === "powerhouse/resource-template" &&
20
+ !doc.state.document.isDeleted &&
21
+ !deletedDriveDocIds.has(doc.header.id)) {
19
22
  const state = doc.state.global;
20
23
  if (status &&
21
24
  status.length > 0 &&
@@ -39,6 +42,11 @@ export const getResolvers = (subgraph) => {
39
42
  });
40
43
  const resourceTemplates = [];
41
44
  for (const doc of docs) {
45
+ // Skip docs from soft-deleted drives or soft-deleted documents
46
+ if (deletedDriveDocIds.has(doc.header.id))
47
+ continue;
48
+ if (doc.state.document.isDeleted)
49
+ continue;
42
50
  const resourceDoc = doc;
43
51
  const state = resourceDoc.state.global;
44
52
  // Skip documents missing required fields
@@ -58,12 +66,15 @@ export const getResolvers = (subgraph) => {
58
66
  },
59
67
  serviceOfferings: async (_, args) => {
60
68
  const { id, status, operatorId, resourceTemplateId } = args.filter || {};
69
+ const deletedDriveDocIds = await getDeletedDriveDocIds(reactorClient);
61
70
  // If filtering by specific id, try to fetch directly
62
71
  if (id) {
63
72
  try {
64
73
  const doc = await reactorClient.get(id);
65
74
  if (doc &&
66
- doc.header.documentType === "powerhouse/service-offering") {
75
+ doc.header.documentType === "powerhouse/service-offering" &&
76
+ !doc.state.document.isDeleted &&
77
+ !deletedDriveDocIds.has(doc.header.id)) {
67
78
  const state = doc.state.global;
68
79
  if (status &&
69
80
  status.length > 0 &&
@@ -91,6 +102,11 @@ export const getResolvers = (subgraph) => {
91
102
  });
92
103
  const serviceOfferings = [];
93
104
  for (const doc of docs) {
105
+ // Skip docs from soft-deleted drives or soft-deleted documents
106
+ if (deletedDriveDocIds.has(doc.header.id))
107
+ continue;
108
+ if (doc.state.document.isDeleted)
109
+ continue;
94
110
  const offeringDoc = doc;
95
111
  const state = offeringDoc.state.global;
96
112
  // Skip documents missing required fields
@@ -195,8 +211,11 @@ export const getResolvers = (subgraph) => {
195
211
  };
196
212
  }
197
213
  // Fetch the service offering
214
+ const deletedDriveDocIds = await getDeletedDriveDocIds(reactorClient);
198
215
  const serviceOfferingDoc = await reactorClient.get(serviceOfferingId);
199
- if (!serviceOfferingDoc) {
216
+ if (!serviceOfferingDoc ||
217
+ serviceOfferingDoc.state.document.isDeleted ||
218
+ deletedDriveDocIds.has(serviceOfferingDoc.header.id)) {
200
219
  return {
201
220
  success: false,
202
221
  data: null,
@@ -667,12 +686,36 @@ function mapServiceOfferingState(state, doc) {
667
686
  })),
668
687
  };
669
688
  }
689
+ /**
690
+ * Returns a Set of document IDs that belong to soft-deleted drives.
691
+ * Documents inside a deleted drive should not be returned by queries.
692
+ */
693
+ async function getDeletedDriveDocIds(reactorClient) {
694
+ const { results: drives } = await reactorClient.find({
695
+ type: "powerhouse/document-drive",
696
+ });
697
+ const ids = new Set();
698
+ for (const drive of drives) {
699
+ if (!drive.state.document.isDeleted)
700
+ continue;
701
+ const driveDoc = drive;
702
+ for (const node of driveDoc.state.global.nodes) {
703
+ if (node.kind === "file") {
704
+ ids.add(node.id);
705
+ }
706
+ }
707
+ }
708
+ return ids;
709
+ }
670
710
  async function getOperatorDrive(reactorClient, resourceTemplateId) {
671
711
  // Find all drives
672
712
  const { results: drives } = await reactorClient.find({
673
713
  type: "powerhouse/document-drive",
674
714
  });
675
715
  for (const drive of drives) {
716
+ // Skip soft-deleted drives
717
+ if (drive.state.document.isDeleted)
718
+ continue;
676
719
  const driveDoc = drive;
677
720
  // Check if this drive contains the resource template as a child
678
721
  const { results: children } = await reactorClient.getChildren(driveDoc.header.id);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@powerhousedao/service-offering",
3
3
  "description": "service offering document models",
4
- "version": "1.0.0-dev.16",
4
+ "version": "1.0.0-dev.18",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
7
7
  "type": "git",