@powerhousedao/network-admin 0.0.46 → 0.0.47

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.
@@ -11,7 +11,7 @@ export const workstreamsProcessorFactory = (module) => async (driveHeader) => {
11
11
  const filter = {
12
12
  branch: ["main"],
13
13
  documentId: ["*"],
14
- documentType: ["powerhouse/workstream"],
14
+ documentType: ["powerhouse/workstream", "powerhouse/document-drive"],
15
15
  scope: ["global"],
16
16
  };
17
17
  // Create the processor
@@ -3,6 +3,7 @@ import type { InternalTransmitterUpdate, InternalOperationUpdate } from "documen
3
3
  import type { DB } from "./schema.js";
4
4
  export declare class WorkstreamsProcessor extends RelationalDbProcessor<DB> {
5
5
  static getNamespace(driveId: string): string;
6
+ workstreams: string[];
6
7
  initAndUpgrade(): Promise<void>;
7
8
  onStrands(strands: InternalTransmitterUpdate[]): Promise<void>;
8
9
  onDisconnect(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../processors/workstreams/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,yBAAyB,EAAE,uBAAuB,EAAG,MAAM,gBAAgB,CAAC;AAG1F,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEtC,qBAAa,oBAAqB,SAAQ,qBAAqB,CAAC,EAAE,CAAC;WACjD,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAKtC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,SAAS,CACtB,OAAO,EAAE,yBAAyB,EAAE,GACnC,OAAO,CAAC,IAAI,CAAC;IAyBV,YAAY;IAelB,aAAa,GAAU,QAAQ,yBAAyB,mBA8BvD;IAED,iCAAiC,GAAU,QAAQ,yBAAyB,EAAE,WAAW,uBAAuB,mBA2C/G;IAED,yBAAyB,GAAU,QAAQ,yBAAyB,EAAE,WAAW,uBAAuB,mBAwCvG;IAED,gBAAgB,GAAU,QAAQ,yBAAyB,EAAE,WAAW,uBAAuB,mBAyC9F;CACF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../processors/workstreams/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,yBAAyB,EAAE,uBAAuB,EAAqB,MAAM,gBAAgB,CAAC;AAG5G,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEtC,qBAAa,oBAAqB,SAAQ,qBAAqB,CAAC,EAAE,CAAC;WACjD,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAKrD,WAAW,EAAE,MAAM,EAAE,CAAK;IAEX,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,SAAS,CACtB,OAAO,EAAE,yBAAyB,EAAE,GACnC,OAAO,CAAC,IAAI,CAAC;IAoCV,YAAY;IAelB,aAAa,GAAU,QAAQ,yBAAyB,mBA+BvD;IAED,iCAAiC,GAAU,QAAQ,yBAAyB,EAAE,WAAW,uBAAuB,mBA6C/G;IAED,yBAAyB,GAAU,QAAQ,yBAAyB,EAAE,WAAW,uBAAuB,mBAwCvG;IAED,gBAAgB,GAAU,QAAQ,yBAAyB,EAAE,WAAW,uBAAuB,mBAyC9F;CACF"}
@@ -5,6 +5,7 @@ export class WorkstreamsProcessor extends RelationalDbProcessor {
5
5
  // Default namespace: `${this.name}_${driveId.replaceAll("-", "_")}`
6
6
  return super.getNamespace(driveId);
7
7
  }
8
+ workstreams = [];
8
9
  async initAndUpgrade() {
9
10
  await up(this.relationalDb);
10
11
  }
@@ -19,13 +20,23 @@ export class WorkstreamsProcessor extends RelationalDbProcessor {
19
20
  if (strand.documentType === "powerhouse/workstream") {
20
21
  this.setWorkstream(strand);
21
22
  }
22
- // console.log("strand", { documentType: strand.documentType, docId: strand.documentId, state: strand.state });
23
+ // console.log("strand", { documentType: strand.documentType, docId: strand.documentId });
23
24
  for (const operation of strand.operations) {
24
25
  if (strand.documentType === "powerhouse/workstream") {
25
26
  this.updateWorkstream(strand, operation);
26
27
  this.updateNetworkInWorkstream(strand, operation);
27
28
  this.updateInitialProposalInWorkstream(strand, operation);
28
29
  }
30
+ if (strand.documentType === "powerhouse/document-drive") {
31
+ if (operation.action.type === "DELETE_NODE") {
32
+ const castAction = operation.action;
33
+ console.log("deleting workstream node", (castAction.input.id));
34
+ const foundWorkstream = this.workstreams.find(ws => ws === castAction.input.id);
35
+ if (foundWorkstream) {
36
+ await this.relationalDb.deleteFrom("workstreams").where("workstream_phid", "=", foundWorkstream).execute();
37
+ }
38
+ }
39
+ }
29
40
  }
30
41
  }
31
42
  }
@@ -54,21 +65,22 @@ export class WorkstreamsProcessor extends RelationalDbProcessor {
54
65
  console.log("existingWorkstreamPhids", existingWorkstreamPhids);
55
66
  if (existingWorkstreamPhids.length === 0) {
56
67
  console.log('No workstream id found, inserting new one', docId);
68
+ this.workstreams.push(docId);
57
69
  // insert network id
58
70
  await this.relationalDb
59
71
  .insertInto("workstreams")
60
72
  .values({
61
- // network_phid: strand.state.client.id,
62
- // network_slug: strand.state.client.name.toLowerCase().split(' ').join("-"),
73
+ network_phid: strand.state.client.id,
74
+ network_slug: strand.state.client.name ? strand.state.client.name.toLowerCase().split(' ').join("-") : null,
63
75
  workstream_phid: strand.documentId,
64
76
  workstream_slug: strand.state.title ? strand.state.title.toLowerCase().split(' ').join("-") : "",
65
77
  workstream_title: strand.state.title,
66
78
  workstream_status: strand.state.status,
67
- // sow_phid: strand.state.sow,
79
+ sow_phid: strand.state.initialProposal ? strand.state.initialProposal.sow : null,
68
80
  // roadmap_oid: "which roadmmap Id ? there's many roadmaps in a sow doc",
69
81
  // final_milestone_target: new Date(),
70
- // initial_proposal_status: strand.state.initialProposal.status,
71
- // initial_proposal_author: strand.state.initialProposal.author.name
82
+ initial_proposal_status: strand.state.initialProposal ? strand.state.initialProposal.status : null,
83
+ initial_proposal_author: strand.state.initialProposal ? strand.state.initialProposal.author.name : null
72
84
  })
73
85
  .onConflict((oc) => oc.column("workstream_phid").doNothing())
74
86
  .execute();
@@ -93,9 +105,11 @@ export class WorkstreamsProcessor extends RelationalDbProcessor {
93
105
  const updateData = {};
94
106
  if (input.sowId) {
95
107
  updateData.sow_phid = input.sowId;
108
+ updateData.initial_proposal_status = "DRAFT";
96
109
  }
97
110
  if (input.proposalAuthor) {
98
111
  updateData.initial_proposal_author = input.proposalAuthor.name;
112
+ updateData.initial_proposal_status = "DRAFT";
99
113
  }
100
114
  if (input.status) {
101
115
  updateData.initial_proposal_status = input.status;
@@ -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,GAAI,UAAU,YAAY,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CA8H3E,CAAC"}
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,GAAI,UAAU,YAAY,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAyI3E,CAAC"}
@@ -3,7 +3,7 @@ export const getResolvers = (subgraph) => {
3
3
  const reactor = subgraph.reactor;
4
4
  return {
5
5
  Query: {
6
- allNetworks: async () => {
6
+ allNetworks: async (_, args) => {
7
7
  const drives = await reactor.getDrives();
8
8
  // Step 1: Collect all network profile documents and builders documents with their drive IDs
9
9
  const networkDocsWithDriveId = [];
@@ -63,13 +63,13 @@ export const getResolvers = (subgraph) => {
63
63
  const state = doc.state.global;
64
64
  return {
65
65
  id: doc.header.id,
66
- name: state?.name || doc.header.id,
66
+ name: state?.name || doc.header.name,
67
67
  icon: state?.icon || "",
68
68
  description: state?.description || state?.slug || "",
69
69
  };
70
70
  };
71
71
  // Step 6: Map each network to its builders from the same drive
72
- return networkDocsWithDriveId.map(({ doc, driveId }) => {
72
+ const allNetworks = networkDocsWithDriveId.map(({ doc, driveId }) => {
73
73
  const state = doc.state.global;
74
74
  // Get the BuildersDocument from the same drive as the network
75
75
  const buildersDoc = driveIdToBuildersDoc.get(driveId);
@@ -84,6 +84,7 @@ export const getResolvers = (subgraph) => {
84
84
  documentType: doc.header.documentType,
85
85
  network: {
86
86
  name: state.name,
87
+ slug: state.name ? state.name.toLowerCase().trim().split(/\s+/).join("-") : null,
87
88
  icon: state.icon,
88
89
  darkThemeIcon: state.darkThemeIcon ?? null,
89
90
  logo: state.logo,
@@ -100,6 +101,12 @@ export const getResolvers = (subgraph) => {
100
101
  builders: builders,
101
102
  };
102
103
  });
104
+ // Step 7: Apply filter if provided
105
+ const networkSlug = args.filter?.networkSlug;
106
+ if (networkSlug) {
107
+ return allNetworks.filter((network) => network.network.slug === networkSlug);
108
+ }
109
+ return allNetworks;
103
110
  },
104
111
  },
105
112
  };
@@ -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,YA+CpB,CAAC"}
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,YAmDpB,CAAC"}
@@ -4,9 +4,12 @@ export const schema = gql `
4
4
  Subgraph definition
5
5
  """
6
6
  type Query {
7
- allNetworks: [AllNetworks!]!
7
+ allNetworks(filter: networkFilter): [AllNetworks!]!
8
8
  }
9
9
 
10
+ input networkFilter {
11
+ networkSlug: String
12
+ }
10
13
 
11
14
  type AllNetworks {
12
15
  id: PHID
@@ -17,6 +20,7 @@ export const schema = gql `
17
20
 
18
21
  type Network {
19
22
  name: String!
23
+ slug: String
20
24
  icon: String!
21
25
  darkThemeIcon: String!
22
26
  logo: String!
@@ -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;AAmC5D,eAAO,MAAM,YAAY,GAAI,UAAU,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAqdxE,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;AAwC5D,eAAO,MAAM,YAAY,GAAI,UAAU,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAmhBxE,CAAC"}
@@ -2,6 +2,7 @@ import {} from "@powerhousedao/reactor-api";
2
2
  import { WorkstreamsProcessor } from "../../processors/workstreams/index.js";
3
3
  import {} from "../../document-models/request-for-proposals/index.js";
4
4
  import {} from "../../document-models/workstream/index.js";
5
+ import { sql } from "kysely";
5
6
  export const getResolvers = (subgraph) => {
6
7
  const reactor = subgraph.reactor;
7
8
  const db = subgraph.relationalDb;
@@ -65,6 +66,34 @@ export const getResolvers = (subgraph) => {
65
66
  };
66
67
  }
67
68
  };
69
+ const loadNetworkProfile = async (networkId) => {
70
+ if (!networkId) {
71
+ return null;
72
+ }
73
+ try {
74
+ const networkDoc = await reactor.getDocument(networkId);
75
+ const state = networkDoc.state.global;
76
+ return {
77
+ name: state.name || "",
78
+ slug: state.name ? state.name.toLowerCase().trim().split(/\s+/).join("-") : null,
79
+ icon: state.icon || "",
80
+ darkThemeIcon: state.darkThemeIcon || "",
81
+ logo: state.logo || "",
82
+ darkThemeLogo: state.darkThemeLogo || "",
83
+ logoBig: state.logoBig || "",
84
+ website: state.website ?? null,
85
+ description: state.description || "",
86
+ category: state.category || [],
87
+ x: state.x ?? null,
88
+ github: state.github ?? null,
89
+ discord: state.discord ?? null,
90
+ youtube: state.youtube ?? null,
91
+ };
92
+ }
93
+ catch {
94
+ return null;
95
+ }
96
+ };
68
97
  const hydrateWorkstreamRow = async (row) => {
69
98
  try {
70
99
  const doc = await reactor.getDocument(row.workstream_phid);
@@ -81,7 +110,7 @@ export const getResolvers = (subgraph) => {
81
110
  status: p.status,
82
111
  author: p.author,
83
112
  }));
84
- const [topSowDoc, topPaymentTermsDoc, initialSowDoc, initialPaymentTermsDoc, altSowDocs, altPaymentDocs, rfpDetails,] = await Promise.all([
113
+ const [topSowDoc, topPaymentTermsDoc, initialSowDoc, initialPaymentTermsDoc, altSowDocs, altPaymentDocs, rfpDetails, networkInfo,] = await Promise.all([
85
114
  loadLinkedDocument(state.sow || row.sow_phid || null),
86
115
  loadLinkedDocument(state.paymentTerms || null),
87
116
  loadLinkedDocument(state.initialProposal?.sow || row.sow_phid || null),
@@ -89,6 +118,7 @@ export const getResolvers = (subgraph) => {
89
118
  Promise.all((state.alternativeProposals || []).map((p) => loadLinkedDocument(p.sow || null))),
90
119
  Promise.all((state.alternativeProposals || []).map((p) => loadLinkedDocument(p.paymentTerms || null))),
91
120
  loadRfpDetails(state.rfp || null),
121
+ loadNetworkProfile(state.client?.id || row.network_phid || null),
92
122
  ]);
93
123
  const client = state.client ??
94
124
  (row.network_phid
@@ -97,8 +127,10 @@ export const getResolvers = (subgraph) => {
97
127
  return {
98
128
  code: state.code || null,
99
129
  title: state.title || row.workstream_title || null,
130
+ slug: state.title ? state.title.toLowerCase().trim().split(/\s+/).join("-") : null,
100
131
  status: state.status || row.workstream_status || null,
101
132
  client,
133
+ network: networkInfo || {},
102
134
  rfp: rfpDetails,
103
135
  initialProposal: initialProposalBase
104
136
  ? {
@@ -118,13 +150,16 @@ export const getResolvers = (subgraph) => {
118
150
  };
119
151
  }
120
152
  catch {
153
+ const networkInfo = await loadNetworkProfile(row.network_phid || null);
121
154
  return {
122
155
  code: row.workstream_title || null,
123
156
  title: row.workstream_title || null,
157
+ slug: row.workstream_slug || null,
124
158
  status: row.workstream_status || null,
125
159
  client: row.network_phid
126
160
  ? { id: row.network_phid, name: row.network_slug, icon: null }
127
161
  : null,
162
+ network: networkInfo || {},
128
163
  rfp: null,
129
164
  initialProposal: null,
130
165
  alternativeProposals: [],
@@ -135,12 +170,22 @@ export const getResolvers = (subgraph) => {
135
170
  }
136
171
  };
137
172
  const applyWorkstreamFilters = (qb, filters, wantedSlug) => {
138
- if (filters.workstreamId) {
173
+ // Handle workstreamId and workstreamSlug (from WorkstreamFilter)
174
+ if ("workstreamId" in filters && filters.workstreamId) {
139
175
  qb = qb.where("workstream_phid", "=", filters.workstreamId);
140
176
  }
141
- else if (filters.workstreamSlug) {
177
+ else if ("workstreamSlug" in filters && filters.workstreamSlug) {
142
178
  qb = qb.where("workstream_slug", "=", filters.workstreamSlug);
143
179
  }
180
+ // Handle workstreamTitle filter (from WorkstreamsFilter)
181
+ if ("workstreamTitle" in filters && filters.workstreamTitle) {
182
+ // Use case-insensitive partial match for workstream title
183
+ // Filter out NULL values and do case-insensitive search
184
+ const searchPattern = `%${filters.workstreamTitle.toLowerCase()}%`;
185
+ qb = qb
186
+ .where("workstream_title", "is not", null)
187
+ .where((eb) => eb(sql `LOWER(workstream_title)`, "like", searchPattern));
188
+ }
144
189
  if (filters.networkId) {
145
190
  qb = qb.where("network_phid", "=", filters.networkId);
146
191
  }
@@ -150,6 +195,15 @@ export const getResolvers = (subgraph) => {
150
195
  else if (filters.networkName && wantedSlug) {
151
196
  qb = qb.where("network_slug", "=", wantedSlug);
152
197
  }
198
+ else if ("networkNames" in filters && filters.networkNames) {
199
+ // Handle networkNames filter (from WorkstreamsFilter)
200
+ const networkSlugs = filters.networkNames
201
+ .filter((name) => Boolean(name))
202
+ .map((name) => deriveSlug(name));
203
+ if (networkSlugs.length > 0) {
204
+ qb = qb.where("network_slug", "in", networkSlugs);
205
+ }
206
+ }
153
207
  const statuses = (filters.workstreamStatuses || []).filter((status) => Boolean(status));
154
208
  if (statuses.length > 0) {
155
209
  qb = qb.where("workstream_status", "in", statuses);
@@ -211,16 +265,20 @@ export const getResolvers = (subgraph) => {
211
265
  const candidateDrives = await getCandidateDrives();
212
266
  const wantedSlug = filters.networkSlug ||
213
267
  (filters.networkName ? deriveSlug(filters.networkName) : undefined);
214
- let resolved = null;
268
+ let resolved = [];
215
269
  for (const driveId of candidateDrives) {
216
270
  let qb = WorkstreamsProcessor.query(driveId, db)
217
271
  .selectFrom("workstreams")
218
272
  .selectAll();
219
273
  qb = applyWorkstreamFilters(qb, filters, wantedSlug);
220
- const row = await qb.executeTakeFirst();
221
- if (!row)
274
+ const rows = await qb.execute();
275
+ if (rows.length === 0) {
222
276
  continue;
223
- resolved = await hydrateWorkstreamRow(row);
277
+ }
278
+ for (const row of rows) {
279
+ const hydrated = await hydrateWorkstreamRow(row);
280
+ resolved.push(hydrated);
281
+ }
224
282
  break;
225
283
  }
226
284
  return resolved;
@@ -232,6 +290,8 @@ export const getResolvers = (subgraph) => {
232
290
  const hasFilters = filters.networkId ||
233
291
  filters.networkSlug ||
234
292
  filters.networkName ||
293
+ (filters.networkNames && filters.networkNames.length > 0) ||
294
+ filters.workstreamTitle ||
235
295
  filters.workstreamStatus ||
236
296
  (filters.workstreamStatuses &&
237
297
  filters.workstreamStatuses.length > 0);
@@ -244,14 +304,7 @@ export const getResolvers = (subgraph) => {
244
304
  .selectAll();
245
305
  // Only apply filters if any are provided
246
306
  if (hasFilters) {
247
- const filterArgs = {
248
- networkId: filters.networkId,
249
- networkSlug: filters.networkSlug,
250
- networkName: filters.networkName,
251
- workstreamStatus: filters.workstreamStatus,
252
- workstreamStatuses: filters.workstreamStatuses,
253
- };
254
- qb = applyWorkstreamFilters(qb, filterArgs, wantedSlug);
307
+ qb = applyWorkstreamFilters(qb, filters, wantedSlug);
255
308
  }
256
309
  const rows = await qb.execute();
257
310
  if (rows.length === 0) {
@@ -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,YAoUpB,CAAC"}
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,YAiWpB,CAAC"}
@@ -5,7 +5,7 @@ export const schema = gql `
5
5
  """
6
6
  type Query {
7
7
  processorWorkstreams: [ProcessorWorkstream!]!
8
- workstream(filter: WorkstreamFilter!): FullQueryWorkstream
8
+ workstream(filter: WorkstreamFilter!): [FullQueryWorkstream!]!
9
9
  workstreams(filter: WorkstreamsFilter): [FullQueryWorkstream!]!
10
10
  rfpByWorkstream(filter: WorkstreamFilter!): [WorkstreamRfp!]!
11
11
  scopeOfWorkByNetworkOrStatus(filter: scopeOfWorkByNetworkOrStatusFilter!): [SOW_ScopeOfWorkState!]!
@@ -72,6 +72,8 @@ export const schema = gql `
72
72
  networkId: PHID
73
73
  networkSlug: String
74
74
  networkName: String
75
+ networkNames: [String!]
76
+ workstreamTitle: String
75
77
  workstreamStatus: WorkstreamStatus
76
78
  workstreamStatuses: [WorkstreamStatus!]
77
79
  }
@@ -98,8 +100,10 @@ export const schema = gql `
98
100
  type FullQueryWorkstream {
99
101
  code: String
100
102
  title: String
103
+ slug: String
101
104
  status: WorkstreamStatus
102
105
  client: ClientInfo
106
+ network: Network
103
107
  rfp: RFP
104
108
  initialProposal: FullProposal
105
109
  alternativeProposals: [FullProposal!]!
@@ -108,6 +112,31 @@ export const schema = gql `
108
112
  paymentRequests: [PHID!]!
109
113
  }
110
114
 
115
+ type Network {
116
+ name: String!
117
+ slug: String
118
+ icon: String!
119
+ darkThemeIcon: String!
120
+ logo: String!
121
+ darkThemeLogo: String!
122
+ logoBig: String!
123
+ website: String
124
+ description: String!
125
+ category: [NetworkCategory!]!
126
+ x: String
127
+ github: String
128
+ discord: String
129
+ youtube: String
130
+ }
131
+
132
+ enum NetworkCategory {
133
+ DEFI
134
+ OSS
135
+ CRYPTO
136
+ NGO
137
+ CHARITY
138
+ }
139
+
111
140
  type WorkstreamRfp {
112
141
  code: String
113
142
  title: String
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.46",
4
+ "version": "0.0.47",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "files": [