@powerhousedao/network-admin 0.0.50 → 0.0.51
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/dist/style.css +3 -0
- package/dist/subgraphs/networks/resolvers.d.ts.map +1 -1
- package/dist/subgraphs/networks/resolvers.js +58 -3
- package/dist/subgraphs/networks/schema.d.ts.map +1 -1
- package/dist/subgraphs/networks/schema.js +51 -0
- package/dist/subgraphs/workstreams/resolvers.d.ts.map +1 -1
- package/dist/subgraphs/workstreams/resolvers.js +227 -0
- package/dist/subgraphs/workstreams/schema.d.ts.map +1 -1
- package/dist/subgraphs/workstreams/schema.js +64 -1
- package/package.json +2 -2
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/networks/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAK/D,eAAO,MAAM,YAAY,GACvB,UAAU,YAAY,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/networks/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAK/D,eAAO,MAAM,YAAY,GACvB,UAAU,YAAY,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAuMxB,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {} from "@powerhousedao/reactor-api";
|
|
2
2
|
export const getResolvers = (subgraph) => {
|
|
3
3
|
const reactor = subgraph.reactor;
|
|
4
|
+
// Shared state for builder profile resolution (used by field resolvers)
|
|
5
|
+
let getBuilderProfileByPhid = null;
|
|
4
6
|
return {
|
|
5
7
|
Query: {
|
|
6
8
|
allNetworks: async (_, args) => {
|
|
@@ -37,6 +39,8 @@ export const getResolvers = (subgraph) => {
|
|
|
37
39
|
});
|
|
38
40
|
}
|
|
39
41
|
});
|
|
42
|
+
// Also collect contributor PHIDs from builder profiles (we'll fetch them later)
|
|
43
|
+
const contributorPhids = new Set();
|
|
40
44
|
// Step 3: Fetch all builder-profile documents from all drives using the PHIDs
|
|
41
45
|
const builderProfileDocs = await Promise.all(Array.from(allBuilderPhids).map(async (phid) => {
|
|
42
46
|
try {
|
|
@@ -47,24 +51,61 @@ export const getResolvers = (subgraph) => {
|
|
|
47
51
|
return null;
|
|
48
52
|
}
|
|
49
53
|
}));
|
|
50
|
-
// Step 4: Create a map of PHID to builder profile document
|
|
54
|
+
// Step 4: Create a map of PHID to builder profile document and collect contributor PHIDs
|
|
51
55
|
const builderProfileMap = new Map();
|
|
52
56
|
builderProfileDocs.forEach((doc) => {
|
|
53
57
|
if (doc && doc.header.documentType === "powerhouse/builder-profile") {
|
|
54
58
|
builderProfileMap.set(doc.header.id, doc);
|
|
59
|
+
// Collect contributor PHIDs from this builder profile
|
|
60
|
+
const state = doc.state.global;
|
|
61
|
+
if (state?.contributors && Array.isArray(state.contributors)) {
|
|
62
|
+
state.contributors.forEach((phid) => {
|
|
63
|
+
if (phid && !builderProfileMap.has(phid)) {
|
|
64
|
+
contributorPhids.add(phid);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
55
68
|
}
|
|
56
69
|
});
|
|
70
|
+
// Step 4b: Fetch contributor builder profiles if any were found
|
|
71
|
+
if (contributorPhids.size > 0) {
|
|
72
|
+
const contributorDocs = await Promise.all(Array.from(contributorPhids).map(async (phid) => {
|
|
73
|
+
try {
|
|
74
|
+
return await reactor.getDocument(phid);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.warn(`Failed to fetch contributor builder profile ${phid}:`, error);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}));
|
|
81
|
+
contributorDocs.forEach((doc) => {
|
|
82
|
+
if (doc && doc.header.documentType === "powerhouse/builder-profile") {
|
|
83
|
+
builderProfileMap.set(doc.header.id, doc);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
57
87
|
// Step 5: Helper function to get builder profile data by PHID
|
|
58
|
-
|
|
88
|
+
getBuilderProfileByPhid = (phid) => {
|
|
59
89
|
const doc = builderProfileMap.get(phid);
|
|
60
90
|
if (!doc)
|
|
61
91
|
return null;
|
|
62
92
|
const state = doc.state.global;
|
|
93
|
+
// Store contributor PHIDs separately - they'll be resolved by the field resolver
|
|
94
|
+
const contributorPhids = state?.contributors || [];
|
|
63
95
|
return {
|
|
64
96
|
id: doc.header.id,
|
|
97
|
+
code: state?.code || null,
|
|
98
|
+
slug: state?.slug || null,
|
|
65
99
|
name: state?.name || doc.header.name,
|
|
66
100
|
icon: state?.icon || "",
|
|
67
101
|
description: state?.description || state?.slug || "",
|
|
102
|
+
lastModified: state.lastModified || null,
|
|
103
|
+
type: state?.type || "INDIVIDUAL",
|
|
104
|
+
_contributorPhids: contributorPhids, // Internal field for resolver
|
|
105
|
+
status: state?.status || null,
|
|
106
|
+
skilss: state?.skilss || state?.skills || [],
|
|
107
|
+
scopes: state?.scopes || [],
|
|
108
|
+
links: state?.links || [],
|
|
68
109
|
};
|
|
69
110
|
};
|
|
70
111
|
// Step 6: Map each network to its builders from the same drive
|
|
@@ -73,7 +114,7 @@ export const getResolvers = (subgraph) => {
|
|
|
73
114
|
// Get the BuildersDocument from the same drive as the network
|
|
74
115
|
const buildersDoc = driveIdToBuildersDoc.get(driveId);
|
|
75
116
|
// Get builders list from the BuildersDocument and map to builder profiles
|
|
76
|
-
const builders = buildersDoc
|
|
117
|
+
const builders = buildersDoc && getBuilderProfileByPhid
|
|
77
118
|
? (buildersDoc.state.global.builders || [])
|
|
78
119
|
.map((phid) => getBuilderProfileByPhid(phid))
|
|
79
120
|
.filter((builder) => builder !== null)
|
|
@@ -110,5 +151,19 @@ export const getResolvers = (subgraph) => {
|
|
|
110
151
|
return allNetworks;
|
|
111
152
|
},
|
|
112
153
|
},
|
|
154
|
+
Builder: {
|
|
155
|
+
contributors: (parent) => {
|
|
156
|
+
// Resolve contributor PHIDs to Builder objects
|
|
157
|
+
if (!parent._contributorPhids || parent._contributorPhids.length === 0) {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
if (!getBuilderProfileByPhid) {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
return parent._contributorPhids
|
|
164
|
+
.map((phid) => getBuilderProfileByPhid(phid))
|
|
165
|
+
.filter((builder) => builder !== null);
|
|
166
|
+
},
|
|
167
|
+
},
|
|
113
168
|
};
|
|
114
169
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../subgraphs/networks/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../subgraphs/networks/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,MAAM,EAAE,YAqGpB,CAAC"}
|
|
@@ -45,8 +45,59 @@ export const schema = gql `
|
|
|
45
45
|
|
|
46
46
|
type Builder {
|
|
47
47
|
id: PHID
|
|
48
|
+
code: String
|
|
49
|
+
slug: String
|
|
48
50
|
name: String!
|
|
49
51
|
icon: String!
|
|
50
52
|
description: String!
|
|
53
|
+
lastModified: DateTime
|
|
54
|
+
type: teamType!
|
|
55
|
+
contributors: [Builder!]!
|
|
56
|
+
status: BuilderStatus
|
|
57
|
+
skilss: [BuilderSkill!]!
|
|
58
|
+
scopes: [BuilderScope!]!
|
|
59
|
+
links: [BuilderLink!]!
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
enum teamType {
|
|
63
|
+
INDIVIDUAL
|
|
64
|
+
TEAM
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
enum BuilderStatus {
|
|
68
|
+
ACTIVE
|
|
69
|
+
INACTIVE
|
|
70
|
+
ON_HOLD
|
|
71
|
+
COMPLETED
|
|
72
|
+
ARCHIVED
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
enum BuilderSkill {
|
|
76
|
+
FRONTEND_DEVELOPMENT
|
|
77
|
+
BACKEND_DEVELOPMENT
|
|
78
|
+
FULL_STACK_DEVELOPMENT
|
|
79
|
+
DEVOPS_ENGINEERING
|
|
80
|
+
SMART_CONTRACT_DEVELOPMENT
|
|
81
|
+
UI_UX_DESIGN
|
|
82
|
+
TECHNICAL_WRITING
|
|
83
|
+
QA_TESTING
|
|
84
|
+
DATA_ENGINEERING
|
|
85
|
+
SECURITY_ENGINEERING
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
enum BuilderScope {
|
|
89
|
+
ACC
|
|
90
|
+
STA
|
|
91
|
+
SUP
|
|
92
|
+
STABILITY_SCOPE
|
|
93
|
+
SUPPORT_SCOPE
|
|
94
|
+
PROTOCOL_SCOPE
|
|
95
|
+
GOVERNANCE_SCOPE
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
type BuilderLink {
|
|
99
|
+
id: OID!
|
|
100
|
+
url: URL!
|
|
101
|
+
label: String
|
|
51
102
|
}
|
|
52
103
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/workstreams/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/workstreams/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAuC5D,eAAO,MAAM,YAAY,GAAI,UAAU,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAoyBxE,CAAC"}
|
|
@@ -6,6 +6,8 @@ import { sql } from "kysely";
|
|
|
6
6
|
export const getResolvers = (subgraph) => {
|
|
7
7
|
const reactor = subgraph.reactor;
|
|
8
8
|
const db = subgraph.relationalDb;
|
|
9
|
+
// Shared state for builder profile resolution (used by field resolvers)
|
|
10
|
+
let getBuilderProfileByPhid = null;
|
|
9
11
|
const deriveSlug = (name) => name.toLowerCase().trim().split(/\s+/).join("-");
|
|
10
12
|
const getCandidateDrives = async () => {
|
|
11
13
|
try {
|
|
@@ -96,6 +98,73 @@ export const getResolvers = (subgraph) => {
|
|
|
96
98
|
return null;
|
|
97
99
|
}
|
|
98
100
|
};
|
|
101
|
+
// Helper function to collect SOWs from hydrated workstreams
|
|
102
|
+
const collectSowsFromWorkstreams = (workstreams) => {
|
|
103
|
+
const sowDocs = [];
|
|
104
|
+
for (const workstream of workstreams) {
|
|
105
|
+
if (workstream.sow) {
|
|
106
|
+
sowDocs.push(workstream.sow);
|
|
107
|
+
}
|
|
108
|
+
if (workstream.initialProposal?.sow) {
|
|
109
|
+
sowDocs.push(workstream.initialProposal.sow);
|
|
110
|
+
}
|
|
111
|
+
for (const altProposal of workstream.alternativeProposals || []) {
|
|
112
|
+
if (altProposal.sow) {
|
|
113
|
+
sowDocs.push(altProposal.sow);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return sowDocs;
|
|
118
|
+
};
|
|
119
|
+
// Helper function to fetch builder profiles for contributors
|
|
120
|
+
const fetchBuilderProfilesForContributors = async (contributorPhids) => {
|
|
121
|
+
const builderProfileMap = new Map();
|
|
122
|
+
if (contributorPhids.size > 0) {
|
|
123
|
+
const builderProfileDocs = await Promise.all(Array.from(contributorPhids).map(async (phid) => {
|
|
124
|
+
try {
|
|
125
|
+
return await reactor.getDocument(phid);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.warn(`Failed to fetch builder profile ${phid}:`, error);
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}));
|
|
132
|
+
builderProfileDocs.forEach((doc) => {
|
|
133
|
+
if (doc && doc.header.documentType === "powerhouse/builder-profile") {
|
|
134
|
+
builderProfileMap.set(doc.header.id, doc);
|
|
135
|
+
// Also collect contributor PHIDs from these builder profiles
|
|
136
|
+
const state = doc.state.global;
|
|
137
|
+
if (state?.contributors && Array.isArray(state.contributors)) {
|
|
138
|
+
state.contributors.forEach((phid) => {
|
|
139
|
+
if (phid && !builderProfileMap.has(phid)) {
|
|
140
|
+
contributorPhids.add(phid);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
// Fetch nested contributors if any were found
|
|
147
|
+
const nestedContributorPhids = Array.from(contributorPhids).filter((phid) => !builderProfileMap.has(phid));
|
|
148
|
+
if (nestedContributorPhids.length > 0) {
|
|
149
|
+
const nestedContributorDocs = await Promise.all(nestedContributorPhids.map(async (phid) => {
|
|
150
|
+
try {
|
|
151
|
+
return await reactor.getDocument(phid);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.warn(`Failed to fetch contributor builder profile ${phid}:`, error);
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}));
|
|
158
|
+
nestedContributorDocs.forEach((doc) => {
|
|
159
|
+
if (doc &&
|
|
160
|
+
doc.header.documentType === "powerhouse/builder-profile") {
|
|
161
|
+
builderProfileMap.set(doc.header.id, doc);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return builderProfileMap;
|
|
167
|
+
};
|
|
99
168
|
const hydrateWorkstreamRow = async (row) => {
|
|
100
169
|
try {
|
|
101
170
|
const doc = await reactor.getDocument(row.workstream_phid);
|
|
@@ -271,6 +340,7 @@ export const getResolvers = (subgraph) => {
|
|
|
271
340
|
const wantedSlug = filters.networkSlug ||
|
|
272
341
|
(filters.networkName ? deriveSlug(filters.networkName) : undefined);
|
|
273
342
|
const resolved = [];
|
|
343
|
+
const contributorPhids = new Set();
|
|
274
344
|
for (const driveId of candidateDrives) {
|
|
275
345
|
let qb = WorkstreamsProcessor.query(driveId, db)
|
|
276
346
|
.selectFrom("workstreams")
|
|
@@ -286,6 +356,47 @@ export const getResolvers = (subgraph) => {
|
|
|
286
356
|
}
|
|
287
357
|
break;
|
|
288
358
|
}
|
|
359
|
+
// Collect SOWs and their contributors
|
|
360
|
+
const sowDocs = collectSowsFromWorkstreams(resolved);
|
|
361
|
+
for (const sow of sowDocs) {
|
|
362
|
+
if (sow && sow.contributors && Array.isArray(sow.contributors)) {
|
|
363
|
+
sow.contributors.forEach((contributor) => {
|
|
364
|
+
// Handle both string PHIDs and objects with id property
|
|
365
|
+
const phid = typeof contributor === "string"
|
|
366
|
+
? contributor
|
|
367
|
+
: contributor?.id;
|
|
368
|
+
if (phid && typeof phid === "string") {
|
|
369
|
+
contributorPhids.add(phid);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// Fetch all builder profile documents for contributors
|
|
375
|
+
const builderProfileMap = await fetchBuilderProfilesForContributors(contributorPhids);
|
|
376
|
+
// Create helper function to get builder profile data by PHID
|
|
377
|
+
getBuilderProfileByPhid = (phid) => {
|
|
378
|
+
const doc = builderProfileMap.get(phid);
|
|
379
|
+
if (!doc)
|
|
380
|
+
return null;
|
|
381
|
+
const state = doc.state.global;
|
|
382
|
+
// Store contributor PHIDs separately - they'll be resolved by the field resolver
|
|
383
|
+
const contributorPhids = state?.contributors || [];
|
|
384
|
+
return {
|
|
385
|
+
id: doc.header.id,
|
|
386
|
+
code: state?.code || null,
|
|
387
|
+
slug: state?.slug || null,
|
|
388
|
+
name: state?.name || doc.header.name,
|
|
389
|
+
icon: state?.icon || "",
|
|
390
|
+
description: state?.description || state?.slug || "",
|
|
391
|
+
lastModified: state?.lastModified || null,
|
|
392
|
+
type: state?.type || "INDIVIDUAL",
|
|
393
|
+
_contributorPhids: contributorPhids, // Internal field for resolver
|
|
394
|
+
status: state?.status || null,
|
|
395
|
+
skilss: state?.skilss || state?.skills || [],
|
|
396
|
+
scopes: state?.scopes || [],
|
|
397
|
+
links: state?.links || [],
|
|
398
|
+
};
|
|
399
|
+
};
|
|
289
400
|
return resolved;
|
|
290
401
|
},
|
|
291
402
|
workstreams: async (parent, args) => {
|
|
@@ -302,6 +413,7 @@ export const getResolvers = (subgraph) => {
|
|
|
302
413
|
const wantedSlug = filters.networkSlug ||
|
|
303
414
|
(filters.networkName ? deriveSlug(filters.networkName) : undefined);
|
|
304
415
|
const results = [];
|
|
416
|
+
const contributorPhids = new Set();
|
|
305
417
|
for (const driveId of candidateDrives) {
|
|
306
418
|
let qb = WorkstreamsProcessor.query(driveId, db)
|
|
307
419
|
.selectFrom("workstreams")
|
|
@@ -319,6 +431,47 @@ export const getResolvers = (subgraph) => {
|
|
|
319
431
|
results.push(hydrated);
|
|
320
432
|
}
|
|
321
433
|
}
|
|
434
|
+
// Collect SOWs and their contributors
|
|
435
|
+
const sowDocs = collectSowsFromWorkstreams(results);
|
|
436
|
+
for (const sow of sowDocs) {
|
|
437
|
+
if (sow && sow.contributors && Array.isArray(sow.contributors)) {
|
|
438
|
+
sow.contributors.forEach((contributor) => {
|
|
439
|
+
// Handle both string PHIDs and objects with id property
|
|
440
|
+
const phid = typeof contributor === "string"
|
|
441
|
+
? contributor
|
|
442
|
+
: contributor?.id;
|
|
443
|
+
if (phid && typeof phid === "string") {
|
|
444
|
+
contributorPhids.add(phid);
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// Fetch all builder profile documents for contributors
|
|
450
|
+
const builderProfileMap = await fetchBuilderProfilesForContributors(contributorPhids);
|
|
451
|
+
// Create helper function to get builder profile data by PHID
|
|
452
|
+
getBuilderProfileByPhid = (phid) => {
|
|
453
|
+
const doc = builderProfileMap.get(phid);
|
|
454
|
+
if (!doc)
|
|
455
|
+
return null;
|
|
456
|
+
const state = doc.state.global;
|
|
457
|
+
// Store contributor PHIDs separately - they'll be resolved by the field resolver
|
|
458
|
+
const contributorPhids = state?.contributors || [];
|
|
459
|
+
return {
|
|
460
|
+
id: doc.header.id,
|
|
461
|
+
code: state?.code || null,
|
|
462
|
+
slug: state?.slug || null,
|
|
463
|
+
name: state?.name || doc.header.name,
|
|
464
|
+
icon: state?.icon || "",
|
|
465
|
+
description: state?.description || state?.slug || "",
|
|
466
|
+
lastModified: state?.lastModified || null,
|
|
467
|
+
type: state?.type || "INDIVIDUAL",
|
|
468
|
+
_contributorPhids: contributorPhids, // Internal field for resolver
|
|
469
|
+
status: state?.status || null,
|
|
470
|
+
skilss: state?.skilss || state?.skills || [],
|
|
471
|
+
scopes: state?.scopes || [],
|
|
472
|
+
links: state?.links || [],
|
|
473
|
+
};
|
|
474
|
+
};
|
|
322
475
|
return results;
|
|
323
476
|
},
|
|
324
477
|
rfpByWorkstream: async (parent, args) => {
|
|
@@ -357,6 +510,7 @@ export const getResolvers = (subgraph) => {
|
|
|
357
510
|
const wantedSlug = filters.networkSlug ||
|
|
358
511
|
(filters.networkName ? deriveSlug(filters.networkName) : undefined);
|
|
359
512
|
const results = [];
|
|
513
|
+
const contributorPhids = new Set();
|
|
360
514
|
for (const driveId of candidateDrives) {
|
|
361
515
|
let qb = WorkstreamsProcessor.query(driveId, db)
|
|
362
516
|
.selectFrom("workstreams")
|
|
@@ -404,6 +558,18 @@ export const getResolvers = (subgraph) => {
|
|
|
404
558
|
sowDocs.push(hydrated.initialProposal.sow);
|
|
405
559
|
}
|
|
406
560
|
}
|
|
561
|
+
// Collect contributor PHIDs from all SOWs
|
|
562
|
+
for (const sow of sowDocs) {
|
|
563
|
+
if (sow && sow.contributors && Array.isArray(sow.contributors)) {
|
|
564
|
+
sow.contributors.forEach((contributor) => {
|
|
565
|
+
// Handle both string PHIDs and objects with id property
|
|
566
|
+
const phid = typeof contributor === "string" ? contributor : contributor?.id;
|
|
567
|
+
if (phid && typeof phid === "string") {
|
|
568
|
+
contributorPhids.add(phid);
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
}
|
|
407
573
|
// Filter out null/undefined SOWs and add to results
|
|
408
574
|
for (const sow of sowDocs) {
|
|
409
575
|
if (sow) {
|
|
@@ -415,6 +581,32 @@ export const getResolvers = (subgraph) => {
|
|
|
415
581
|
break;
|
|
416
582
|
}
|
|
417
583
|
}
|
|
584
|
+
// Fetch all builder profile documents for contributors
|
|
585
|
+
const builderProfileMap = await fetchBuilderProfilesForContributors(contributorPhids);
|
|
586
|
+
// Create helper function to get builder profile data by PHID
|
|
587
|
+
getBuilderProfileByPhid = (phid) => {
|
|
588
|
+
const doc = builderProfileMap.get(phid);
|
|
589
|
+
if (!doc)
|
|
590
|
+
return null;
|
|
591
|
+
const state = doc.state.global;
|
|
592
|
+
// Store contributor PHIDs separately - they'll be resolved by the field resolver
|
|
593
|
+
const contributorPhids = state?.contributors || [];
|
|
594
|
+
return {
|
|
595
|
+
id: doc.header.id,
|
|
596
|
+
code: state?.code || null,
|
|
597
|
+
slug: state?.slug || null,
|
|
598
|
+
name: state?.name || doc.header.name,
|
|
599
|
+
icon: state?.icon || "",
|
|
600
|
+
description: state?.description || state?.slug || "",
|
|
601
|
+
lastModified: state?.lastModified || null,
|
|
602
|
+
type: state?.type || "INDIVIDUAL",
|
|
603
|
+
_contributorPhids: contributorPhids, // Internal field for resolver
|
|
604
|
+
status: state?.status || null,
|
|
605
|
+
skilss: state?.skilss || state?.skills || [],
|
|
606
|
+
scopes: state?.scopes || [],
|
|
607
|
+
links: state?.links || [],
|
|
608
|
+
};
|
|
609
|
+
};
|
|
418
610
|
return results;
|
|
419
611
|
},
|
|
420
612
|
},
|
|
@@ -435,5 +627,40 @@ export const getResolvers = (subgraph) => {
|
|
|
435
627
|
return null;
|
|
436
628
|
},
|
|
437
629
|
},
|
|
630
|
+
SOW_ScopeOfWorkState: {
|
|
631
|
+
contributors: (parent) => {
|
|
632
|
+
// Resolve contributor PHIDs to Builder objects
|
|
633
|
+
if (!parent.contributors || parent.contributors.length === 0) {
|
|
634
|
+
return [];
|
|
635
|
+
}
|
|
636
|
+
if (!getBuilderProfileByPhid) {
|
|
637
|
+
return [];
|
|
638
|
+
}
|
|
639
|
+
return parent.contributors
|
|
640
|
+
.map((contributor) => {
|
|
641
|
+
// Handle both string PHIDs and objects with id property
|
|
642
|
+
const phid = typeof contributor === "string" ? contributor : contributor?.id;
|
|
643
|
+
if (!phid || typeof phid !== "string") {
|
|
644
|
+
return null;
|
|
645
|
+
}
|
|
646
|
+
return getBuilderProfileByPhid(phid);
|
|
647
|
+
})
|
|
648
|
+
.filter((builder) => builder !== null);
|
|
649
|
+
},
|
|
650
|
+
},
|
|
651
|
+
Builder: {
|
|
652
|
+
contributors: (parent) => {
|
|
653
|
+
// Resolve contributor PHIDs to Builder objects
|
|
654
|
+
if (!parent._contributorPhids || parent._contributorPhids.length === 0) {
|
|
655
|
+
return [];
|
|
656
|
+
}
|
|
657
|
+
if (!getBuilderProfileByPhid) {
|
|
658
|
+
return [];
|
|
659
|
+
}
|
|
660
|
+
return parent._contributorPhids
|
|
661
|
+
.map((phid) => getBuilderProfileByPhid(phid))
|
|
662
|
+
.filter((builder) => builder !== null);
|
|
663
|
+
},
|
|
664
|
+
},
|
|
438
665
|
};
|
|
439
666
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../subgraphs/workstreams/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../subgraphs/workstreams/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,MAAM,EAAE,YAugBpB,CAAC"}
|
|
@@ -198,7 +198,7 @@ export const schema = gql `
|
|
|
198
198
|
deliverables: [SOW_Deliverable!]!
|
|
199
199
|
projects: [SOW_Project!]!
|
|
200
200
|
roadmaps: [SOW_Roadmap!]!
|
|
201
|
-
contributors: [
|
|
201
|
+
contributors: [Builder!]!
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
enum SOW_ScopeOfWorkStatus {
|
|
@@ -276,6 +276,7 @@ export const schema = gql `
|
|
|
276
276
|
id: OID!
|
|
277
277
|
code: String!
|
|
278
278
|
title: String!
|
|
279
|
+
slug: String!
|
|
279
280
|
projectOwner: ID
|
|
280
281
|
abstract: String
|
|
281
282
|
imageUrl: URL
|
|
@@ -455,4 +456,66 @@ export const schema = gql `
|
|
|
455
456
|
sow: SOW_ScopeOfWorkState
|
|
456
457
|
paymentTerms: PT_PaymentTermsState
|
|
457
458
|
}
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
# ==========================
|
|
462
|
+
# Builder (typed)
|
|
463
|
+
# ==========================
|
|
464
|
+
type Builder {
|
|
465
|
+
id: PHID
|
|
466
|
+
code: String
|
|
467
|
+
slug: String
|
|
468
|
+
name: String!
|
|
469
|
+
icon: String!
|
|
470
|
+
description: String!
|
|
471
|
+
lastModified: DateTime
|
|
472
|
+
type: teamType!
|
|
473
|
+
contributors: [Builder!]!
|
|
474
|
+
status: BuilderStatus
|
|
475
|
+
skilss: [BuilderSkill!]!
|
|
476
|
+
scopes: [BuilderScope!]!
|
|
477
|
+
links: [BuilderLink!]!
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
enum teamType {
|
|
481
|
+
INDIVIDUAL
|
|
482
|
+
TEAM
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
enum BuilderStatus {
|
|
486
|
+
ACTIVE
|
|
487
|
+
INACTIVE
|
|
488
|
+
ON_HOLD
|
|
489
|
+
COMPLETED
|
|
490
|
+
ARCHIVED
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
enum BuilderSkill {
|
|
494
|
+
FRONTEND_DEVELOPMENT
|
|
495
|
+
BACKEND_DEVELOPMENT
|
|
496
|
+
FULL_STACK_DEVELOPMENT
|
|
497
|
+
DEVOPS_ENGINEERING
|
|
498
|
+
SMART_CONTRACT_DEVELOPMENT
|
|
499
|
+
UI_UX_DESIGN
|
|
500
|
+
TECHNICAL_WRITING
|
|
501
|
+
QA_TESTING
|
|
502
|
+
DATA_ENGINEERING
|
|
503
|
+
SECURITY_ENGINEERING
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
enum BuilderScope {
|
|
507
|
+
ACC
|
|
508
|
+
STA
|
|
509
|
+
SUP
|
|
510
|
+
STABILITY_SCOPE
|
|
511
|
+
SUPPORT_SCOPE
|
|
512
|
+
PROTOCOL_SCOPE
|
|
513
|
+
GOVERNANCE_SCOPE
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
type BuilderLink {
|
|
517
|
+
id: OID!
|
|
518
|
+
url: URL!
|
|
519
|
+
label: String
|
|
520
|
+
}
|
|
458
521
|
`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/network-admin",
|
|
3
3
|
"description": "Network Admin package for Powerhouse",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.51",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"@powerhousedao/common": "^5.0.12",
|
|
67
67
|
"@powerhousedao/design-system": "^5.0.12",
|
|
68
68
|
"@powerhousedao/document-engineering": "^1.39.0",
|
|
69
|
-
"@powerhousedao/project-management": "0.0.
|
|
69
|
+
"@powerhousedao/project-management": "0.0.65",
|
|
70
70
|
"@uiw/react-md-editor": "^4.0.8",
|
|
71
71
|
"document-model": "^5.0.12",
|
|
72
72
|
"error": "^10.4.0",
|