@uniforge/portal 0.1.0-alpha.2
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/auth/index.d.cts +104 -0
- package/dist/auth/index.d.ts +104 -0
- package/dist/auth/index.js +194 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +160 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/dashboard/index.d.cts +76 -0
- package/dist/dashboard/index.d.ts +76 -0
- package/dist/dashboard/index.js +158 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/index.mjs +129 -0
- package/dist/dashboard/index.mjs.map +1 -0
- package/dist/feature-flags/index.d.cts +75 -0
- package/dist/feature-flags/index.d.ts +75 -0
- package/dist/feature-flags/index.js +111 -0
- package/dist/feature-flags/index.js.map +1 -0
- package/dist/feature-flags/index.mjs +83 -0
- package/dist/feature-flags/index.mjs.map +1 -0
- package/dist/index.d.cts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -0
- package/dist/merchants/index.d.cts +100 -0
- package/dist/merchants/index.d.ts +100 -0
- package/dist/merchants/index.js +120 -0
- package/dist/merchants/index.js.map +1 -0
- package/dist/merchants/index.mjs +90 -0
- package/dist/merchants/index.mjs.map +1 -0
- package/dist/metrics/index.d.cts +83 -0
- package/dist/metrics/index.d.ts +83 -0
- package/dist/metrics/index.js +112 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/index.mjs +83 -0
- package/dist/metrics/index.mjs.map +1 -0
- package/dist/tickets/index.d.cts +96 -0
- package/dist/tickets/index.d.ts +96 -0
- package/dist/tickets/index.js +102 -0
- package/dist/tickets/index.js.map +1 -0
- package/dist/tickets/index.mjs +73 -0
- package/dist/tickets/index.mjs.map +1 -0
- package/dist/webhook-logs/index.d.cts +88 -0
- package/dist/webhook-logs/index.d.ts +88 -0
- package/dist/webhook-logs/index.js +111 -0
- package/dist/webhook-logs/index.js.map +1 -0
- package/dist/webhook-logs/index.mjs +82 -0
- package/dist/webhook-logs/index.mjs.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API metrics types for the developer portal.
|
|
3
|
+
*/
|
|
4
|
+
interface ApiMetricEntry {
|
|
5
|
+
id: string;
|
|
6
|
+
endpoint: string;
|
|
7
|
+
method: string;
|
|
8
|
+
statusCode: number;
|
|
9
|
+
responseTimeMs: number;
|
|
10
|
+
timestamp: Date;
|
|
11
|
+
shopDomain?: string;
|
|
12
|
+
errorMessage?: string;
|
|
13
|
+
}
|
|
14
|
+
interface MetricsTimeRange {
|
|
15
|
+
start: Date;
|
|
16
|
+
end: Date;
|
|
17
|
+
}
|
|
18
|
+
interface MetricsSummary {
|
|
19
|
+
totalRequests: number;
|
|
20
|
+
avgResponseTimeMs: number;
|
|
21
|
+
p95ResponseTimeMs: number;
|
|
22
|
+
p99ResponseTimeMs: number;
|
|
23
|
+
errorRate: number;
|
|
24
|
+
successRate: number;
|
|
25
|
+
timeRange: MetricsTimeRange;
|
|
26
|
+
}
|
|
27
|
+
interface EndpointMetrics {
|
|
28
|
+
endpoint: string;
|
|
29
|
+
method: string;
|
|
30
|
+
totalRequests: number;
|
|
31
|
+
avgResponseTimeMs: number;
|
|
32
|
+
errorCount: number;
|
|
33
|
+
errorRate: number;
|
|
34
|
+
}
|
|
35
|
+
interface ErrorSummary {
|
|
36
|
+
errorMessage: string;
|
|
37
|
+
count: number;
|
|
38
|
+
lastOccurrence: Date;
|
|
39
|
+
endpoints: string[];
|
|
40
|
+
}
|
|
41
|
+
interface MetricsFilter {
|
|
42
|
+
endpoint?: string;
|
|
43
|
+
method?: string;
|
|
44
|
+
statusCode?: number;
|
|
45
|
+
shopDomain?: string;
|
|
46
|
+
startDate?: Date;
|
|
47
|
+
endDate?: Date;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface MetricsDataSource {
|
|
51
|
+
recordMetric(entry: Omit<ApiMetricEntry, 'id'>): Promise<ApiMetricEntry>;
|
|
52
|
+
getMetrics(filter?: MetricsFilter): Promise<ApiMetricEntry[]>;
|
|
53
|
+
getMetricsSummary(timeRange: MetricsTimeRange): Promise<MetricsSummary>;
|
|
54
|
+
getEndpointMetrics(timeRange: MetricsTimeRange): Promise<EndpointMetrics[]>;
|
|
55
|
+
getErrorSummary(timeRange: MetricsTimeRange, limit?: number): Promise<ErrorSummary[]>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
declare class MetricsCollector {
|
|
59
|
+
private readonly dataSource;
|
|
60
|
+
constructor(dataSource: MetricsDataSource);
|
|
61
|
+
record(entry: Omit<ApiMetricEntry, 'id'>): Promise<ApiMetricEntry>;
|
|
62
|
+
recordBatch(entries: Array<Omit<ApiMetricEntry, 'id'>>): Promise<ApiMetricEntry[]>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
declare class MetricsQueryService {
|
|
66
|
+
private readonly dataSource;
|
|
67
|
+
constructor(dataSource: MetricsDataSource);
|
|
68
|
+
getSummary(timeRange?: MetricsTimeRange): Promise<MetricsSummary>;
|
|
69
|
+
getEndpointBreakdown(timeRange?: MetricsTimeRange): Promise<EndpointMetrics[]>;
|
|
70
|
+
getTopErrors(timeRange?: MetricsTimeRange, limit?: number): Promise<ErrorSummary[]>;
|
|
71
|
+
getMetricsByFilter(filter: MetricsFilter): Promise<ApiMetricEntry[]>;
|
|
72
|
+
private defaultTimeRange;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
declare class ErrorTracker {
|
|
76
|
+
private readonly dataSource;
|
|
77
|
+
constructor(dataSource: MetricsDataSource);
|
|
78
|
+
trackError(endpoint: string, method: string, statusCode: number, errorMessage: string, shopDomain?: string): Promise<ApiMetricEntry>;
|
|
79
|
+
getRecentErrors(limit?: number): Promise<ApiMetricEntry[]>;
|
|
80
|
+
getErrorsByEndpoint(endpoint: string, limit?: number): Promise<ApiMetricEntry[]>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { type ApiMetricEntry, type EndpointMetrics, type ErrorSummary, ErrorTracker, MetricsCollector, type MetricsDataSource, type MetricsFilter, MetricsQueryService, type MetricsSummary, type MetricsTimeRange };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API metrics types for the developer portal.
|
|
3
|
+
*/
|
|
4
|
+
interface ApiMetricEntry {
|
|
5
|
+
id: string;
|
|
6
|
+
endpoint: string;
|
|
7
|
+
method: string;
|
|
8
|
+
statusCode: number;
|
|
9
|
+
responseTimeMs: number;
|
|
10
|
+
timestamp: Date;
|
|
11
|
+
shopDomain?: string;
|
|
12
|
+
errorMessage?: string;
|
|
13
|
+
}
|
|
14
|
+
interface MetricsTimeRange {
|
|
15
|
+
start: Date;
|
|
16
|
+
end: Date;
|
|
17
|
+
}
|
|
18
|
+
interface MetricsSummary {
|
|
19
|
+
totalRequests: number;
|
|
20
|
+
avgResponseTimeMs: number;
|
|
21
|
+
p95ResponseTimeMs: number;
|
|
22
|
+
p99ResponseTimeMs: number;
|
|
23
|
+
errorRate: number;
|
|
24
|
+
successRate: number;
|
|
25
|
+
timeRange: MetricsTimeRange;
|
|
26
|
+
}
|
|
27
|
+
interface EndpointMetrics {
|
|
28
|
+
endpoint: string;
|
|
29
|
+
method: string;
|
|
30
|
+
totalRequests: number;
|
|
31
|
+
avgResponseTimeMs: number;
|
|
32
|
+
errorCount: number;
|
|
33
|
+
errorRate: number;
|
|
34
|
+
}
|
|
35
|
+
interface ErrorSummary {
|
|
36
|
+
errorMessage: string;
|
|
37
|
+
count: number;
|
|
38
|
+
lastOccurrence: Date;
|
|
39
|
+
endpoints: string[];
|
|
40
|
+
}
|
|
41
|
+
interface MetricsFilter {
|
|
42
|
+
endpoint?: string;
|
|
43
|
+
method?: string;
|
|
44
|
+
statusCode?: number;
|
|
45
|
+
shopDomain?: string;
|
|
46
|
+
startDate?: Date;
|
|
47
|
+
endDate?: Date;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface MetricsDataSource {
|
|
51
|
+
recordMetric(entry: Omit<ApiMetricEntry, 'id'>): Promise<ApiMetricEntry>;
|
|
52
|
+
getMetrics(filter?: MetricsFilter): Promise<ApiMetricEntry[]>;
|
|
53
|
+
getMetricsSummary(timeRange: MetricsTimeRange): Promise<MetricsSummary>;
|
|
54
|
+
getEndpointMetrics(timeRange: MetricsTimeRange): Promise<EndpointMetrics[]>;
|
|
55
|
+
getErrorSummary(timeRange: MetricsTimeRange, limit?: number): Promise<ErrorSummary[]>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
declare class MetricsCollector {
|
|
59
|
+
private readonly dataSource;
|
|
60
|
+
constructor(dataSource: MetricsDataSource);
|
|
61
|
+
record(entry: Omit<ApiMetricEntry, 'id'>): Promise<ApiMetricEntry>;
|
|
62
|
+
recordBatch(entries: Array<Omit<ApiMetricEntry, 'id'>>): Promise<ApiMetricEntry[]>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
declare class MetricsQueryService {
|
|
66
|
+
private readonly dataSource;
|
|
67
|
+
constructor(dataSource: MetricsDataSource);
|
|
68
|
+
getSummary(timeRange?: MetricsTimeRange): Promise<MetricsSummary>;
|
|
69
|
+
getEndpointBreakdown(timeRange?: MetricsTimeRange): Promise<EndpointMetrics[]>;
|
|
70
|
+
getTopErrors(timeRange?: MetricsTimeRange, limit?: number): Promise<ErrorSummary[]>;
|
|
71
|
+
getMetricsByFilter(filter: MetricsFilter): Promise<ApiMetricEntry[]>;
|
|
72
|
+
private defaultTimeRange;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
declare class ErrorTracker {
|
|
76
|
+
private readonly dataSource;
|
|
77
|
+
constructor(dataSource: MetricsDataSource);
|
|
78
|
+
trackError(endpoint: string, method: string, statusCode: number, errorMessage: string, shopDomain?: string): Promise<ApiMetricEntry>;
|
|
79
|
+
getRecentErrors(limit?: number): Promise<ApiMetricEntry[]>;
|
|
80
|
+
getErrorsByEndpoint(endpoint: string, limit?: number): Promise<ApiMetricEntry[]>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { type ApiMetricEntry, type EndpointMetrics, type ErrorSummary, ErrorTracker, MetricsCollector, type MetricsDataSource, type MetricsFilter, MetricsQueryService, type MetricsSummary, type MetricsTimeRange };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/metrics/index.ts
|
|
21
|
+
var metrics_exports = {};
|
|
22
|
+
__export(metrics_exports, {
|
|
23
|
+
ErrorTracker: () => ErrorTracker,
|
|
24
|
+
MetricsCollector: () => MetricsCollector,
|
|
25
|
+
MetricsQueryService: () => MetricsQueryService
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(metrics_exports);
|
|
28
|
+
|
|
29
|
+
// src/metrics/metrics-collector.ts
|
|
30
|
+
var MetricsCollector = class {
|
|
31
|
+
constructor(dataSource) {
|
|
32
|
+
this.dataSource = dataSource;
|
|
33
|
+
}
|
|
34
|
+
async record(entry) {
|
|
35
|
+
return this.dataSource.recordMetric(entry);
|
|
36
|
+
}
|
|
37
|
+
async recordBatch(entries) {
|
|
38
|
+
const results = await Promise.all(
|
|
39
|
+
entries.map((entry) => this.dataSource.recordMetric(entry))
|
|
40
|
+
);
|
|
41
|
+
return results;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// src/metrics/metrics-query-service.ts
|
|
46
|
+
var MetricsQueryService = class {
|
|
47
|
+
constructor(dataSource) {
|
|
48
|
+
this.dataSource = dataSource;
|
|
49
|
+
}
|
|
50
|
+
async getSummary(timeRange) {
|
|
51
|
+
const range = timeRange ?? this.defaultTimeRange();
|
|
52
|
+
return this.dataSource.getMetricsSummary(range);
|
|
53
|
+
}
|
|
54
|
+
async getEndpointBreakdown(timeRange) {
|
|
55
|
+
const range = timeRange ?? this.defaultTimeRange();
|
|
56
|
+
return this.dataSource.getEndpointMetrics(range);
|
|
57
|
+
}
|
|
58
|
+
async getTopErrors(timeRange, limit) {
|
|
59
|
+
const range = timeRange ?? this.defaultTimeRange();
|
|
60
|
+
return this.dataSource.getErrorSummary(range, limit);
|
|
61
|
+
}
|
|
62
|
+
async getMetricsByFilter(filter) {
|
|
63
|
+
return this.dataSource.getMetrics(filter);
|
|
64
|
+
}
|
|
65
|
+
defaultTimeRange() {
|
|
66
|
+
const end = /* @__PURE__ */ new Date();
|
|
67
|
+
const start = new Date(end.getTime() - 24 * 60 * 60 * 1e3);
|
|
68
|
+
return { start, end };
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/metrics/error-tracker.ts
|
|
73
|
+
var ErrorTracker = class {
|
|
74
|
+
constructor(dataSource) {
|
|
75
|
+
this.dataSource = dataSource;
|
|
76
|
+
}
|
|
77
|
+
async trackError(endpoint, method, statusCode, errorMessage, shopDomain) {
|
|
78
|
+
const entry = {
|
|
79
|
+
endpoint,
|
|
80
|
+
method,
|
|
81
|
+
statusCode,
|
|
82
|
+
responseTimeMs: 0,
|
|
83
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
84
|
+
errorMessage,
|
|
85
|
+
...shopDomain !== void 0 ? { shopDomain } : {}
|
|
86
|
+
};
|
|
87
|
+
return this.dataSource.recordMetric(entry);
|
|
88
|
+
}
|
|
89
|
+
async getRecentErrors(limit) {
|
|
90
|
+
const entries = await this.dataSource.getMetrics({});
|
|
91
|
+
const sorted = entries.filter((e) => e.statusCode >= 400).sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
92
|
+
if (limit !== void 0) {
|
|
93
|
+
return sorted.slice(0, limit);
|
|
94
|
+
}
|
|
95
|
+
return sorted;
|
|
96
|
+
}
|
|
97
|
+
async getErrorsByEndpoint(endpoint, limit) {
|
|
98
|
+
const entries = await this.dataSource.getMetrics({ endpoint });
|
|
99
|
+
const errors = entries.filter((e) => e.statusCode >= 400).sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
100
|
+
if (limit !== void 0) {
|
|
101
|
+
return errors.slice(0, limit);
|
|
102
|
+
}
|
|
103
|
+
return errors;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
107
|
+
0 && (module.exports = {
|
|
108
|
+
ErrorTracker,
|
|
109
|
+
MetricsCollector,
|
|
110
|
+
MetricsQueryService
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/metrics/index.ts","../../src/metrics/metrics-collector.ts","../../src/metrics/metrics-query-service.ts","../../src/metrics/error-tracker.ts"],"sourcesContent":["export type {\n ApiMetricEntry,\n MetricsSummary,\n MetricsTimeRange,\n EndpointMetrics,\n ErrorSummary,\n MetricsFilter,\n} from './types.js';\n\nexport type { MetricsDataSource } from './metrics-data-source.js';\nexport { MetricsCollector } from './metrics-collector.js';\nexport { MetricsQueryService } from './metrics-query-service.js';\nexport { ErrorTracker } from './error-tracker.js';\n","import type { MetricsDataSource } from './metrics-data-source.js';\nimport type { ApiMetricEntry } from './types.js';\n\nexport class MetricsCollector {\n constructor(private readonly dataSource: MetricsDataSource) {}\n\n async record(\n entry: Omit<ApiMetricEntry, 'id'>,\n ): Promise<ApiMetricEntry> {\n return this.dataSource.recordMetric(entry);\n }\n\n async recordBatch(\n entries: Array<Omit<ApiMetricEntry, 'id'>>,\n ): Promise<ApiMetricEntry[]> {\n const results = await Promise.all(\n entries.map((entry) => this.dataSource.recordMetric(entry)),\n );\n return results;\n }\n}\n","import type { MetricsDataSource } from './metrics-data-source.js';\nimport type {\n ApiMetricEntry,\n EndpointMetrics,\n ErrorSummary,\n MetricsFilter,\n MetricsSummary,\n MetricsTimeRange,\n} from './types.js';\n\nexport class MetricsQueryService {\n constructor(private readonly dataSource: MetricsDataSource) {}\n\n async getSummary(timeRange?: MetricsTimeRange): Promise<MetricsSummary> {\n const range = timeRange ?? this.defaultTimeRange();\n return this.dataSource.getMetricsSummary(range);\n }\n\n async getEndpointBreakdown(\n timeRange?: MetricsTimeRange,\n ): Promise<EndpointMetrics[]> {\n const range = timeRange ?? this.defaultTimeRange();\n return this.dataSource.getEndpointMetrics(range);\n }\n\n async getTopErrors(\n timeRange?: MetricsTimeRange,\n limit?: number,\n ): Promise<ErrorSummary[]> {\n const range = timeRange ?? this.defaultTimeRange();\n return this.dataSource.getErrorSummary(range, limit);\n }\n\n async getMetricsByFilter(\n filter: MetricsFilter,\n ): Promise<ApiMetricEntry[]> {\n return this.dataSource.getMetrics(filter);\n }\n\n private defaultTimeRange(): MetricsTimeRange {\n const end = new Date();\n const start = new Date(end.getTime() - 24 * 60 * 60 * 1000);\n return { start, end };\n }\n}\n","import type { MetricsDataSource } from './metrics-data-source.js';\nimport type { ApiMetricEntry } from './types.js';\n\nexport class ErrorTracker {\n constructor(private readonly dataSource: MetricsDataSource) {}\n\n async trackError(\n endpoint: string,\n method: string,\n statusCode: number,\n errorMessage: string,\n shopDomain?: string,\n ): Promise<ApiMetricEntry> {\n const entry: Omit<ApiMetricEntry, 'id'> = {\n endpoint,\n method,\n statusCode,\n responseTimeMs: 0,\n timestamp: new Date(),\n errorMessage,\n ...(shopDomain !== undefined ? { shopDomain } : {}),\n };\n return this.dataSource.recordMetric(entry);\n }\n\n async getRecentErrors(limit?: number): Promise<ApiMetricEntry[]> {\n const entries = await this.dataSource.getMetrics({});\n const sorted = entries\n .filter((e) => e.statusCode >= 400)\n .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n if (limit !== undefined) {\n return sorted.slice(0, limit);\n }\n return sorted;\n }\n\n async getErrorsByEndpoint(\n endpoint: string,\n limit?: number,\n ): Promise<ApiMetricEntry[]> {\n const entries = await this.dataSource.getMetrics({ endpoint });\n const errors = entries\n .filter((e) => e.statusCode >= 400)\n .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n if (limit !== undefined) {\n return errors.slice(0, limit);\n }\n return errors;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,YAA+B;AAA/B;AAAA,EAAgC;AAAA,EAE7D,MAAM,OACJ,OACyB;AACzB,WAAO,KAAK,WAAW,aAAa,KAAK;AAAA,EAC3C;AAAA,EAEA,MAAM,YACJ,SAC2B;AAC3B,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,QAAQ,IAAI,CAAC,UAAU,KAAK,WAAW,aAAa,KAAK,CAAC;AAAA,IAC5D;AACA,WAAO;AAAA,EACT;AACF;;;ACVO,IAAM,sBAAN,MAA0B;AAAA,EAC/B,YAA6B,YAA+B;AAA/B;AAAA,EAAgC;AAAA,EAE7D,MAAM,WAAW,WAAuD;AACtE,UAAM,QAAQ,aAAa,KAAK,iBAAiB;AACjD,WAAO,KAAK,WAAW,kBAAkB,KAAK;AAAA,EAChD;AAAA,EAEA,MAAM,qBACJ,WAC4B;AAC5B,UAAM,QAAQ,aAAa,KAAK,iBAAiB;AACjD,WAAO,KAAK,WAAW,mBAAmB,KAAK;AAAA,EACjD;AAAA,EAEA,MAAM,aACJ,WACA,OACyB;AACzB,UAAM,QAAQ,aAAa,KAAK,iBAAiB;AACjD,WAAO,KAAK,WAAW,gBAAgB,OAAO,KAAK;AAAA,EACrD;AAAA,EAEA,MAAM,mBACJ,QAC2B;AAC3B,WAAO,KAAK,WAAW,WAAW,MAAM;AAAA,EAC1C;AAAA,EAEQ,mBAAqC;AAC3C,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,QAAQ,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,KAAK,KAAK,GAAI;AAC1D,WAAO,EAAE,OAAO,IAAI;AAAA,EACtB;AACF;;;ACzCO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,YAA+B;AAA/B;AAAA,EAAgC;AAAA,EAE7D,MAAM,WACJ,UACA,QACA,YACA,cACA,YACyB;AACzB,UAAM,QAAoC;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,WAAW,oBAAI,KAAK;AAAA,MACpB;AAAA,MACA,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,IACnD;AACA,WAAO,KAAK,WAAW,aAAa,KAAK;AAAA,EAC3C;AAAA,EAEA,MAAM,gBAAgB,OAA2C;AAC/D,UAAM,UAAU,MAAM,KAAK,WAAW,WAAW,CAAC,CAAC;AACnD,UAAM,SAAS,QACZ,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,EACjC,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,QAAQ,IAAI,EAAE,UAAU,QAAQ,CAAC;AAC/D,QAAI,UAAU,QAAW;AACvB,aAAO,OAAO,MAAM,GAAG,KAAK;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,oBACJ,UACA,OAC2B;AAC3B,UAAM,UAAU,MAAM,KAAK,WAAW,WAAW,EAAE,SAAS,CAAC;AAC7D,UAAM,SAAS,QACZ,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,EACjC,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,QAAQ,IAAI,EAAE,UAAU,QAAQ,CAAC;AAC/D,QAAI,UAAU,QAAW;AACvB,aAAO,OAAO,MAAM,GAAG,KAAK;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// src/metrics/metrics-collector.ts
|
|
2
|
+
var MetricsCollector = class {
|
|
3
|
+
constructor(dataSource) {
|
|
4
|
+
this.dataSource = dataSource;
|
|
5
|
+
}
|
|
6
|
+
async record(entry) {
|
|
7
|
+
return this.dataSource.recordMetric(entry);
|
|
8
|
+
}
|
|
9
|
+
async recordBatch(entries) {
|
|
10
|
+
const results = await Promise.all(
|
|
11
|
+
entries.map((entry) => this.dataSource.recordMetric(entry))
|
|
12
|
+
);
|
|
13
|
+
return results;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/metrics/metrics-query-service.ts
|
|
18
|
+
var MetricsQueryService = class {
|
|
19
|
+
constructor(dataSource) {
|
|
20
|
+
this.dataSource = dataSource;
|
|
21
|
+
}
|
|
22
|
+
async getSummary(timeRange) {
|
|
23
|
+
const range = timeRange ?? this.defaultTimeRange();
|
|
24
|
+
return this.dataSource.getMetricsSummary(range);
|
|
25
|
+
}
|
|
26
|
+
async getEndpointBreakdown(timeRange) {
|
|
27
|
+
const range = timeRange ?? this.defaultTimeRange();
|
|
28
|
+
return this.dataSource.getEndpointMetrics(range);
|
|
29
|
+
}
|
|
30
|
+
async getTopErrors(timeRange, limit) {
|
|
31
|
+
const range = timeRange ?? this.defaultTimeRange();
|
|
32
|
+
return this.dataSource.getErrorSummary(range, limit);
|
|
33
|
+
}
|
|
34
|
+
async getMetricsByFilter(filter) {
|
|
35
|
+
return this.dataSource.getMetrics(filter);
|
|
36
|
+
}
|
|
37
|
+
defaultTimeRange() {
|
|
38
|
+
const end = /* @__PURE__ */ new Date();
|
|
39
|
+
const start = new Date(end.getTime() - 24 * 60 * 60 * 1e3);
|
|
40
|
+
return { start, end };
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// src/metrics/error-tracker.ts
|
|
45
|
+
var ErrorTracker = class {
|
|
46
|
+
constructor(dataSource) {
|
|
47
|
+
this.dataSource = dataSource;
|
|
48
|
+
}
|
|
49
|
+
async trackError(endpoint, method, statusCode, errorMessage, shopDomain) {
|
|
50
|
+
const entry = {
|
|
51
|
+
endpoint,
|
|
52
|
+
method,
|
|
53
|
+
statusCode,
|
|
54
|
+
responseTimeMs: 0,
|
|
55
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
56
|
+
errorMessage,
|
|
57
|
+
...shopDomain !== void 0 ? { shopDomain } : {}
|
|
58
|
+
};
|
|
59
|
+
return this.dataSource.recordMetric(entry);
|
|
60
|
+
}
|
|
61
|
+
async getRecentErrors(limit) {
|
|
62
|
+
const entries = await this.dataSource.getMetrics({});
|
|
63
|
+
const sorted = entries.filter((e) => e.statusCode >= 400).sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
64
|
+
if (limit !== void 0) {
|
|
65
|
+
return sorted.slice(0, limit);
|
|
66
|
+
}
|
|
67
|
+
return sorted;
|
|
68
|
+
}
|
|
69
|
+
async getErrorsByEndpoint(endpoint, limit) {
|
|
70
|
+
const entries = await this.dataSource.getMetrics({ endpoint });
|
|
71
|
+
const errors = entries.filter((e) => e.statusCode >= 400).sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
72
|
+
if (limit !== void 0) {
|
|
73
|
+
return errors.slice(0, limit);
|
|
74
|
+
}
|
|
75
|
+
return errors;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
export {
|
|
79
|
+
ErrorTracker,
|
|
80
|
+
MetricsCollector,
|
|
81
|
+
MetricsQueryService
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/metrics/metrics-collector.ts","../../src/metrics/metrics-query-service.ts","../../src/metrics/error-tracker.ts"],"sourcesContent":["import type { MetricsDataSource } from './metrics-data-source.js';\nimport type { ApiMetricEntry } from './types.js';\n\nexport class MetricsCollector {\n constructor(private readonly dataSource: MetricsDataSource) {}\n\n async record(\n entry: Omit<ApiMetricEntry, 'id'>,\n ): Promise<ApiMetricEntry> {\n return this.dataSource.recordMetric(entry);\n }\n\n async recordBatch(\n entries: Array<Omit<ApiMetricEntry, 'id'>>,\n ): Promise<ApiMetricEntry[]> {\n const results = await Promise.all(\n entries.map((entry) => this.dataSource.recordMetric(entry)),\n );\n return results;\n }\n}\n","import type { MetricsDataSource } from './metrics-data-source.js';\nimport type {\n ApiMetricEntry,\n EndpointMetrics,\n ErrorSummary,\n MetricsFilter,\n MetricsSummary,\n MetricsTimeRange,\n} from './types.js';\n\nexport class MetricsQueryService {\n constructor(private readonly dataSource: MetricsDataSource) {}\n\n async getSummary(timeRange?: MetricsTimeRange): Promise<MetricsSummary> {\n const range = timeRange ?? this.defaultTimeRange();\n return this.dataSource.getMetricsSummary(range);\n }\n\n async getEndpointBreakdown(\n timeRange?: MetricsTimeRange,\n ): Promise<EndpointMetrics[]> {\n const range = timeRange ?? this.defaultTimeRange();\n return this.dataSource.getEndpointMetrics(range);\n }\n\n async getTopErrors(\n timeRange?: MetricsTimeRange,\n limit?: number,\n ): Promise<ErrorSummary[]> {\n const range = timeRange ?? this.defaultTimeRange();\n return this.dataSource.getErrorSummary(range, limit);\n }\n\n async getMetricsByFilter(\n filter: MetricsFilter,\n ): Promise<ApiMetricEntry[]> {\n return this.dataSource.getMetrics(filter);\n }\n\n private defaultTimeRange(): MetricsTimeRange {\n const end = new Date();\n const start = new Date(end.getTime() - 24 * 60 * 60 * 1000);\n return { start, end };\n }\n}\n","import type { MetricsDataSource } from './metrics-data-source.js';\nimport type { ApiMetricEntry } from './types.js';\n\nexport class ErrorTracker {\n constructor(private readonly dataSource: MetricsDataSource) {}\n\n async trackError(\n endpoint: string,\n method: string,\n statusCode: number,\n errorMessage: string,\n shopDomain?: string,\n ): Promise<ApiMetricEntry> {\n const entry: Omit<ApiMetricEntry, 'id'> = {\n endpoint,\n method,\n statusCode,\n responseTimeMs: 0,\n timestamp: new Date(),\n errorMessage,\n ...(shopDomain !== undefined ? { shopDomain } : {}),\n };\n return this.dataSource.recordMetric(entry);\n }\n\n async getRecentErrors(limit?: number): Promise<ApiMetricEntry[]> {\n const entries = await this.dataSource.getMetrics({});\n const sorted = entries\n .filter((e) => e.statusCode >= 400)\n .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n if (limit !== undefined) {\n return sorted.slice(0, limit);\n }\n return sorted;\n }\n\n async getErrorsByEndpoint(\n endpoint: string,\n limit?: number,\n ): Promise<ApiMetricEntry[]> {\n const entries = await this.dataSource.getMetrics({ endpoint });\n const errors = entries\n .filter((e) => e.statusCode >= 400)\n .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n if (limit !== undefined) {\n return errors.slice(0, limit);\n }\n return errors;\n }\n}\n"],"mappings":";AAGO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,YAA+B;AAA/B;AAAA,EAAgC;AAAA,EAE7D,MAAM,OACJ,OACyB;AACzB,WAAO,KAAK,WAAW,aAAa,KAAK;AAAA,EAC3C;AAAA,EAEA,MAAM,YACJ,SAC2B;AAC3B,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,QAAQ,IAAI,CAAC,UAAU,KAAK,WAAW,aAAa,KAAK,CAAC;AAAA,IAC5D;AACA,WAAO;AAAA,EACT;AACF;;;ACVO,IAAM,sBAAN,MAA0B;AAAA,EAC/B,YAA6B,YAA+B;AAA/B;AAAA,EAAgC;AAAA,EAE7D,MAAM,WAAW,WAAuD;AACtE,UAAM,QAAQ,aAAa,KAAK,iBAAiB;AACjD,WAAO,KAAK,WAAW,kBAAkB,KAAK;AAAA,EAChD;AAAA,EAEA,MAAM,qBACJ,WAC4B;AAC5B,UAAM,QAAQ,aAAa,KAAK,iBAAiB;AACjD,WAAO,KAAK,WAAW,mBAAmB,KAAK;AAAA,EACjD;AAAA,EAEA,MAAM,aACJ,WACA,OACyB;AACzB,UAAM,QAAQ,aAAa,KAAK,iBAAiB;AACjD,WAAO,KAAK,WAAW,gBAAgB,OAAO,KAAK;AAAA,EACrD;AAAA,EAEA,MAAM,mBACJ,QAC2B;AAC3B,WAAO,KAAK,WAAW,WAAW,MAAM;AAAA,EAC1C;AAAA,EAEQ,mBAAqC;AAC3C,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,QAAQ,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,KAAK,KAAK,GAAI;AAC1D,WAAO,EAAE,OAAO,IAAI;AAAA,EACtB;AACF;;;ACzCO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,YAA+B;AAA/B;AAAA,EAAgC;AAAA,EAE7D,MAAM,WACJ,UACA,QACA,YACA,cACA,YACyB;AACzB,UAAM,QAAoC;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,WAAW,oBAAI,KAAK;AAAA,MACpB;AAAA,MACA,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,IACnD;AACA,WAAO,KAAK,WAAW,aAAa,KAAK;AAAA,EAC3C;AAAA,EAEA,MAAM,gBAAgB,OAA2C;AAC/D,UAAM,UAAU,MAAM,KAAK,WAAW,WAAW,CAAC,CAAC;AACnD,UAAM,SAAS,QACZ,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,EACjC,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,QAAQ,IAAI,EAAE,UAAU,QAAQ,CAAC;AAC/D,QAAI,UAAU,QAAW;AACvB,aAAO,OAAO,MAAM,GAAG,KAAK;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,oBACJ,UACA,OAC2B;AAC3B,UAAM,UAAU,MAAM,KAAK,WAAW,WAAW,EAAE,SAAS,CAAC;AAC7D,UAAM,SAAS,QACZ,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,EACjC,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,QAAQ,IAAI,EAAE,UAAU,QAAQ,CAAC;AAC/D,QAAI,UAAU,QAAW;AACvB,aAAO,OAAO,MAAM,GAAG,KAAK;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
type TicketPriority = 'low' | 'medium' | 'high' | 'urgent';
|
|
2
|
+
type TicketStatus = 'open' | 'in_progress' | 'waiting_on_customer' | 'waiting_on_developer' | 'resolved' | 'closed';
|
|
3
|
+
interface Ticket {
|
|
4
|
+
id: string;
|
|
5
|
+
subject: string;
|
|
6
|
+
description: string;
|
|
7
|
+
status: TicketStatus;
|
|
8
|
+
priority: TicketPriority;
|
|
9
|
+
shopDomain: string;
|
|
10
|
+
merchantEmail: string;
|
|
11
|
+
assignee?: string;
|
|
12
|
+
tags: string[];
|
|
13
|
+
createdAt: Date;
|
|
14
|
+
updatedAt: Date;
|
|
15
|
+
resolvedAt?: Date;
|
|
16
|
+
closedAt?: Date;
|
|
17
|
+
}
|
|
18
|
+
interface TicketComment {
|
|
19
|
+
id: string;
|
|
20
|
+
ticketId: string;
|
|
21
|
+
author: string;
|
|
22
|
+
authorRole: 'merchant' | 'developer' | 'system';
|
|
23
|
+
content: string;
|
|
24
|
+
createdAt: Date;
|
|
25
|
+
}
|
|
26
|
+
interface TicketCreateInput {
|
|
27
|
+
subject: string;
|
|
28
|
+
description: string;
|
|
29
|
+
priority?: TicketPriority;
|
|
30
|
+
shopDomain: string;
|
|
31
|
+
merchantEmail: string;
|
|
32
|
+
tags?: string[];
|
|
33
|
+
}
|
|
34
|
+
interface TicketUpdateInput {
|
|
35
|
+
status?: TicketStatus;
|
|
36
|
+
priority?: TicketPriority;
|
|
37
|
+
assignee?: string;
|
|
38
|
+
tags?: string[];
|
|
39
|
+
}
|
|
40
|
+
interface TicketFilter {
|
|
41
|
+
status?: TicketStatus;
|
|
42
|
+
priority?: TicketPriority;
|
|
43
|
+
shopDomain?: string;
|
|
44
|
+
assignee?: string;
|
|
45
|
+
search?: string;
|
|
46
|
+
}
|
|
47
|
+
interface TicketListResult {
|
|
48
|
+
tickets: Ticket[];
|
|
49
|
+
total: number;
|
|
50
|
+
page: number;
|
|
51
|
+
pageSize: number;
|
|
52
|
+
}
|
|
53
|
+
interface TicketStats {
|
|
54
|
+
openCount: number;
|
|
55
|
+
inProgressCount: number;
|
|
56
|
+
resolvedCount: number;
|
|
57
|
+
avgResolutionTimeHours: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface TicketDataSource {
|
|
61
|
+
create(input: TicketCreateInput): Promise<Ticket>;
|
|
62
|
+
getById(ticketId: string): Promise<Ticket | null>;
|
|
63
|
+
list(filter?: TicketFilter, page?: number, pageSize?: number): Promise<TicketListResult>;
|
|
64
|
+
update(ticketId: string, input: TicketUpdateInput): Promise<Ticket | null>;
|
|
65
|
+
addComment(ticketId: string, comment: Omit<TicketComment, 'id' | 'ticketId' | 'createdAt'>): Promise<TicketComment>;
|
|
66
|
+
getComments(ticketId: string): Promise<TicketComment[]>;
|
|
67
|
+
getStats(): Promise<TicketStats>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
declare class TicketService {
|
|
71
|
+
private readonly dataSource;
|
|
72
|
+
constructor(dataSource: TicketDataSource);
|
|
73
|
+
createTicket(input: TicketCreateInput): Promise<Ticket>;
|
|
74
|
+
getTicket(ticketId: string): Promise<Ticket | null>;
|
|
75
|
+
listTickets(filter?: TicketFilter, page?: number, pageSize?: number): Promise<TicketListResult>;
|
|
76
|
+
updateTicket(ticketId: string, input: TicketUpdateInput): Promise<Ticket | null>;
|
|
77
|
+
resolveTicket(ticketId: string): Promise<Ticket | null>;
|
|
78
|
+
closeTicket(ticketId: string): Promise<Ticket | null>;
|
|
79
|
+
assignTicket(ticketId: string, assignee: string): Promise<Ticket | null>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
declare class TicketCommentService {
|
|
83
|
+
private readonly dataSource;
|
|
84
|
+
constructor(dataSource: TicketDataSource);
|
|
85
|
+
addComment(ticketId: string, author: string, authorRole: TicketComment['authorRole'], content: string): Promise<TicketComment>;
|
|
86
|
+
getComments(ticketId: string): Promise<TicketComment[]>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
declare class TicketStatsService {
|
|
90
|
+
private readonly dataSource;
|
|
91
|
+
constructor(dataSource: TicketDataSource);
|
|
92
|
+
getStats(): Promise<TicketStats>;
|
|
93
|
+
getOpenTicketCount(): Promise<number>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { type Ticket, type TicketComment, TicketCommentService, type TicketCreateInput, type TicketDataSource, type TicketFilter, type TicketListResult, type TicketPriority, TicketService, type TicketStats, TicketStatsService, type TicketStatus, type TicketUpdateInput };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
type TicketPriority = 'low' | 'medium' | 'high' | 'urgent';
|
|
2
|
+
type TicketStatus = 'open' | 'in_progress' | 'waiting_on_customer' | 'waiting_on_developer' | 'resolved' | 'closed';
|
|
3
|
+
interface Ticket {
|
|
4
|
+
id: string;
|
|
5
|
+
subject: string;
|
|
6
|
+
description: string;
|
|
7
|
+
status: TicketStatus;
|
|
8
|
+
priority: TicketPriority;
|
|
9
|
+
shopDomain: string;
|
|
10
|
+
merchantEmail: string;
|
|
11
|
+
assignee?: string;
|
|
12
|
+
tags: string[];
|
|
13
|
+
createdAt: Date;
|
|
14
|
+
updatedAt: Date;
|
|
15
|
+
resolvedAt?: Date;
|
|
16
|
+
closedAt?: Date;
|
|
17
|
+
}
|
|
18
|
+
interface TicketComment {
|
|
19
|
+
id: string;
|
|
20
|
+
ticketId: string;
|
|
21
|
+
author: string;
|
|
22
|
+
authorRole: 'merchant' | 'developer' | 'system';
|
|
23
|
+
content: string;
|
|
24
|
+
createdAt: Date;
|
|
25
|
+
}
|
|
26
|
+
interface TicketCreateInput {
|
|
27
|
+
subject: string;
|
|
28
|
+
description: string;
|
|
29
|
+
priority?: TicketPriority;
|
|
30
|
+
shopDomain: string;
|
|
31
|
+
merchantEmail: string;
|
|
32
|
+
tags?: string[];
|
|
33
|
+
}
|
|
34
|
+
interface TicketUpdateInput {
|
|
35
|
+
status?: TicketStatus;
|
|
36
|
+
priority?: TicketPriority;
|
|
37
|
+
assignee?: string;
|
|
38
|
+
tags?: string[];
|
|
39
|
+
}
|
|
40
|
+
interface TicketFilter {
|
|
41
|
+
status?: TicketStatus;
|
|
42
|
+
priority?: TicketPriority;
|
|
43
|
+
shopDomain?: string;
|
|
44
|
+
assignee?: string;
|
|
45
|
+
search?: string;
|
|
46
|
+
}
|
|
47
|
+
interface TicketListResult {
|
|
48
|
+
tickets: Ticket[];
|
|
49
|
+
total: number;
|
|
50
|
+
page: number;
|
|
51
|
+
pageSize: number;
|
|
52
|
+
}
|
|
53
|
+
interface TicketStats {
|
|
54
|
+
openCount: number;
|
|
55
|
+
inProgressCount: number;
|
|
56
|
+
resolvedCount: number;
|
|
57
|
+
avgResolutionTimeHours: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface TicketDataSource {
|
|
61
|
+
create(input: TicketCreateInput): Promise<Ticket>;
|
|
62
|
+
getById(ticketId: string): Promise<Ticket | null>;
|
|
63
|
+
list(filter?: TicketFilter, page?: number, pageSize?: number): Promise<TicketListResult>;
|
|
64
|
+
update(ticketId: string, input: TicketUpdateInput): Promise<Ticket | null>;
|
|
65
|
+
addComment(ticketId: string, comment: Omit<TicketComment, 'id' | 'ticketId' | 'createdAt'>): Promise<TicketComment>;
|
|
66
|
+
getComments(ticketId: string): Promise<TicketComment[]>;
|
|
67
|
+
getStats(): Promise<TicketStats>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
declare class TicketService {
|
|
71
|
+
private readonly dataSource;
|
|
72
|
+
constructor(dataSource: TicketDataSource);
|
|
73
|
+
createTicket(input: TicketCreateInput): Promise<Ticket>;
|
|
74
|
+
getTicket(ticketId: string): Promise<Ticket | null>;
|
|
75
|
+
listTickets(filter?: TicketFilter, page?: number, pageSize?: number): Promise<TicketListResult>;
|
|
76
|
+
updateTicket(ticketId: string, input: TicketUpdateInput): Promise<Ticket | null>;
|
|
77
|
+
resolveTicket(ticketId: string): Promise<Ticket | null>;
|
|
78
|
+
closeTicket(ticketId: string): Promise<Ticket | null>;
|
|
79
|
+
assignTicket(ticketId: string, assignee: string): Promise<Ticket | null>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
declare class TicketCommentService {
|
|
83
|
+
private readonly dataSource;
|
|
84
|
+
constructor(dataSource: TicketDataSource);
|
|
85
|
+
addComment(ticketId: string, author: string, authorRole: TicketComment['authorRole'], content: string): Promise<TicketComment>;
|
|
86
|
+
getComments(ticketId: string): Promise<TicketComment[]>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
declare class TicketStatsService {
|
|
90
|
+
private readonly dataSource;
|
|
91
|
+
constructor(dataSource: TicketDataSource);
|
|
92
|
+
getStats(): Promise<TicketStats>;
|
|
93
|
+
getOpenTicketCount(): Promise<number>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { type Ticket, type TicketComment, TicketCommentService, type TicketCreateInput, type TicketDataSource, type TicketFilter, type TicketListResult, type TicketPriority, TicketService, type TicketStats, TicketStatsService, type TicketStatus, type TicketUpdateInput };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/tickets/index.ts
|
|
21
|
+
var tickets_exports = {};
|
|
22
|
+
__export(tickets_exports, {
|
|
23
|
+
TicketCommentService: () => TicketCommentService,
|
|
24
|
+
TicketService: () => TicketService,
|
|
25
|
+
TicketStatsService: () => TicketStatsService
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(tickets_exports);
|
|
28
|
+
|
|
29
|
+
// src/tickets/ticket-service.ts
|
|
30
|
+
var TicketService = class {
|
|
31
|
+
dataSource;
|
|
32
|
+
constructor(dataSource) {
|
|
33
|
+
this.dataSource = dataSource;
|
|
34
|
+
}
|
|
35
|
+
async createTicket(input) {
|
|
36
|
+
if (!input.subject.trim()) {
|
|
37
|
+
throw new Error("Ticket subject cannot be empty");
|
|
38
|
+
}
|
|
39
|
+
return this.dataSource.create(input);
|
|
40
|
+
}
|
|
41
|
+
async getTicket(ticketId) {
|
|
42
|
+
return this.dataSource.getById(ticketId);
|
|
43
|
+
}
|
|
44
|
+
async listTickets(filter, page = 1, pageSize = 20) {
|
|
45
|
+
return this.dataSource.list(filter, page, pageSize);
|
|
46
|
+
}
|
|
47
|
+
async updateTicket(ticketId, input) {
|
|
48
|
+
return this.dataSource.update(ticketId, input);
|
|
49
|
+
}
|
|
50
|
+
async resolveTicket(ticketId) {
|
|
51
|
+
return this.dataSource.update(ticketId, {
|
|
52
|
+
status: "resolved"
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async closeTicket(ticketId) {
|
|
56
|
+
return this.dataSource.update(ticketId, {
|
|
57
|
+
status: "closed"
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async assignTicket(ticketId, assignee) {
|
|
61
|
+
return this.dataSource.update(ticketId, { assignee });
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/tickets/ticket-comment-service.ts
|
|
66
|
+
var TicketCommentService = class {
|
|
67
|
+
dataSource;
|
|
68
|
+
constructor(dataSource) {
|
|
69
|
+
this.dataSource = dataSource;
|
|
70
|
+
}
|
|
71
|
+
async addComment(ticketId, author, authorRole, content) {
|
|
72
|
+
if (!content.trim()) {
|
|
73
|
+
throw new Error("Comment content cannot be empty");
|
|
74
|
+
}
|
|
75
|
+
return this.dataSource.addComment(ticketId, { author, authorRole, content });
|
|
76
|
+
}
|
|
77
|
+
async getComments(ticketId) {
|
|
78
|
+
return this.dataSource.getComments(ticketId);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// src/tickets/ticket-stats-service.ts
|
|
83
|
+
var TicketStatsService = class {
|
|
84
|
+
dataSource;
|
|
85
|
+
constructor(dataSource) {
|
|
86
|
+
this.dataSource = dataSource;
|
|
87
|
+
}
|
|
88
|
+
async getStats() {
|
|
89
|
+
return this.dataSource.getStats();
|
|
90
|
+
}
|
|
91
|
+
async getOpenTicketCount() {
|
|
92
|
+
const stats = await this.dataSource.getStats();
|
|
93
|
+
return stats.openCount;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
97
|
+
0 && (module.exports = {
|
|
98
|
+
TicketCommentService,
|
|
99
|
+
TicketService,
|
|
100
|
+
TicketStatsService
|
|
101
|
+
});
|
|
102
|
+
//# sourceMappingURL=index.js.map
|