@powerhousedao/service-offering 1.0.0-dev.11 → 1.0.0-dev.12
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/document-models/subscription-instance/v1/src/reducers/metrics.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/src/reducers/metrics.js +7 -6
- package/dist/document-models/subscription-instance/v1/src/reducers/utils.d.ts +7 -0
- package/dist/document-models/subscription-instance/v1/src/reducers/utils.d.ts.map +1 -0
- package/dist/document-models/subscription-instance/v1/src/reducers/utils.js +15 -0
- package/dist/document-models/subscription-instance/v1/tests/metrics.test.js +88 -1
- package/dist/subgraphs/resources-services/resolvers.d.ts.map +1 -1
- package/dist/subgraphs/resources-services/resolvers.js +10 -3
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../../../../document-models/subscription-instance/v1/src/reducers/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,0EAA0E,CAAC;
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../../../../document-models/subscription-instance/v1/src/reducers/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,0EAA0E,CAAC;AAgBtI,eAAO,MAAM,qCAAqC,EAAE,qCAsHjD,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { findService } from "./utils.js";
|
|
1
2
|
import { AddServiceMetricServiceNotFoundError, UpdateMetricServiceNotFoundError, UpdateMetricNotFoundError, UpdateMetricUsageServiceNotFoundError, UpdateMetricUsageNotFoundError, RemoveServiceMetricServiceNotFoundError, RemoveServiceMetricNotFoundError, IncrementMetricUsageServiceNotFoundError, IncrementMetricUsageNotFoundError, DecrementMetricUsageServiceNotFoundError, DecrementMetricUsageNotFoundError, } from "../../gen/metrics/error.js";
|
|
2
3
|
export const subscriptionInstanceMetricsOperations = {
|
|
3
4
|
addServiceMetricOperation(state, action) {
|
|
4
|
-
const svc = state
|
|
5
|
+
const svc = findService(state, action.input.serviceId);
|
|
5
6
|
if (!svc) {
|
|
6
7
|
throw new AddServiceMetricServiceNotFoundError(`Service with ID ${action.input.serviceId} not found`);
|
|
7
8
|
}
|
|
@@ -30,7 +31,7 @@ export const subscriptionInstanceMetricsOperations = {
|
|
|
30
31
|
});
|
|
31
32
|
},
|
|
32
33
|
updateMetricOperation(state, action) {
|
|
33
|
-
const svc = state
|
|
34
|
+
const svc = findService(state, action.input.serviceId);
|
|
34
35
|
if (!svc) {
|
|
35
36
|
throw new UpdateMetricServiceNotFoundError(`Service with ID ${action.input.serviceId} not found`);
|
|
36
37
|
}
|
|
@@ -50,7 +51,7 @@ export const subscriptionInstanceMetricsOperations = {
|
|
|
50
51
|
metric.nextUsageReset = action.input.nextUsageReset || null;
|
|
51
52
|
},
|
|
52
53
|
updateMetricUsageOperation(state, action) {
|
|
53
|
-
const svc = state
|
|
54
|
+
const svc = findService(state, action.input.serviceId);
|
|
54
55
|
if (!svc) {
|
|
55
56
|
throw new UpdateMetricUsageServiceNotFoundError(`Service with ID ${action.input.serviceId} not found`);
|
|
56
57
|
}
|
|
@@ -61,7 +62,7 @@ export const subscriptionInstanceMetricsOperations = {
|
|
|
61
62
|
metric.currentUsage = action.input.currentUsage;
|
|
62
63
|
},
|
|
63
64
|
removeServiceMetricOperation(state, action) {
|
|
64
|
-
const svc = state
|
|
65
|
+
const svc = findService(state, action.input.serviceId);
|
|
65
66
|
if (!svc) {
|
|
66
67
|
throw new RemoveServiceMetricServiceNotFoundError(`Service with ID ${action.input.serviceId} not found`);
|
|
67
68
|
}
|
|
@@ -72,7 +73,7 @@ export const subscriptionInstanceMetricsOperations = {
|
|
|
72
73
|
svc.metrics.splice(index, 1);
|
|
73
74
|
},
|
|
74
75
|
incrementMetricUsageOperation(state, action) {
|
|
75
|
-
const svc = state
|
|
76
|
+
const svc = findService(state, action.input.serviceId);
|
|
76
77
|
if (!svc) {
|
|
77
78
|
throw new IncrementMetricUsageServiceNotFoundError(`Service with ID ${action.input.serviceId} not found`);
|
|
78
79
|
}
|
|
@@ -83,7 +84,7 @@ export const subscriptionInstanceMetricsOperations = {
|
|
|
83
84
|
metric.currentUsage += action.input.incrementBy;
|
|
84
85
|
},
|
|
85
86
|
decrementMetricUsageOperation(state, action) {
|
|
86
|
-
const svc = state
|
|
87
|
+
const svc = findService(state, action.input.serviceId);
|
|
87
88
|
if (!svc) {
|
|
88
89
|
throw new DecrementMetricUsageServiceNotFoundError(`Service with ID ${action.input.serviceId} not found`);
|
|
89
90
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SubscriptionInstanceState, Service } from "../../gen/schema/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Finds a service by ID across both top-level standalone services
|
|
4
|
+
* and services nested inside service groups.
|
|
5
|
+
*/
|
|
6
|
+
export declare function findService(state: SubscriptionInstanceState, serviceId: string): Service | undefined;
|
|
7
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../../document-models/subscription-instance/v1/src/reducers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,OAAO,EACR,MAAM,2BAA2B,CAAC;AAEnC;;;GAGG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,yBAAyB,EAChC,SAAS,EAAE,MAAM,GAChB,OAAO,GAAG,SAAS,CAQrB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds a service by ID across both top-level standalone services
|
|
3
|
+
* and services nested inside service groups.
|
|
4
|
+
*/
|
|
5
|
+
export function findService(state, serviceId) {
|
|
6
|
+
const standalone = state.services.find((s) => s.id === serviceId);
|
|
7
|
+
if (standalone)
|
|
8
|
+
return standalone;
|
|
9
|
+
for (const group of state.serviceGroups) {
|
|
10
|
+
const grouped = group.services.find((s) => s.id === serviceId);
|
|
11
|
+
if (grouped)
|
|
12
|
+
return grouped;
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
import { generateMock } from "@powerhousedao/common/utils";
|
|
2
|
+
import { generateId } from "document-model/core";
|
|
2
3
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { reducer, utils, isSubscriptionInstanceDocument, addServiceMetric, updateMetric, updateMetricUsage, removeServiceMetric, incrementMetricUsage, decrementMetricUsage, AddServiceMetricInputSchema, UpdateMetricInputSchema, UpdateMetricUsageInputSchema, RemoveServiceMetricInputSchema, IncrementMetricUsageInputSchema, DecrementMetricUsageInputSchema, } from "@powerhousedao/service-offering/document-models/subscription-instance/v1";
|
|
4
|
+
import { reducer, utils, isSubscriptionInstanceDocument, initializeSubscription, addServiceMetric, updateMetric, updateMetricUsage, removeServiceMetric, incrementMetricUsage, decrementMetricUsage, AddServiceMetricInputSchema, UpdateMetricInputSchema, UpdateMetricUsageInputSchema, RemoveServiceMetricInputSchema, IncrementMetricUsageInputSchema, DecrementMetricUsageInputSchema, } from "@powerhousedao/service-offering/document-models/subscription-instance/v1";
|
|
5
|
+
/** Creates a document with a service group containing a service with a metric. */
|
|
6
|
+
function createDocWithServiceGroup() {
|
|
7
|
+
const serviceId = generateId();
|
|
8
|
+
const metricId = generateId();
|
|
9
|
+
const groupId = generateId();
|
|
10
|
+
let doc = utils.createDocument();
|
|
11
|
+
doc = reducer(doc, initializeSubscription({
|
|
12
|
+
createdAt: new Date().toISOString(),
|
|
13
|
+
customerName: "Test",
|
|
14
|
+
selectedBillingCycle: "MONTHLY",
|
|
15
|
+
globalCurrency: "USD",
|
|
16
|
+
autoRenew: true,
|
|
17
|
+
serviceGroups: [
|
|
18
|
+
{
|
|
19
|
+
id: groupId,
|
|
20
|
+
name: "Test Group",
|
|
21
|
+
optional: false,
|
|
22
|
+
services: [
|
|
23
|
+
{
|
|
24
|
+
id: serviceId,
|
|
25
|
+
name: "Test Service",
|
|
26
|
+
metrics: [
|
|
27
|
+
{
|
|
28
|
+
id: metricId,
|
|
29
|
+
name: "API Calls",
|
|
30
|
+
unitName: "calls",
|
|
31
|
+
currentUsage: 100,
|
|
32
|
+
freeLimit: 50,
|
|
33
|
+
paidLimit: 200,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
}));
|
|
41
|
+
return { doc, serviceId, metricId, groupId };
|
|
42
|
+
}
|
|
4
43
|
describe("MetricsOperations", () => {
|
|
5
44
|
it("should handle addServiceMetric operation", () => {
|
|
6
45
|
const document = utils.createDocument();
|
|
@@ -62,4 +101,52 @@ describe("MetricsOperations", () => {
|
|
|
62
101
|
expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
|
|
63
102
|
expect(updatedDocument.operations.global[0].index).toEqual(0);
|
|
64
103
|
});
|
|
104
|
+
describe("service group metric operations", () => {
|
|
105
|
+
it("should increment metric usage for a service inside a service group", () => {
|
|
106
|
+
const { doc, serviceId, metricId } = createDocWithServiceGroup();
|
|
107
|
+
const updatedDoc = reducer(doc, incrementMetricUsage({
|
|
108
|
+
serviceId,
|
|
109
|
+
metricId,
|
|
110
|
+
incrementBy: 10,
|
|
111
|
+
currentTime: new Date().toISOString(),
|
|
112
|
+
}));
|
|
113
|
+
const metric = updatedDoc.state.global.serviceGroups[0].services[0].metrics[0];
|
|
114
|
+
expect(metric.currentUsage).toBe(110);
|
|
115
|
+
expect(updatedDoc.operations.global[1].error).toBeUndefined();
|
|
116
|
+
});
|
|
117
|
+
it("should decrement metric usage for a service inside a service group", () => {
|
|
118
|
+
const { doc, serviceId, metricId } = createDocWithServiceGroup();
|
|
119
|
+
const updatedDoc = reducer(doc, decrementMetricUsage({
|
|
120
|
+
serviceId,
|
|
121
|
+
metricId,
|
|
122
|
+
decrementBy: 25,
|
|
123
|
+
currentTime: new Date().toISOString(),
|
|
124
|
+
}));
|
|
125
|
+
const metric = updatedDoc.state.global.serviceGroups[0].services[0].metrics[0];
|
|
126
|
+
expect(metric.currentUsage).toBe(75);
|
|
127
|
+
expect(updatedDoc.operations.global[1].error).toBeUndefined();
|
|
128
|
+
});
|
|
129
|
+
it("should set metric usage for a service inside a service group", () => {
|
|
130
|
+
const { doc, serviceId, metricId } = createDocWithServiceGroup();
|
|
131
|
+
const updatedDoc = reducer(doc, updateMetricUsage({
|
|
132
|
+
serviceId,
|
|
133
|
+
metricId,
|
|
134
|
+
currentUsage: 999,
|
|
135
|
+
currentTime: new Date().toISOString(),
|
|
136
|
+
}));
|
|
137
|
+
const metric = updatedDoc.state.global.serviceGroups[0].services[0].metrics[0];
|
|
138
|
+
expect(metric.currentUsage).toBe(999);
|
|
139
|
+
expect(updatedDoc.operations.global[1].error).toBeUndefined();
|
|
140
|
+
});
|
|
141
|
+
it("should return error for non-existent service in service group", () => {
|
|
142
|
+
const { doc, metricId } = createDocWithServiceGroup();
|
|
143
|
+
const updatedDoc = reducer(doc, incrementMetricUsage({
|
|
144
|
+
serviceId: "non-existent-id",
|
|
145
|
+
metricId,
|
|
146
|
+
incrementBy: 1,
|
|
147
|
+
currentTime: new Date().toISOString(),
|
|
148
|
+
}));
|
|
149
|
+
expect(updatedDoc.operations.global[1].error).toBe("Service with ID non-existent-id not found");
|
|
150
|
+
});
|
|
151
|
+
});
|
|
65
152
|
});
|
|
@@ -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,
|
|
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,CA6gBxB,CAAC"}
|
|
@@ -322,25 +322,32 @@ export const getResolvers = (subgraph) => {
|
|
|
322
322
|
}),
|
|
323
323
|
]);
|
|
324
324
|
}
|
|
325
|
+
// create a team folder inside "Service Subscriptions" for this team's docs
|
|
326
|
+
const teamFolderId = generateId();
|
|
325
327
|
// add reactor-level relationships so Connect syncs the child documents
|
|
326
328
|
// (createEmpty guarantees CREATE_DOCUMENT is persisted before this runs)
|
|
327
329
|
await reactorClient.addChildren(operatorDrive.header.id, [
|
|
328
330
|
resourceInstanceDoc.header.id,
|
|
329
331
|
subscriptionInstanceDoc.header.id,
|
|
330
332
|
]);
|
|
331
|
-
// add file references to operator drive
|
|
333
|
+
// add team folder and file references to operator drive
|
|
332
334
|
await reactorClient.execute(operatorDrive.header.id, "main", [
|
|
335
|
+
addFolder({
|
|
336
|
+
id: teamFolderId,
|
|
337
|
+
name: teamName,
|
|
338
|
+
parentFolder: serviceSubscriptionsFolderId,
|
|
339
|
+
}),
|
|
333
340
|
addFile({
|
|
334
341
|
documentType: "powerhouse/resource-instance",
|
|
335
342
|
id: resourceInstanceDoc.header.id,
|
|
336
343
|
name: `${parsedTeamName} Resource Instance`,
|
|
337
|
-
parentFolder:
|
|
344
|
+
parentFolder: teamFolderId,
|
|
338
345
|
}),
|
|
339
346
|
addFile({
|
|
340
347
|
documentType: "powerhouse/subscription-instance",
|
|
341
348
|
id: subscriptionInstanceDoc.header.id,
|
|
342
349
|
name: `${parsedTeamName} Subscription Instance`,
|
|
343
|
-
parentFolder:
|
|
350
|
+
parentFolder: teamFolderId,
|
|
344
351
|
}),
|
|
345
352
|
]);
|
|
346
353
|
// populate documents after all files are added to both drives
|