@pattern-stack/codegen 0.4.1 → 0.4.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/package.json +2 -1
- package/runtime/analytics/index.ts +31 -0
- package/runtime/analytics/metrics.ts +85 -0
- package/runtime/analytics/packs/crm-entity-measures.ts +20 -0
- package/runtime/analytics/packs/index.ts +5 -0
- package/runtime/analytics/packs/monetary-measures.ts +20 -0
- package/runtime/analytics/specs.ts +54 -0
- package/runtime/analytics/types.ts +105 -0
- package/runtime/base-classes/activity-entity-repository.ts +50 -0
- package/runtime/base-classes/activity-entity-service.ts +48 -0
- package/runtime/base-classes/base-read-use-cases.ts +88 -0
- package/runtime/base-classes/base-repository.ts +289 -0
- package/runtime/base-classes/base-service.ts +183 -0
- package/runtime/base-classes/index.ts +38 -0
- package/runtime/base-classes/knowledge-entity-repository.ts +12 -0
- package/runtime/base-classes/knowledge-entity-service.ts +14 -0
- package/runtime/base-classes/lifecycle-events.ts +152 -0
- package/runtime/base-classes/metadata-entity-repository.ts +80 -0
- package/runtime/base-classes/metadata-entity-service.ts +48 -0
- package/runtime/base-classes/synced-entity-repository.ts +57 -0
- package/runtime/base-classes/synced-entity-service.ts +50 -0
- package/runtime/base-classes/with-analytics.ts +22 -0
- package/runtime/constants/tokens.ts +29 -0
- package/runtime/eav-helpers.ts +74 -0
- package/runtime/pipes/zod-validation.pipe.ts +64 -0
- package/runtime/shared/openapi/error-response.dto.ts +24 -0
- package/runtime/shared/openapi/errors.ts +39 -0
- package/runtime/shared/openapi/index.ts +20 -0
- package/runtime/shared/openapi/registry.tokens.ts +13 -0
- package/runtime/shared/openapi/registry.ts +151 -0
- package/runtime/subsystems/analytics/analytics-query.protocol.ts +37 -0
- package/runtime/subsystems/analytics/analytics.module.ts +64 -0
- package/runtime/subsystems/analytics/analytics.tokens.ts +24 -0
- package/runtime/subsystems/analytics/cube-backend.ts +75 -0
- package/runtime/subsystems/analytics/index.ts +15 -0
- package/runtime/subsystems/analytics/noop-backend.ts +27 -0
- package/runtime/subsystems/auth/auth.module.ts +91 -0
- package/runtime/subsystems/auth/auth.tokens.ts +27 -0
- package/runtime/subsystems/auth/backends/encryption-key/env.ts +76 -0
- package/runtime/subsystems/auth/backends/oauth-state-store/in-memory.ts +42 -0
- package/runtime/subsystems/auth/index.ts +77 -0
- package/runtime/subsystems/auth/protocols/auth-strategy.ts +46 -0
- package/runtime/subsystems/auth/protocols/encryption-key.ts +21 -0
- package/runtime/subsystems/auth/protocols/integration-store.ts +66 -0
- package/runtime/subsystems/auth/protocols/oauth-state-store.ts +16 -0
- package/runtime/subsystems/auth/runtime/integration-broken.error.ts +21 -0
- package/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.ts +189 -0
- package/runtime/subsystems/auth/runtime/session-expired.error.ts +39 -0
- package/runtime/subsystems/auth/runtime/with-auth-retry.ts +50 -0
- package/runtime/subsystems/bridge/assert-tenant-id.ts +57 -0
- package/runtime/subsystems/bridge/bridge-delivery-handler.ts +220 -0
- package/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.ts +149 -0
- package/runtime/subsystems/bridge/bridge-delivery.memory-backend.ts +140 -0
- package/runtime/subsystems/bridge/bridge-delivery.schema.ts +142 -0
- package/runtime/subsystems/bridge/bridge-errors.ts +112 -0
- package/runtime/subsystems/bridge/bridge-outbox-drain-hook.ts +175 -0
- package/runtime/subsystems/bridge/bridge.module.ts +160 -0
- package/runtime/subsystems/bridge/bridge.protocol.ts +351 -0
- package/runtime/subsystems/bridge/bridge.tokens.ts +68 -0
- package/runtime/subsystems/bridge/event-flow.service.ts +175 -0
- package/runtime/subsystems/bridge/generated/.gitkeep +0 -0
- package/runtime/subsystems/bridge/generated/registry.ts +6 -0
- package/runtime/subsystems/bridge/index.ts +84 -0
- package/runtime/subsystems/bridge/reserved-pools.ts +36 -0
- package/runtime/subsystems/cache/cache.drizzle-backend.ts +150 -0
- package/runtime/subsystems/cache/cache.memory-backend.ts +116 -0
- package/runtime/subsystems/cache/cache.module.ts +115 -0
- package/runtime/subsystems/cache/cache.protocol.ts +45 -0
- package/runtime/subsystems/cache/cache.schema.ts +27 -0
- package/runtime/subsystems/cache/cache.tokens.ts +17 -0
- package/runtime/subsystems/cache/index.ts +22 -0
- package/runtime/subsystems/events/domain-events.schema.ts +77 -0
- package/runtime/subsystems/events/event-bus.drizzle-backend.ts +327 -0
- package/runtime/subsystems/events/event-bus.memory-backend.ts +142 -0
- package/runtime/subsystems/events/event-bus.protocol.ts +86 -0
- package/runtime/subsystems/events/event-bus.redis-backend.ts +304 -0
- package/runtime/subsystems/events/events-errors.ts +30 -0
- package/runtime/subsystems/events/events.module.ts +230 -0
- package/runtime/subsystems/events/events.tokens.ts +62 -0
- package/runtime/subsystems/events/generated/bus.ts +103 -0
- package/runtime/subsystems/events/generated/index.ts +7 -0
- package/runtime/subsystems/events/generated/registry.ts +84 -0
- package/runtime/subsystems/events/generated/schemas.ts +59 -0
- package/runtime/subsystems/events/generated/types.ts +94 -0
- package/runtime/subsystems/events/index.ts +21 -0
- package/runtime/subsystems/index.ts +63 -0
- package/runtime/subsystems/jobs/generated/job-orchestration.schema.multi-tenant.ts +217 -0
- package/runtime/subsystems/jobs/generated/job-orchestration.schema.single-tenant.ts +217 -0
- package/runtime/subsystems/jobs/generated/scope-entity-type.ts +10 -0
- package/runtime/subsystems/jobs/index.ts +120 -0
- package/runtime/subsystems/jobs/job-handler.base.ts +206 -0
- package/runtime/subsystems/jobs/job-orchestration.schema.ts +217 -0
- package/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.ts +536 -0
- package/runtime/subsystems/jobs/job-orchestrator.memory-backend.ts +850 -0
- package/runtime/subsystems/jobs/job-orchestrator.protocol.ts +179 -0
- package/runtime/subsystems/jobs/job-run-service.drizzle-backend.ts +171 -0
- package/runtime/subsystems/jobs/job-run-service.memory-backend.ts +165 -0
- package/runtime/subsystems/jobs/job-run-service.protocol.ts +79 -0
- package/runtime/subsystems/jobs/job-step-service.drizzle-backend.ts +66 -0
- package/runtime/subsystems/jobs/job-step-service.memory-backend.ts +119 -0
- package/runtime/subsystems/jobs/job-step-service.protocol.ts +53 -0
- package/runtime/subsystems/jobs/job-worker.module.ts +302 -0
- package/runtime/subsystems/jobs/job-worker.ts +615 -0
- package/runtime/subsystems/jobs/jobs-domain.module.ts +119 -0
- package/runtime/subsystems/jobs/jobs-domain.tokens.ts +30 -0
- package/runtime/subsystems/jobs/jobs-errors.ts +150 -0
- package/runtime/subsystems/jobs/memory-job-store.ts +35 -0
- package/runtime/subsystems/jobs/pool-config.loader.ts +218 -0
- package/runtime/subsystems/storage/index.ts +18 -0
- package/runtime/subsystems/storage/storage.local-backend.ts +113 -0
- package/runtime/subsystems/storage/storage.memory-backend.ts +78 -0
- package/runtime/subsystems/storage/storage.module.ts +60 -0
- package/runtime/subsystems/storage/storage.protocol.ts +78 -0
- package/runtime/subsystems/storage/storage.tokens.ts +9 -0
- package/runtime/subsystems/storage/storage.utils.ts +20 -0
- package/runtime/subsystems/sync/deep-equal.differ.ts +198 -0
- package/runtime/subsystems/sync/execute-sync.use-case.ts +334 -0
- package/runtime/subsystems/sync/index.ts +98 -0
- package/runtime/subsystems/sync/sync-audit.schema.ts +300 -0
- package/runtime/subsystems/sync/sync-change-source.protocol.ts +99 -0
- package/runtime/subsystems/sync/sync-cursor-store.drizzle-backend.ts +104 -0
- package/runtime/subsystems/sync/sync-cursor-store.memory-backend.ts +64 -0
- package/runtime/subsystems/sync/sync-cursor-store.protocol.ts +53 -0
- package/runtime/subsystems/sync/sync-errors.ts +54 -0
- package/runtime/subsystems/sync/sync-field-diff.protocol.ts +61 -0
- package/runtime/subsystems/sync/sync-loopback.protocol.ts +33 -0
- package/runtime/subsystems/sync/sync-run-recorder.drizzle-backend.ts +123 -0
- package/runtime/subsystems/sync/sync-run-recorder.memory-backend.ts +143 -0
- package/runtime/subsystems/sync/sync-run-recorder.protocol.ts +86 -0
- package/runtime/subsystems/sync/sync-sink.protocol.ts +55 -0
- package/runtime/subsystems/sync/sync.module.ts +156 -0
- package/runtime/subsystems/sync/sync.tokens.ts +57 -0
- package/runtime/types/drizzle.ts +23 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pattern-stack/codegen",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Entity-driven code generation for full-stack TypeScript applications",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
37
|
"dist",
|
|
38
|
+
"runtime",
|
|
38
39
|
"templates",
|
|
39
40
|
"CHANGELOG.md",
|
|
40
41
|
"README.md",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics layer — public API
|
|
3
|
+
*
|
|
4
|
+
* Re-exports types, metrics, specs, and measure packs.
|
|
5
|
+
*/
|
|
6
|
+
export {
|
|
7
|
+
AggregationType,
|
|
8
|
+
DimensionType,
|
|
9
|
+
EntityType,
|
|
10
|
+
MetricType,
|
|
11
|
+
TimeGranularity,
|
|
12
|
+
} from './types';
|
|
13
|
+
export type {
|
|
14
|
+
NonAdditiveDimensionConfig,
|
|
15
|
+
SemanticFieldConfig,
|
|
16
|
+
} from './types';
|
|
17
|
+
export type {
|
|
18
|
+
SimpleMetric,
|
|
19
|
+
DerivedMetric,
|
|
20
|
+
RatioMetric,
|
|
21
|
+
CumulativeMetric,
|
|
22
|
+
MetricDefinition,
|
|
23
|
+
} from './metrics';
|
|
24
|
+
export type {
|
|
25
|
+
MeasureSpec,
|
|
26
|
+
DimensionSpec,
|
|
27
|
+
EntitySpec,
|
|
28
|
+
SemanticModelSpec,
|
|
29
|
+
} from './specs';
|
|
30
|
+
export type { MonetaryMeasures } from './packs/monetary-measures';
|
|
31
|
+
export type { CrmEntityMeasures } from './packs/crm-entity-measures';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metric composition types for the analytics layer.
|
|
3
|
+
*
|
|
4
|
+
* Ported from the Python reference (pattern_stack/atoms/semantic/metrics.py).
|
|
5
|
+
* These interfaces describe the four metric types that can be declared on
|
|
6
|
+
* entity YAML specs and compiled into cube.js metric definitions.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { AggregationType, TimeGranularity } from './types';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Metric interfaces
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A simple metric based on a single measure.
|
|
17
|
+
*
|
|
18
|
+
* Example:
|
|
19
|
+
* { type: 'simple', measure: 'amount' }
|
|
20
|
+
* { type: 'simple', measure: 'amount', agg: 'count', filter: "status = 'completed'" }
|
|
21
|
+
*/
|
|
22
|
+
export interface SimpleMetric {
|
|
23
|
+
type: 'simple';
|
|
24
|
+
measure: string;
|
|
25
|
+
agg?: AggregationType;
|
|
26
|
+
filter?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
label?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A derived metric computed from an expression over other metrics.
|
|
33
|
+
*
|
|
34
|
+
* Example:
|
|
35
|
+
* { type: 'derived', expr: 'total_revenue / order_count', metrics: ['total_revenue', 'order_count'] }
|
|
36
|
+
*/
|
|
37
|
+
export interface DerivedMetric {
|
|
38
|
+
type: 'derived';
|
|
39
|
+
expr: string;
|
|
40
|
+
metrics: string[];
|
|
41
|
+
description?: string;
|
|
42
|
+
label?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A ratio metric computing numerator / denominator.
|
|
47
|
+
*
|
|
48
|
+
* Example:
|
|
49
|
+
* { type: 'ratio', numerator: 'won_deals', denominator: 'total_deals' }
|
|
50
|
+
*/
|
|
51
|
+
export interface RatioMetric {
|
|
52
|
+
type: 'ratio';
|
|
53
|
+
numerator: string | SimpleMetric;
|
|
54
|
+
denominator: string | SimpleMetric;
|
|
55
|
+
filter?: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
label?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A cumulative metric for time-series accumulation.
|
|
62
|
+
*
|
|
63
|
+
* Specify either window OR grain_to_date, not both.
|
|
64
|
+
*
|
|
65
|
+
* Example:
|
|
66
|
+
* { type: 'cumulative', measure: 'revenue', window: '28 days' }
|
|
67
|
+
* { type: 'cumulative', measure: 'order_count', grain_to_date: 'month' }
|
|
68
|
+
*/
|
|
69
|
+
export interface CumulativeMetric {
|
|
70
|
+
type: 'cumulative';
|
|
71
|
+
measure: string;
|
|
72
|
+
window?: string;
|
|
73
|
+
grain_to_date?: TimeGranularity;
|
|
74
|
+
description?: string;
|
|
75
|
+
label?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Union type of all metric definitions.
|
|
80
|
+
*/
|
|
81
|
+
export type MetricDefinition =
|
|
82
|
+
| SimpleMetric
|
|
83
|
+
| DerivedMetric
|
|
84
|
+
| RatioMetric
|
|
85
|
+
| CumulativeMetric;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CrmEntityMeasures — measure pack interface for CRM entities.
|
|
3
|
+
*
|
|
4
|
+
* Entities that include the 'crm_entity' measure pack implement this
|
|
5
|
+
* interface on their generated analytics provider.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { AnalyticsQueryOpts, ResultRow } from '../../subsystems/analytics/analytics-query.protocol';
|
|
9
|
+
|
|
10
|
+
export interface CrmEntityMeasures {
|
|
11
|
+
/**
|
|
12
|
+
* Count of active (non-deleted) entities.
|
|
13
|
+
*/
|
|
14
|
+
activeCount(opts?: AnalyticsQueryOpts): Promise<ResultRow[]>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Count of entities created in the last N days.
|
|
18
|
+
*/
|
|
19
|
+
createdInLastNDays(n: number, opts?: AnalyticsQueryOpts): Promise<ResultRow[]>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MonetaryMeasures — measure pack interface for revenue / monetary fields.
|
|
3
|
+
*
|
|
4
|
+
* Entities that include the 'monetary' measure pack implement this interface
|
|
5
|
+
* on their generated analytics provider.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { AnalyticsQueryOpts, ResultRow } from '../../subsystems/analytics/analytics-query.protocol';
|
|
9
|
+
|
|
10
|
+
export interface MonetaryMeasures {
|
|
11
|
+
/**
|
|
12
|
+
* Total revenue (sum of the monetary measure).
|
|
13
|
+
*/
|
|
14
|
+
totalRevenue(opts?: AnalyticsQueryOpts): Promise<ResultRow[]>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Revenue broken down by a dimension.
|
|
18
|
+
*/
|
|
19
|
+
revenueBy(dimension: string, opts?: AnalyticsQueryOpts): Promise<ResultRow[]>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intermediate spec types for the analytics layer.
|
|
3
|
+
*
|
|
4
|
+
* Ported from the Python reference (pattern_stack/atoms/semantic/manifest.py).
|
|
5
|
+
* These interfaces are the intermediate representation used when extracting
|
|
6
|
+
* semantic metadata from entity YAML and converting it into cube.js schema.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { AggregationType, DimensionType, EntityType, NonAdditiveDimensionConfig, TimeGranularity } from './types';
|
|
10
|
+
import type { MetricDefinition } from './metrics';
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Spec interfaces
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
export interface MeasureSpec {
|
|
17
|
+
name: string;
|
|
18
|
+
agg: AggregationType;
|
|
19
|
+
expr?: string;
|
|
20
|
+
agg_time_dimension?: string;
|
|
21
|
+
non_additive_dimension?: NonAdditiveDimensionConfig;
|
|
22
|
+
description?: string;
|
|
23
|
+
label?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface DimensionSpec {
|
|
27
|
+
name: string;
|
|
28
|
+
dimension_type: DimensionType;
|
|
29
|
+
expr?: string;
|
|
30
|
+
time_granularity?: TimeGranularity;
|
|
31
|
+
is_partition?: boolean;
|
|
32
|
+
description?: string;
|
|
33
|
+
label?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface EntitySpec {
|
|
37
|
+
name: string;
|
|
38
|
+
entity_type: EntityType;
|
|
39
|
+
expr?: string;
|
|
40
|
+
role?: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
label?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface SemanticModelSpec {
|
|
46
|
+
name: string;
|
|
47
|
+
table_name: string;
|
|
48
|
+
measures: MeasureSpec[];
|
|
49
|
+
dimensions: DimensionSpec[];
|
|
50
|
+
entities: EntitySpec[];
|
|
51
|
+
metrics: MetricDefinition[];
|
|
52
|
+
primary_entity?: string;
|
|
53
|
+
default_agg_time_dimension?: string;
|
|
54
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic type definitions for the analytics layer.
|
|
3
|
+
*
|
|
4
|
+
* These types mirror MetricFlow / dbt-semantic-interfaces enums but are
|
|
5
|
+
* defined locally so consumers don't need the full dependency for basic
|
|
6
|
+
* field configuration. When the cube.js backend is used, these values
|
|
7
|
+
* map 1:1 to cube measure/dimension types.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Enums
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
export enum AggregationType {
|
|
15
|
+
SUM = 'sum',
|
|
16
|
+
MIN = 'min',
|
|
17
|
+
MAX = 'max',
|
|
18
|
+
COUNT = 'count',
|
|
19
|
+
COUNT_DISTINCT = 'count_distinct',
|
|
20
|
+
AVERAGE = 'average',
|
|
21
|
+
MEDIAN = 'median',
|
|
22
|
+
PERCENTILE = 'percentile',
|
|
23
|
+
SUM_BOOLEAN = 'sum_boolean',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export enum DimensionType {
|
|
27
|
+
CATEGORICAL = 'categorical',
|
|
28
|
+
TIME = 'time',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export enum EntityType {
|
|
32
|
+
PRIMARY = 'primary',
|
|
33
|
+
UNIQUE = 'unique',
|
|
34
|
+
FOREIGN = 'foreign',
|
|
35
|
+
NATURAL = 'natural',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export enum MetricType {
|
|
39
|
+
SIMPLE = 'simple',
|
|
40
|
+
DERIVED = 'derived',
|
|
41
|
+
RATIO = 'ratio',
|
|
42
|
+
CUMULATIVE = 'cumulative',
|
|
43
|
+
CONVERSION = 'conversion',
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Time granularity for time dimensions.
|
|
48
|
+
*
|
|
49
|
+
* Sub-day granularities (hour, minute, second) are intentionally omitted
|
|
50
|
+
* because cube.js does not support them.
|
|
51
|
+
*/
|
|
52
|
+
export enum TimeGranularity {
|
|
53
|
+
DAY = 'day',
|
|
54
|
+
WEEK = 'week',
|
|
55
|
+
MONTH = 'month',
|
|
56
|
+
QUARTER = 'quarter',
|
|
57
|
+
YEAR = 'year',
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Config interfaces
|
|
62
|
+
// ============================================================================
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Configuration for non-additive dimensions on measures.
|
|
66
|
+
*
|
|
67
|
+
* Non-additive dimensions specify that a measure cannot be summed across
|
|
68
|
+
* certain dimensions. For example, inventory balances cannot be summed
|
|
69
|
+
* across time — you need the latest value, not the sum.
|
|
70
|
+
*/
|
|
71
|
+
export interface NonAdditiveDimensionConfig {
|
|
72
|
+
name: string;
|
|
73
|
+
window_choice?: AggregationType;
|
|
74
|
+
window_groupings?: string[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Complete semantic configuration for a field.
|
|
79
|
+
*
|
|
80
|
+
* Used to store all semantic metadata on a field definition for later
|
|
81
|
+
* extraction by the manifest builder / cube schema generator.
|
|
82
|
+
*/
|
|
83
|
+
export interface SemanticFieldConfig {
|
|
84
|
+
// Measure configuration
|
|
85
|
+
measure?: boolean;
|
|
86
|
+
agg?: AggregationType;
|
|
87
|
+
agg_time_dimension?: string;
|
|
88
|
+
non_additive_dimension?: NonAdditiveDimensionConfig;
|
|
89
|
+
|
|
90
|
+
// Dimension configuration
|
|
91
|
+
dimension?: boolean;
|
|
92
|
+
dimension_type?: DimensionType;
|
|
93
|
+
time_granularity?: TimeGranularity;
|
|
94
|
+
is_partition?: boolean;
|
|
95
|
+
|
|
96
|
+
// Entity configuration
|
|
97
|
+
entity?: boolean;
|
|
98
|
+
entity_type?: EntityType;
|
|
99
|
+
entity_role?: string;
|
|
100
|
+
|
|
101
|
+
// Common
|
|
102
|
+
semantic_expr?: string;
|
|
103
|
+
semantic_label?: string;
|
|
104
|
+
visibility?: 'internal' | 'agent' | 'public';
|
|
105
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ActivityEntityRepository<TEntity>
|
|
3
|
+
*
|
|
4
|
+
* Family-specific base for activity entities (emails, calls, meetings, notes).
|
|
5
|
+
* Adds date-range queries, user/opportunity scoping, and recency ordering.
|
|
6
|
+
*
|
|
7
|
+
* Concrete repos extend this and declare their table + behaviors.
|
|
8
|
+
*/
|
|
9
|
+
import { eq, between, desc } from 'drizzle-orm';
|
|
10
|
+
import { BaseRepository } from './base-repository';
|
|
11
|
+
|
|
12
|
+
export abstract class ActivityEntityRepository<TEntity> extends BaseRepository<TEntity> {
|
|
13
|
+
/**
|
|
14
|
+
* Find activities within a date range (inclusive).
|
|
15
|
+
*/
|
|
16
|
+
async findByDateRange(start: Date, end: Date): Promise<TEntity[]> {
|
|
17
|
+
const rows = await this.baseQuery()
|
|
18
|
+
.where(between(this.table['occurredAt'], start, end));
|
|
19
|
+
return rows as TEntity[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Find all activities for a specific user.
|
|
24
|
+
*/
|
|
25
|
+
async findByUserId(userId: string): Promise<TEntity[]> {
|
|
26
|
+
const rows = await this.baseQuery()
|
|
27
|
+
.where(eq(this.table['userId'], userId));
|
|
28
|
+
return rows as TEntity[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Find all activities for a specific opportunity.
|
|
33
|
+
*/
|
|
34
|
+
async findByOpportunityId(opportunityId: string): Promise<TEntity[]> {
|
|
35
|
+
const rows = await this.baseQuery()
|
|
36
|
+
.where(eq(this.table['opportunityId'], opportunityId));
|
|
37
|
+
return rows as TEntity[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Find the most recent activities for an opportunity, ordered by occurredAt desc.
|
|
42
|
+
*/
|
|
43
|
+
async findRecentByOpportunityId(opportunityId: string, limit = 10): Promise<TEntity[]> {
|
|
44
|
+
const rows = await this.baseQuery()
|
|
45
|
+
.where(eq(this.table['opportunityId'], opportunityId))
|
|
46
|
+
.orderBy(desc(this.table['occurredAt']))
|
|
47
|
+
.limit(limit);
|
|
48
|
+
return rows as TEntity[];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ActivityEntityService<TRepo, TEntity>
|
|
3
|
+
*
|
|
4
|
+
* Family-specific base service for activity entities.
|
|
5
|
+
* Delegates to an activity repository that provides date-range,
|
|
6
|
+
* user, and opportunity queries.
|
|
7
|
+
*/
|
|
8
|
+
import { BaseService, type IBaseRepository } from './base-service';
|
|
9
|
+
|
|
10
|
+
export interface IActivityEntityRepository<TEntity> extends IBaseRepository<TEntity> {
|
|
11
|
+
findByDateRange(start: Date, end: Date): Promise<TEntity[]>;
|
|
12
|
+
findByUserId(userId: string): Promise<TEntity[]>;
|
|
13
|
+
findByOpportunityId(opportunityId: string): Promise<TEntity[]>;
|
|
14
|
+
findRecentByOpportunityId(opportunityId: string, limit?: number): Promise<TEntity[]>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export abstract class ActivityEntityService<
|
|
18
|
+
TRepo extends IActivityEntityRepository<TEntity>,
|
|
19
|
+
TEntity,
|
|
20
|
+
> extends BaseService<TRepo, TEntity> {
|
|
21
|
+
/**
|
|
22
|
+
* Find activities within a date range (inclusive).
|
|
23
|
+
*/
|
|
24
|
+
findByDateRange(start: Date, end: Date): Promise<TEntity[]> {
|
|
25
|
+
return this.repository.findByDateRange(start, end);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Find all activities for a specific user.
|
|
30
|
+
*/
|
|
31
|
+
findByUser(userId: string): Promise<TEntity[]> {
|
|
32
|
+
return this.repository.findByUserId(userId);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Find all activities for a specific opportunity.
|
|
37
|
+
*/
|
|
38
|
+
findByOpportunity(opportunityId: string): Promise<TEntity[]> {
|
|
39
|
+
return this.repository.findByOpportunityId(opportunityId);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Find the most recent activities for an opportunity.
|
|
44
|
+
*/
|
|
45
|
+
findRecent(opportunityId: string, limit?: number): Promise<TEntity[]> {
|
|
46
|
+
return this.repository.findRecentByOpportunityId(opportunityId, limit);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base read use cases
|
|
3
|
+
*
|
|
4
|
+
* Abstract base classes for auto-generated per-entity read use cases.
|
|
5
|
+
* Controllers always import use case classes — never services directly (ADR-003).
|
|
6
|
+
*
|
|
7
|
+
* Each entity gets a single generated file with two named exports:
|
|
8
|
+
* - ContactFindByIdUseCase extends BaseFindByIdUseCase<ContactService, Contact>
|
|
9
|
+
* - ContactListUseCase extends BaseListUseCase<ContactService, Contact>
|
|
10
|
+
*
|
|
11
|
+
* Note: @Injectable() is applied on concrete use case classes (not here),
|
|
12
|
+
* matching the pattern established by BaseRepository and BaseService.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// BaseFindByIdUseCase
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Structural interface for any service that supports findById.
|
|
21
|
+
* Keeps base use cases decoupled from concrete service implementations.
|
|
22
|
+
*/
|
|
23
|
+
export interface IFindByIdService<TEntity> {
|
|
24
|
+
findById(id: string): Promise<TEntity | null>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Base class for generated FindById use cases.
|
|
29
|
+
*
|
|
30
|
+
* Generated usage:
|
|
31
|
+
* ```typescript
|
|
32
|
+
* @Injectable()
|
|
33
|
+
* export class ContactFindByIdUseCase extends BaseFindByIdUseCase<ContactService, Contact> {
|
|
34
|
+
* constructor(service: ContactService) { super(service); }
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export abstract class BaseFindByIdUseCase<
|
|
39
|
+
TService extends IFindByIdService<TEntity>,
|
|
40
|
+
TEntity,
|
|
41
|
+
> {
|
|
42
|
+
constructor(protected readonly service: TService) {}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Find a single entity by its primary key.
|
|
46
|
+
* Returns null if not found.
|
|
47
|
+
*/
|
|
48
|
+
execute(id: string): Promise<TEntity | null> {
|
|
49
|
+
return this.service.findById(id);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// BaseListUseCase
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Structural interface for any service that supports list.
|
|
59
|
+
*/
|
|
60
|
+
export interface IListService<TEntity> {
|
|
61
|
+
list(options?: unknown): Promise<TEntity[]>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Base class for generated List use cases.
|
|
66
|
+
*
|
|
67
|
+
* Generated usage:
|
|
68
|
+
* ```typescript
|
|
69
|
+
* @Injectable()
|
|
70
|
+
* export class ContactListUseCase extends BaseListUseCase<ContactService, Contact> {
|
|
71
|
+
* constructor(service: ContactService) { super(service); }
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export abstract class BaseListUseCase<
|
|
76
|
+
TService extends IListService<TEntity>,
|
|
77
|
+
TEntity,
|
|
78
|
+
> {
|
|
79
|
+
constructor(protected readonly service: TService) {}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* List all entities (no filters).
|
|
83
|
+
* Controllers that need filtered lists should use a dedicated use case.
|
|
84
|
+
*/
|
|
85
|
+
execute(): Promise<TEntity[]> {
|
|
86
|
+
return this.service.list();
|
|
87
|
+
}
|
|
88
|
+
}
|