@gravito/satellite-analytics 0.1.1
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/CHANGELOG.md +8 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +61 -0
- package/package.json +26 -0
- package/src/Application/Resolvers/OrderVolumeResolver.ts +26 -0
- package/src/Domain/Contracts/IAnalyticsResolver.ts +16 -0
- package/src/index.ts +49 -0
- package/tsconfig.json +21 -0
package/CHANGELOG.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ServiceProvider, Container } from '@gravito/core';
|
|
2
|
+
|
|
3
|
+
declare class AnalyticsServiceProvider extends ServiceProvider {
|
|
4
|
+
private resolvers;
|
|
5
|
+
register(_container: Container): void;
|
|
6
|
+
private addResolver;
|
|
7
|
+
boot(): void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { AnalyticsServiceProvider };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { ServiceProvider } from "@gravito/core";
|
|
3
|
+
|
|
4
|
+
// src/Application/Resolvers/OrderVolumeResolver.ts
|
|
5
|
+
var OrderVolumeResolver = class {
|
|
6
|
+
metric = "order_volume";
|
|
7
|
+
async resolve(_query) {
|
|
8
|
+
return {
|
|
9
|
+
type: "TIMESERIES",
|
|
10
|
+
data: [
|
|
11
|
+
{ label: "Mon", value: 120 },
|
|
12
|
+
{ label: "Tue", value: 150 },
|
|
13
|
+
{ label: "Wed", value: 80 },
|
|
14
|
+
{ label: "Thu", value: 200 },
|
|
15
|
+
{ label: "Fri", value: 170 },
|
|
16
|
+
{ label: "Sat", value: 250 },
|
|
17
|
+
{ label: "Sun", value: 300 }
|
|
18
|
+
],
|
|
19
|
+
summary: "\u672C\u9031\u8A02\u55AE\u91CF\u589E\u9577 15%"
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/index.ts
|
|
25
|
+
var AnalyticsServiceProvider = class extends ServiceProvider {
|
|
26
|
+
resolvers = /* @__PURE__ */ new Map();
|
|
27
|
+
register(_container) {
|
|
28
|
+
this.addResolver(new OrderVolumeResolver());
|
|
29
|
+
}
|
|
30
|
+
addResolver(resolver) {
|
|
31
|
+
this.resolvers.set(resolver.metric, resolver);
|
|
32
|
+
}
|
|
33
|
+
boot() {
|
|
34
|
+
const core = this.core;
|
|
35
|
+
if (!core) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
core.logger.info("\u{1F4CA} Analytics Framework is ready for data ingestion");
|
|
39
|
+
core.router.prefix("/api/admin/v1/analytics").group((router) => {
|
|
40
|
+
router.get("/query", async (ctx) => {
|
|
41
|
+
const metric = ctx.req.query("metric");
|
|
42
|
+
const period = ctx.req.query("period") || "7d";
|
|
43
|
+
if (!metric) {
|
|
44
|
+
return ctx.json({ error: "Metric is required" }, 400);
|
|
45
|
+
}
|
|
46
|
+
const resolver = this.resolvers.get(metric);
|
|
47
|
+
if (!resolver) {
|
|
48
|
+
return ctx.json({ error: `Metric ${metric} not supported` }, 404);
|
|
49
|
+
}
|
|
50
|
+
const result = await resolver.resolve({ metric, period });
|
|
51
|
+
return ctx.json(result);
|
|
52
|
+
});
|
|
53
|
+
router.get("/metrics", (ctx) => {
|
|
54
|
+
return ctx.json(Array.from(this.resolvers.keys()));
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export {
|
|
60
|
+
AnalyticsServiceProvider
|
|
61
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gravito/satellite-analytics",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsup src/index.ts --format esm --dts",
|
|
8
|
+
"typecheck": "bun tsc -p tsconfig.json --noEmit --skipLibCheck"
|
|
9
|
+
},
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@gravito/core": "workspace:*"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"tsup": "^8.3.5",
|
|
16
|
+
"typescript": "^5.9.3"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/gravito-framework/gravito.git",
|
|
24
|
+
"directory": "satellites/analytics"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AnalyticsQuery,
|
|
3
|
+
AnalyticsResponse,
|
|
4
|
+
IAnalyticsResolver,
|
|
5
|
+
} from '../../Domain/Contracts/IAnalyticsResolver'
|
|
6
|
+
|
|
7
|
+
export class OrderVolumeResolver implements IAnalyticsResolver {
|
|
8
|
+
metric = 'order_volume'
|
|
9
|
+
|
|
10
|
+
async resolve(_query: AnalyticsQuery): Promise<AnalyticsResponse> {
|
|
11
|
+
// 模擬數據邏輯
|
|
12
|
+
return {
|
|
13
|
+
type: 'TIMESERIES',
|
|
14
|
+
data: [
|
|
15
|
+
{ label: 'Mon', value: 120 },
|
|
16
|
+
{ label: 'Tue', value: 150 },
|
|
17
|
+
{ label: 'Wed', value: 80 },
|
|
18
|
+
{ label: 'Thu', value: 200 },
|
|
19
|
+
{ label: 'Fri', value: 170 },
|
|
20
|
+
{ label: 'Sat', value: 250 },
|
|
21
|
+
{ label: 'Sun', value: 300 },
|
|
22
|
+
],
|
|
23
|
+
summary: '本週訂單量增長 15%',
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface AnalyticsQuery {
|
|
2
|
+
metric: string
|
|
3
|
+
period: '24h' | '7d' | '30d' | '90d'
|
|
4
|
+
filters?: Record<string, any>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface AnalyticsResponse {
|
|
8
|
+
type: 'TIMESERIES' | 'SINGLE_VALUE' | 'PIE' | 'TABLE'
|
|
9
|
+
data: any
|
|
10
|
+
summary?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IAnalyticsResolver {
|
|
14
|
+
metric: string
|
|
15
|
+
resolve(query: AnalyticsQuery): Promise<AnalyticsResponse>
|
|
16
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type Container, ServiceProvider } from '@gravito/core'
|
|
2
|
+
import { OrderVolumeResolver } from './Application/Resolvers/OrderVolumeResolver'
|
|
3
|
+
import type { IAnalyticsResolver } from './Domain/Contracts/IAnalyticsResolver'
|
|
4
|
+
|
|
5
|
+
export class AnalyticsServiceProvider extends ServiceProvider {
|
|
6
|
+
private resolvers: Map<string, IAnalyticsResolver> = new Map()
|
|
7
|
+
|
|
8
|
+
register(_container: Container): void {
|
|
9
|
+
// 註冊內建解析器
|
|
10
|
+
this.addResolver(new OrderVolumeResolver())
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
private addResolver(resolver: IAnalyticsResolver) {
|
|
14
|
+
this.resolvers.set(resolver.metric, resolver)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override boot(): void {
|
|
18
|
+
const core = this.core
|
|
19
|
+
if (!core) {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
core.logger.info('📊 Analytics Framework is ready for data ingestion')
|
|
24
|
+
|
|
25
|
+
core.router.prefix('/api/admin/v1/analytics').group((router) => {
|
|
26
|
+
router.get('/query', async (ctx) => {
|
|
27
|
+
const metric = ctx.req.query('metric')
|
|
28
|
+
const period = (ctx.req.query('period') as any) || '7d'
|
|
29
|
+
|
|
30
|
+
if (!metric) {
|
|
31
|
+
return ctx.json({ error: 'Metric is required' }, 400)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const resolver = this.resolvers.get(metric)
|
|
35
|
+
if (!resolver) {
|
|
36
|
+
return ctx.json({ error: `Metric ${metric} not supported` }, 404)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const result = await resolver.resolve({ metric, period })
|
|
40
|
+
return ctx.json(result)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// 讓開發者查詢目前有哪些可用的指標
|
|
44
|
+
router.get('/metrics', (ctx) => {
|
|
45
|
+
return ctx.json(Array.from(this.resolvers.keys()))
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"baseUrl": ".",
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"types": ["bun-types"],
|
|
8
|
+
"paths": {
|
|
9
|
+
"@gravito/core": ["../../packages/core/src/index.ts"],
|
|
10
|
+
"@gravito/*": ["../../packages/*/src/index.ts"]
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"include": [
|
|
14
|
+
"src/**/*"
|
|
15
|
+
],
|
|
16
|
+
"exclude": [
|
|
17
|
+
"node_modules",
|
|
18
|
+
"dist",
|
|
19
|
+
"**/*.test.ts"
|
|
20
|
+
]
|
|
21
|
+
}
|