Skip to content

Commit f34f31c

Browse files
committed
feat(analytics): implement analytics API protocol and schemas for query execution and metadata discovery
1 parent ad4ae2a commit f34f31c

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { z } from 'zod';
2+
import { AnalyticsQuerySchema, CubeSchema } from '../data/analytics.zod';
3+
import { BaseResponseSchema } from './contract.zod';
4+
5+
/**
6+
* Analytics API Protocol
7+
*
8+
* Defines the HTTP interface for the Semantic Layer.
9+
* Provides endpoints for executing analytical queries and discovering metadata.
10+
*/
11+
12+
// ==========================================
13+
// 1. API Endpoints
14+
// ==========================================
15+
16+
export const AnalyticsEndpoint = z.enum([
17+
'/api/v1/analytics/query', // Execute analysis
18+
'/api/v1/analytics/meta', // Discover cubes/metrics
19+
'/api/v1/analytics/sql', // Dry-run SQL generation
20+
]);
21+
22+
// ==========================================
23+
// 2. Query Execution
24+
// ==========================================
25+
26+
/**
27+
* Query Request Body
28+
*/
29+
export const AnalyticsQueryRequestSchema = z.object({
30+
query: AnalyticsQuerySchema.describe(' The analytic query definition'),
31+
cube: z.string().describe('Target cube name'),
32+
format: z.enum(['json', 'csv', 'xlsx']).default('json').describe('Response format'),
33+
});
34+
35+
/**
36+
* Query Response (JSON)
37+
*/
38+
export const AnalyticsResultResponseSchema = BaseResponseSchema.extend({
39+
data: z.object({
40+
rows: z.array(z.record(z.string(), z.any())).describe('Result rows'),
41+
fields: z.array(z.object({
42+
name: z.string(),
43+
type: z.string(),
44+
})).describe('Column metadata'),
45+
sql: z.string().optional().describe('Executed SQL (if debug enabled)'),
46+
}),
47+
});
48+
49+
// ==========================================
50+
// 3. Metadata Discovery
51+
// ==========================================
52+
53+
/**
54+
* Meta Response
55+
* Returns available cubes, metrics, and dimensions.
56+
*/
57+
export const AnalyticsMetadataResponseSchema = BaseResponseSchema.extend({
58+
data: z.object({
59+
cubes: z.array(CubeSchema).describe('Available cubes'),
60+
}),
61+
});
62+
63+
// ==========================================
64+
// 4. SQL Dry-Run
65+
// ==========================================
66+
67+
export const AnalyticsSqlResponseSchema = BaseResponseSchema.extend({
68+
data: z.object({
69+
sql: z.string(),
70+
params: z.array(z.any()),
71+
}),
72+
});

packages/spec/src/api/discovery.zod.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const ApiCapabilitiesSchema = z.object({
99
search: z.boolean().default(false),
1010
websockets: z.boolean().default(false),
1111
files: z.boolean().default(true),
12+
analytics: z.boolean().default(false).describe('Is the Analytics/BI engine enabled?'),
1213
});
1314

1415
/**
@@ -32,6 +33,9 @@ export const ApiRoutesSchema = z.object({
3233
/** Base URL for File/Storage operations */
3334
storage: z.string().optional().describe('e.g. /api/storage'),
3435

36+
/** Base URL for Analytics/BI operations */
37+
analytics: z.string().optional().describe('e.g. /api/analytics'),
38+
3539
/** GraphQL Endpoint (if enabled) */
3640
graphql: z.string().optional().describe('e.g. /graphql'),
3741
});

packages/spec/src/api/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export * from './rest-server.zod';
2626
export * from './hub.zod';
2727
export * from './registry.zod';
2828
export * from './documentation.zod';
29+
export * from './analytics.zod';
2930

3031
// Legacy interface export (deprecated)
3132
// export type { IObjectStackProtocol } from './protocol';

0 commit comments

Comments
 (0)