@stackmemoryai/stackmemory 0.2.8 → 0.2.9
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/src/core/context/compaction-handler.d.ts.map +1 -1
- package/dist/src/core/context/compaction-handler.js +1 -1
- package/dist/src/core/context/compaction-handler.js.map +1 -1
- package/dist/src/core/digest/hybrid-digest-generator.d.ts +76 -0
- package/dist/src/core/digest/hybrid-digest-generator.d.ts.map +1 -0
- package/dist/src/core/digest/hybrid-digest-generator.js +629 -0
- package/dist/src/core/digest/hybrid-digest-generator.js.map +1 -0
- package/dist/src/core/digest/index.d.ts +7 -0
- package/dist/src/core/digest/index.d.ts.map +1 -0
- package/dist/src/core/digest/index.js +7 -0
- package/dist/src/core/digest/index.js.map +1 -0
- package/dist/src/core/digest/types.d.ts +154 -0
- package/dist/src/core/digest/types.d.ts.map +1 -0
- package/dist/src/core/digest/types.js +18 -0
- package/dist/src/core/digest/types.js.map +1 -0
- package/dist/src/core/monitoring/logger.d.ts +2 -2
- package/dist/src/core/monitoring/logger.d.ts.map +1 -1
- package/dist/src/core/monitoring/logger.js +10 -5
- package/dist/src/core/monitoring/logger.js.map +1 -1
- package/dist/src/core/monitoring/metrics.d.ts +3 -0
- package/dist/src/core/monitoring/metrics.d.ts.map +1 -1
- package/dist/src/core/monitoring/metrics.js +142 -3
- package/dist/src/core/monitoring/metrics.js.map +1 -1
- package/dist/src/core/persistence/postgres-adapter.d.ts +31 -0
- package/dist/src/core/persistence/postgres-adapter.d.ts.map +1 -0
- package/dist/src/core/persistence/postgres-adapter.js +316 -0
- package/dist/src/core/persistence/postgres-adapter.js.map +1 -0
- package/dist/src/core/trace/trace-detector.demo.js +5 -5
- package/dist/src/core/trace/trace-detector.demo.js.map +1 -1
- package/dist/src/core/types.d.ts +35 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +2 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/integrations/mcp/server.js +2 -2
- package/dist/src/integrations/mcp/server.js.map +1 -1
- package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts +48 -0
- package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts.map +1 -0
- package/dist/src/integrations/pg-aiguide/embedding-provider.js +190 -0
- package/dist/src/integrations/pg-aiguide/embedding-provider.js.map +1 -0
- package/dist/src/integrations/pg-aiguide/semantic-search.d.ts +34 -0
- package/dist/src/integrations/pg-aiguide/semantic-search.d.ts.map +1 -0
- package/dist/src/integrations/pg-aiguide/semantic-search.js +154 -0
- package/dist/src/integrations/pg-aiguide/semantic-search.js.map +1 -0
- package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts +44 -0
- package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts.map +1 -0
- package/dist/src/integrations/pg-aiguide/timescale-analytics.js +215 -0
- package/dist/src/integrations/pg-aiguide/timescale-analytics.js.map +1 -0
- package/dist/src/models/user.model.d.ts +55 -0
- package/dist/src/models/user.model.d.ts.map +1 -0
- package/dist/src/models/user.model.js +263 -0
- package/dist/src/models/user.model.js.map +1 -0
- package/dist/src/servers/production/auth-middleware.d.ts +7 -0
- package/dist/src/servers/production/auth-middleware.d.ts.map +1 -1
- package/dist/src/servers/production/auth-middleware.js +201 -26
- package/dist/src/servers/production/auth-middleware.js.map +1 -1
- package/dist/src/servers/railway/index.js.map +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../../../src/integrations/pg-aiguide/semantic-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Pool } from 'pg';
|
|
2
|
+
export interface TimeSeriesConfig {
|
|
3
|
+
pool: Pool;
|
|
4
|
+
tableName: string;
|
|
5
|
+
timeColumn: string;
|
|
6
|
+
valueColumns: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface TimeSeriesData {
|
|
9
|
+
timestamp: Date;
|
|
10
|
+
values: Record<string, any>;
|
|
11
|
+
metadata?: Record<string, any>;
|
|
12
|
+
}
|
|
13
|
+
export interface AggregateResult {
|
|
14
|
+
period: Date;
|
|
15
|
+
count: number;
|
|
16
|
+
avg: Record<string, number>;
|
|
17
|
+
min: Record<string, number>;
|
|
18
|
+
max: Record<string, number>;
|
|
19
|
+
sum: Record<string, number>;
|
|
20
|
+
}
|
|
21
|
+
export declare class TimescaleAnalytics {
|
|
22
|
+
private pool;
|
|
23
|
+
private config;
|
|
24
|
+
constructor(config: TimeSeriesConfig);
|
|
25
|
+
createContinuousAggregate(name: string, interval: string, columns: string[]): Promise<void>;
|
|
26
|
+
getTimeSeries(startTime: Date, endTime: Date, interval: string, columns?: string[]): Promise<AggregateResult[]>;
|
|
27
|
+
detectAnomalies(column: string, sensitivity?: number, lookback?: string): Promise<TimeSeriesData[]>;
|
|
28
|
+
forecast(column: string, periods: number, method?: 'linear' | 'seasonal'): Promise<TimeSeriesData[]>;
|
|
29
|
+
getRetentionPolicy(): Promise<{
|
|
30
|
+
tableName: string;
|
|
31
|
+
retentionPeriod: string;
|
|
32
|
+
isEnabled: boolean;
|
|
33
|
+
}[]>;
|
|
34
|
+
setRetentionPolicy(retentionPeriod: string): Promise<void>;
|
|
35
|
+
compress(olderThan: string): Promise<void>;
|
|
36
|
+
getChunkStats(): Promise<{
|
|
37
|
+
totalChunks: number;
|
|
38
|
+
compressedChunks: number;
|
|
39
|
+
totalSize: string;
|
|
40
|
+
compressedSize: string;
|
|
41
|
+
compressionRatio: number;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=timescale-analytics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timescale-analytics.d.ts","sourceRoot":"","sources":["../../../../src/integrations/pg-aiguide/timescale-analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG1B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,EAAE,gBAAgB;IAK9B,yBAAyB,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC;IAuCV,aAAa,CACjB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,eAAe,EAAE,CAAC;IAoDvB,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,WAAW,SAAM,EACjB,QAAQ,SAAW,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC;IAgCtB,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,QAAQ,GAAG,UAAqB,GACvC,OAAO,CAAC,cAAc,EAAE,CAAC;IAqCtB,kBAAkB,IAAI,OAAO,CACjC;QACE,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,OAAO,CAAC;KACpB,EAAE,CACJ;IAmBK,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc1D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB1C,aAAa,IAAI,OAAO,CAAC;QAC7B,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CA2BH"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { logger } from '../../core/monitoring/logger.js';
|
|
2
|
+
export class TimescaleAnalytics {
|
|
3
|
+
pool;
|
|
4
|
+
config;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.pool = config.pool;
|
|
7
|
+
this.config = config;
|
|
8
|
+
}
|
|
9
|
+
async createContinuousAggregate(name, interval, columns) {
|
|
10
|
+
const aggregates = columns
|
|
11
|
+
.map((col) => `
|
|
12
|
+
AVG(${col}) as avg_${col},
|
|
13
|
+
MIN(${col}) as min_${col},
|
|
14
|
+
MAX(${col}) as max_${col},
|
|
15
|
+
SUM(${col}) as sum_${col}
|
|
16
|
+
`)
|
|
17
|
+
.join(',\n ');
|
|
18
|
+
const query = `
|
|
19
|
+
CREATE MATERIALIZED VIEW IF NOT EXISTS ${name}
|
|
20
|
+
WITH (timescaledb.continuous) AS
|
|
21
|
+
SELECT
|
|
22
|
+
time_bucket('${interval}', ${this.config.timeColumn}) as bucket,
|
|
23
|
+
COUNT(*) as count,
|
|
24
|
+
${aggregates}
|
|
25
|
+
FROM ${this.config.tableName}
|
|
26
|
+
GROUP BY bucket
|
|
27
|
+
WITH NO DATA
|
|
28
|
+
`;
|
|
29
|
+
await this.pool.query(query);
|
|
30
|
+
// Add refresh policy
|
|
31
|
+
await this.pool.query(`
|
|
32
|
+
SELECT add_continuous_aggregate_policy('${name}',
|
|
33
|
+
start_offset => INTERVAL '1 month',
|
|
34
|
+
end_offset => INTERVAL '1 hour',
|
|
35
|
+
schedule_interval => INTERVAL '1 hour',
|
|
36
|
+
if_not_exists => TRUE
|
|
37
|
+
)
|
|
38
|
+
`);
|
|
39
|
+
logger.info(`Created continuous aggregate: ${name}`);
|
|
40
|
+
}
|
|
41
|
+
async getTimeSeries(startTime, endTime, interval, columns) {
|
|
42
|
+
const selectedColumns = columns || this.config.valueColumns;
|
|
43
|
+
const aggregates = selectedColumns
|
|
44
|
+
.map((col) => `
|
|
45
|
+
AVG(${col})::float as avg_${col},
|
|
46
|
+
MIN(${col})::float as min_${col},
|
|
47
|
+
MAX(${col})::float as max_${col},
|
|
48
|
+
SUM(${col})::float as sum_${col}
|
|
49
|
+
`)
|
|
50
|
+
.join(',\n ');
|
|
51
|
+
const query = `
|
|
52
|
+
SELECT
|
|
53
|
+
time_bucket($1, ${this.config.timeColumn}) as period,
|
|
54
|
+
COUNT(*)::int as count,
|
|
55
|
+
${aggregates}
|
|
56
|
+
FROM ${this.config.tableName}
|
|
57
|
+
WHERE ${this.config.timeColumn} >= $2
|
|
58
|
+
AND ${this.config.timeColumn} <= $3
|
|
59
|
+
GROUP BY period
|
|
60
|
+
ORDER BY period
|
|
61
|
+
`;
|
|
62
|
+
const result = await this.pool.query(query, [interval, startTime, endTime]);
|
|
63
|
+
return result.rows.map((row) => {
|
|
64
|
+
const avg = {};
|
|
65
|
+
const min = {};
|
|
66
|
+
const max = {};
|
|
67
|
+
const sum = {};
|
|
68
|
+
selectedColumns.forEach((col) => {
|
|
69
|
+
avg[col] = row[`avg_${col}`];
|
|
70
|
+
min[col] = row[`min_${col}`];
|
|
71
|
+
max[col] = row[`max_${col}`];
|
|
72
|
+
sum[col] = row[`sum_${col}`];
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
period: row.period,
|
|
76
|
+
count: row.count,
|
|
77
|
+
avg,
|
|
78
|
+
min,
|
|
79
|
+
max,
|
|
80
|
+
sum,
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async detectAnomalies(column, sensitivity = 2.5, lookback = '7 days') {
|
|
85
|
+
const query = `
|
|
86
|
+
WITH stats AS (
|
|
87
|
+
SELECT
|
|
88
|
+
AVG(${column})::float as mean,
|
|
89
|
+
STDDEV(${column})::float as stddev
|
|
90
|
+
FROM ${this.config.tableName}
|
|
91
|
+
WHERE ${this.config.timeColumn} >= NOW() - INTERVAL '${lookback}'
|
|
92
|
+
),
|
|
93
|
+
anomalies AS (
|
|
94
|
+
SELECT
|
|
95
|
+
${this.config.timeColumn} as timestamp,
|
|
96
|
+
${column} as value,
|
|
97
|
+
metadata,
|
|
98
|
+
ABS(${column} - stats.mean) / NULLIF(stats.stddev, 0) as z_score
|
|
99
|
+
FROM ${this.config.tableName}, stats
|
|
100
|
+
WHERE ${this.config.timeColumn} >= NOW() - INTERVAL '${lookback}'
|
|
101
|
+
AND ABS(${column} - stats.mean) / NULLIF(stats.stddev, 0) > $1
|
|
102
|
+
)
|
|
103
|
+
SELECT * FROM anomalies
|
|
104
|
+
ORDER BY z_score DESC
|
|
105
|
+
`;
|
|
106
|
+
const result = await this.pool.query(query, [sensitivity]);
|
|
107
|
+
return result.rows.map((row) => ({
|
|
108
|
+
timestamp: row.timestamp,
|
|
109
|
+
values: { [column]: row.value, z_score: row.z_score },
|
|
110
|
+
metadata: row.metadata,
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
async forecast(column, periods, method = 'linear') {
|
|
114
|
+
// Simple linear regression forecast
|
|
115
|
+
if (method === 'linear') {
|
|
116
|
+
const query = `
|
|
117
|
+
WITH regression AS (
|
|
118
|
+
SELECT
|
|
119
|
+
regr_slope(${column}, EXTRACT(EPOCH FROM ${this.config.timeColumn}))::float as slope,
|
|
120
|
+
regr_intercept(${column}, EXTRACT(EPOCH FROM ${this.config.timeColumn}))::float as intercept,
|
|
121
|
+
MAX(${this.config.timeColumn}) as last_time,
|
|
122
|
+
EXTRACT(EPOCH FROM MAX(${this.config.timeColumn})) as last_epoch
|
|
123
|
+
FROM ${this.config.tableName}
|
|
124
|
+
WHERE ${this.config.timeColumn} >= NOW() - INTERVAL '30 days'
|
|
125
|
+
),
|
|
126
|
+
forecast_times AS (
|
|
127
|
+
SELECT
|
|
128
|
+
last_time + (INTERVAL '1 hour' * generate_series(1, $1)) as forecast_time
|
|
129
|
+
FROM regression
|
|
130
|
+
)
|
|
131
|
+
SELECT
|
|
132
|
+
forecast_time as timestamp,
|
|
133
|
+
(intercept + slope * EXTRACT(EPOCH FROM forecast_time))::float as forecast_value
|
|
134
|
+
FROM forecast_times, regression
|
|
135
|
+
`;
|
|
136
|
+
const result = await this.pool.query(query, [periods]);
|
|
137
|
+
return result.rows.map((row) => ({
|
|
138
|
+
timestamp: row.timestamp,
|
|
139
|
+
values: { [column]: row.forecast_value, forecast: true },
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
// Seasonal decomposition would require more complex logic
|
|
143
|
+
logger.warn('Seasonal forecasting not yet implemented');
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
async getRetentionPolicy() {
|
|
147
|
+
const query = `
|
|
148
|
+
SELECT
|
|
149
|
+
hypertable_name as table_name,
|
|
150
|
+
drop_after::text as retention_period,
|
|
151
|
+
schedule_interval IS NOT NULL as is_enabled
|
|
152
|
+
FROM timescaledb_information.retention_policies
|
|
153
|
+
WHERE hypertable_name = $1
|
|
154
|
+
`;
|
|
155
|
+
const result = await this.pool.query(query, [this.config.tableName]);
|
|
156
|
+
return result.rows.map((row) => ({
|
|
157
|
+
tableName: row.table_name,
|
|
158
|
+
retentionPeriod: row.retention_period,
|
|
159
|
+
isEnabled: row.is_enabled,
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
async setRetentionPolicy(retentionPeriod) {
|
|
163
|
+
const query = `
|
|
164
|
+
SELECT add_retention_policy($1,
|
|
165
|
+
drop_after => INTERVAL '${retentionPeriod}',
|
|
166
|
+
if_not_exists => TRUE
|
|
167
|
+
)
|
|
168
|
+
`;
|
|
169
|
+
await this.pool.query(query, [this.config.tableName]);
|
|
170
|
+
logger.info(`Set retention policy for ${this.config.tableName}: ${retentionPeriod}`);
|
|
171
|
+
}
|
|
172
|
+
async compress(olderThan) {
|
|
173
|
+
// Enable compression
|
|
174
|
+
await this.pool.query(`
|
|
175
|
+
ALTER TABLE ${this.config.tableName}
|
|
176
|
+
SET (timescaledb.compress,
|
|
177
|
+
timescaledb.compress_segmentby = 'type',
|
|
178
|
+
timescaledb.compress_orderby = '${this.config.timeColumn} DESC')
|
|
179
|
+
`);
|
|
180
|
+
// Add compression policy
|
|
181
|
+
await this.pool.query(`
|
|
182
|
+
SELECT add_compression_policy($1,
|
|
183
|
+
compress_after => INTERVAL '${olderThan}',
|
|
184
|
+
if_not_exists => TRUE
|
|
185
|
+
)
|
|
186
|
+
`, [this.config.tableName]);
|
|
187
|
+
logger.info(`Enabled compression for ${this.config.tableName} older than ${olderThan}`);
|
|
188
|
+
}
|
|
189
|
+
async getChunkStats() {
|
|
190
|
+
const query = `
|
|
191
|
+
SELECT
|
|
192
|
+
COUNT(*) as total_chunks,
|
|
193
|
+
COUNT(*) FILTER (WHERE is_compressed) as compressed_chunks,
|
|
194
|
+
pg_size_pretty(SUM(total_bytes)) as total_size,
|
|
195
|
+
pg_size_pretty(SUM(total_bytes) FILTER (WHERE is_compressed)) as compressed_size,
|
|
196
|
+
CASE
|
|
197
|
+
WHEN SUM(uncompressed_total_bytes) > 0
|
|
198
|
+
THEN (1 - SUM(total_bytes)::float / SUM(uncompressed_total_bytes))::numeric(4,2)
|
|
199
|
+
ELSE 0
|
|
200
|
+
END as compression_ratio
|
|
201
|
+
FROM timescaledb_information.chunks
|
|
202
|
+
WHERE hypertable_name = $1
|
|
203
|
+
`;
|
|
204
|
+
const result = await this.pool.query(query, [this.config.tableName]);
|
|
205
|
+
const row = result.rows[0];
|
|
206
|
+
return {
|
|
207
|
+
totalChunks: parseInt(row.total_chunks) || 0,
|
|
208
|
+
compressedChunks: parseInt(row.compressed_chunks) || 0,
|
|
209
|
+
totalSize: row.total_size || '0 bytes',
|
|
210
|
+
compressedSize: row.compressed_size || '0 bytes',
|
|
211
|
+
compressionRatio: parseFloat(row.compression_ratio) || 0,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=timescale-analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timescale-analytics.js","sourceRoot":"","sources":["../../../../src/integrations/pg-aiguide/timescale-analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
type Database = BetterSqlite3.Database;
|
|
3
|
+
export interface User {
|
|
4
|
+
id: string;
|
|
5
|
+
sub: string;
|
|
6
|
+
email: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
avatar?: string;
|
|
9
|
+
tier: 'free' | 'pro' | 'enterprise';
|
|
10
|
+
permissions: string[];
|
|
11
|
+
organizations: Array<{
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
role: string;
|
|
15
|
+
}>;
|
|
16
|
+
apiKeys?: string[];
|
|
17
|
+
createdAt: Date;
|
|
18
|
+
updatedAt: Date;
|
|
19
|
+
lastLoginAt?: Date;
|
|
20
|
+
metadata?: Record<string, any>;
|
|
21
|
+
}
|
|
22
|
+
export interface UserSession {
|
|
23
|
+
id: string;
|
|
24
|
+
userId: string;
|
|
25
|
+
token: string;
|
|
26
|
+
expiresAt: Date;
|
|
27
|
+
createdAt: Date;
|
|
28
|
+
metadata?: Record<string, any>;
|
|
29
|
+
}
|
|
30
|
+
export declare class UserModel {
|
|
31
|
+
private db;
|
|
32
|
+
constructor(db: Database);
|
|
33
|
+
private initialize;
|
|
34
|
+
createUser(userData: Partial<User>): Promise<User>;
|
|
35
|
+
findUserBySub(sub: string): Promise<User | null>;
|
|
36
|
+
findUserByEmail(email: string): Promise<User | null>;
|
|
37
|
+
findUserById(id: string): Promise<User | null>;
|
|
38
|
+
updateUser(id: string, updates: Partial<User>): Promise<User | null>;
|
|
39
|
+
deleteUser(id: string): Promise<boolean>;
|
|
40
|
+
updateLastLogin(id: string): Promise<void>;
|
|
41
|
+
createSession(userId: string, expiresIn?: number): Promise<UserSession>;
|
|
42
|
+
findSessionByToken(token: string): Promise<UserSession | null>;
|
|
43
|
+
validateSession(token: string): Promise<User | null>;
|
|
44
|
+
deleteSession(id: string): Promise<boolean>;
|
|
45
|
+
deleteExpiredSessions(): Promise<number>;
|
|
46
|
+
generateApiKey(userId: string): Promise<string>;
|
|
47
|
+
validateApiKey(apiKey: string): Promise<User | null>;
|
|
48
|
+
private rowToUser;
|
|
49
|
+
private rowToSession;
|
|
50
|
+
private generateSessionToken;
|
|
51
|
+
private generateToken;
|
|
52
|
+
}
|
|
53
|
+
export declare function getUserModel(db: BetterSqlite3.Database): UserModel;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=user.model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.model.d.ts","sourceRoot":"","sources":["../../../src/models/user.model.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAK3C,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAEvC,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,YAAY,CAAC;IACpC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,KAAK,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,EAAE,CAAW;gBAET,EAAE,EAAE,QAAQ;IAKxB,OAAO,CAAC,UAAU;IA6CZ,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA0ClD,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAWhD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAWpD,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAW9C,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAsCpE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYxC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1C,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,WAAW,CAAC;IA4BtE,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAW9D,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAiBpD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM3C,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAcxC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB/C,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAuB1D,OAAO,CAAC,SAAS;IAkBjB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,aAAa;CAStB;AAKD,wBAAgB,YAAY,CAAC,EAAE,EAAE,aAAa,CAAC,QAAQ,GAAG,SAAS,CAKlE"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import * as bcrypt from 'bcryptjs';
|
|
3
|
+
import { logger } from '../core/monitoring/logger.js';
|
|
4
|
+
export class UserModel {
|
|
5
|
+
db;
|
|
6
|
+
constructor(db) {
|
|
7
|
+
this.db = db;
|
|
8
|
+
this.initialize();
|
|
9
|
+
}
|
|
10
|
+
initialize() {
|
|
11
|
+
// Create users table
|
|
12
|
+
this.db.exec(`
|
|
13
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
14
|
+
id TEXT PRIMARY KEY,
|
|
15
|
+
sub TEXT UNIQUE NOT NULL,
|
|
16
|
+
email TEXT UNIQUE NOT NULL,
|
|
17
|
+
name TEXT,
|
|
18
|
+
avatar TEXT,
|
|
19
|
+
tier TEXT DEFAULT 'free',
|
|
20
|
+
permissions TEXT DEFAULT '["read", "write"]',
|
|
21
|
+
organizations TEXT DEFAULT '[]',
|
|
22
|
+
api_keys TEXT DEFAULT '[]',
|
|
23
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
24
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
25
|
+
last_login_at DATETIME,
|
|
26
|
+
metadata TEXT DEFAULT '{}'
|
|
27
|
+
)
|
|
28
|
+
`);
|
|
29
|
+
// Create sessions table
|
|
30
|
+
this.db.exec(`
|
|
31
|
+
CREATE TABLE IF NOT EXISTS user_sessions (
|
|
32
|
+
id TEXT PRIMARY KEY,
|
|
33
|
+
user_id TEXT NOT NULL,
|
|
34
|
+
token TEXT UNIQUE NOT NULL,
|
|
35
|
+
expires_at DATETIME NOT NULL,
|
|
36
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
37
|
+
metadata TEXT DEFAULT '{}',
|
|
38
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
39
|
+
)
|
|
40
|
+
`);
|
|
41
|
+
// Create indexes
|
|
42
|
+
this.db.exec(`
|
|
43
|
+
CREATE INDEX IF NOT EXISTS idx_users_sub ON users(sub);
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
|
45
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_token ON user_sessions(token);
|
|
46
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_user ON user_sessions(user_id);
|
|
47
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_expires ON user_sessions(expires_at);
|
|
48
|
+
`);
|
|
49
|
+
logger.info('User database schema initialized');
|
|
50
|
+
}
|
|
51
|
+
async createUser(userData) {
|
|
52
|
+
const user = {
|
|
53
|
+
id: userData.id || uuidv4(),
|
|
54
|
+
sub: userData.sub,
|
|
55
|
+
email: userData.email,
|
|
56
|
+
name: userData.name,
|
|
57
|
+
avatar: userData.avatar,
|
|
58
|
+
tier: userData.tier || 'free',
|
|
59
|
+
permissions: userData.permissions || ['read', 'write'],
|
|
60
|
+
organizations: userData.organizations || [],
|
|
61
|
+
apiKeys: userData.apiKeys || [],
|
|
62
|
+
createdAt: new Date(),
|
|
63
|
+
updatedAt: new Date(),
|
|
64
|
+
metadata: userData.metadata || {},
|
|
65
|
+
};
|
|
66
|
+
const stmt = this.db.prepare(`
|
|
67
|
+
INSERT INTO users (
|
|
68
|
+
id, sub, email, name, avatar, tier, permissions,
|
|
69
|
+
organizations, api_keys, created_at, updated_at, metadata
|
|
70
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
71
|
+
`);
|
|
72
|
+
stmt.run(user.id, user.sub, user.email, user.name, user.avatar, user.tier, JSON.stringify(user.permissions), JSON.stringify(user.organizations), JSON.stringify(user.apiKeys), user.createdAt.toISOString(), user.updatedAt.toISOString(), JSON.stringify(user.metadata));
|
|
73
|
+
logger.info('User created', { userId: user.id, email: user.email });
|
|
74
|
+
return user;
|
|
75
|
+
}
|
|
76
|
+
async findUserBySub(sub) {
|
|
77
|
+
const stmt = this.db.prepare('SELECT * FROM users WHERE sub = ?');
|
|
78
|
+
const row = stmt.get(sub);
|
|
79
|
+
if (!row) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return this.rowToUser(row);
|
|
83
|
+
}
|
|
84
|
+
async findUserByEmail(email) {
|
|
85
|
+
const stmt = this.db.prepare('SELECT * FROM users WHERE email = ?');
|
|
86
|
+
const row = stmt.get(email);
|
|
87
|
+
if (!row) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return this.rowToUser(row);
|
|
91
|
+
}
|
|
92
|
+
async findUserById(id) {
|
|
93
|
+
const stmt = this.db.prepare('SELECT * FROM users WHERE id = ?');
|
|
94
|
+
const row = stmt.get(id);
|
|
95
|
+
if (!row) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return this.rowToUser(row);
|
|
99
|
+
}
|
|
100
|
+
async updateUser(id, updates) {
|
|
101
|
+
const user = await this.findUserById(id);
|
|
102
|
+
if (!user) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const updatedUser = {
|
|
106
|
+
...user,
|
|
107
|
+
...updates,
|
|
108
|
+
updatedAt: new Date(),
|
|
109
|
+
};
|
|
110
|
+
const stmt = this.db.prepare(`
|
|
111
|
+
UPDATE users SET
|
|
112
|
+
email = ?, name = ?, avatar = ?, tier = ?,
|
|
113
|
+
permissions = ?, organizations = ?, api_keys = ?,
|
|
114
|
+
updated_at = ?, last_login_at = ?, metadata = ?
|
|
115
|
+
WHERE id = ?
|
|
116
|
+
`);
|
|
117
|
+
stmt.run(updatedUser.email, updatedUser.name, updatedUser.avatar, updatedUser.tier, JSON.stringify(updatedUser.permissions), JSON.stringify(updatedUser.organizations), JSON.stringify(updatedUser.apiKeys), updatedUser.updatedAt.toISOString(), updatedUser.lastLoginAt?.toISOString(), JSON.stringify(updatedUser.metadata), id);
|
|
118
|
+
logger.info('User updated', { userId: id });
|
|
119
|
+
return updatedUser;
|
|
120
|
+
}
|
|
121
|
+
async deleteUser(id) {
|
|
122
|
+
const stmt = this.db.prepare('DELETE FROM users WHERE id = ?');
|
|
123
|
+
const result = stmt.run(id);
|
|
124
|
+
if (result.changes > 0) {
|
|
125
|
+
logger.info('User deleted', { userId: id });
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
async updateLastLogin(id) {
|
|
131
|
+
const stmt = this.db.prepare('UPDATE users SET last_login_at = ? WHERE id = ?');
|
|
132
|
+
stmt.run(new Date().toISOString(), id);
|
|
133
|
+
}
|
|
134
|
+
// Session management
|
|
135
|
+
async createSession(userId, expiresIn = 86400) {
|
|
136
|
+
const session = {
|
|
137
|
+
id: uuidv4(),
|
|
138
|
+
userId,
|
|
139
|
+
token: this.generateSessionToken(),
|
|
140
|
+
expiresAt: new Date(Date.now() + expiresIn * 1000),
|
|
141
|
+
createdAt: new Date(),
|
|
142
|
+
metadata: {},
|
|
143
|
+
};
|
|
144
|
+
const stmt = this.db.prepare(`
|
|
145
|
+
INSERT INTO user_sessions (id, user_id, token, expires_at, created_at, metadata)
|
|
146
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
147
|
+
`);
|
|
148
|
+
stmt.run(session.id, session.userId, session.token, session.expiresAt.toISOString(), session.createdAt.toISOString(), JSON.stringify(session.metadata));
|
|
149
|
+
logger.info('Session created', { sessionId: session.id, userId });
|
|
150
|
+
return session;
|
|
151
|
+
}
|
|
152
|
+
async findSessionByToken(token) {
|
|
153
|
+
const stmt = this.db.prepare('SELECT * FROM user_sessions WHERE token = ?');
|
|
154
|
+
const row = stmt.get(token);
|
|
155
|
+
if (!row) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
return this.rowToSession(row);
|
|
159
|
+
}
|
|
160
|
+
async validateSession(token) {
|
|
161
|
+
const session = await this.findSessionByToken(token);
|
|
162
|
+
if (!session) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
// Check if session is expired
|
|
166
|
+
if (new Date(session.expiresAt) < new Date()) {
|
|
167
|
+
await this.deleteSession(session.id);
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
// Get the user
|
|
171
|
+
return await this.findUserById(session.userId);
|
|
172
|
+
}
|
|
173
|
+
async deleteSession(id) {
|
|
174
|
+
const stmt = this.db.prepare('DELETE FROM user_sessions WHERE id = ?');
|
|
175
|
+
const result = stmt.run(id);
|
|
176
|
+
return result.changes > 0;
|
|
177
|
+
}
|
|
178
|
+
async deleteExpiredSessions() {
|
|
179
|
+
const stmt = this.db.prepare('DELETE FROM user_sessions WHERE expires_at < ?');
|
|
180
|
+
const result = stmt.run(new Date().toISOString());
|
|
181
|
+
if (result.changes > 0) {
|
|
182
|
+
logger.info('Expired sessions deleted', { count: result.changes });
|
|
183
|
+
}
|
|
184
|
+
return result.changes;
|
|
185
|
+
}
|
|
186
|
+
// API Key management
|
|
187
|
+
async generateApiKey(userId) {
|
|
188
|
+
const apiKey = `sk-${this.generateToken(32)}`;
|
|
189
|
+
const user = await this.findUserById(userId);
|
|
190
|
+
if (!user) {
|
|
191
|
+
throw new Error('User not found');
|
|
192
|
+
}
|
|
193
|
+
const hashedKey = await bcrypt.hash(apiKey, 10);
|
|
194
|
+
const apiKeys = [...(user.apiKeys || []), hashedKey];
|
|
195
|
+
await this.updateUser(userId, { apiKeys });
|
|
196
|
+
logger.info('API key generated', { userId });
|
|
197
|
+
return apiKey;
|
|
198
|
+
}
|
|
199
|
+
async validateApiKey(apiKey) {
|
|
200
|
+
// This is inefficient for large scale, but works for small deployments
|
|
201
|
+
// For production, consider a separate api_keys table
|
|
202
|
+
const stmt = this.db.prepare('SELECT * FROM users WHERE api_keys IS NOT NULL');
|
|
203
|
+
const rows = stmt.all();
|
|
204
|
+
for (const row of rows) {
|
|
205
|
+
const user = this.rowToUser(row);
|
|
206
|
+
const apiKeys = user.apiKeys || [];
|
|
207
|
+
for (const hashedKey of apiKeys) {
|
|
208
|
+
if (await bcrypt.compare(apiKey, hashedKey)) {
|
|
209
|
+
return user;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
// Helper methods
|
|
216
|
+
rowToUser(row) {
|
|
217
|
+
return {
|
|
218
|
+
id: row.id,
|
|
219
|
+
sub: row.sub,
|
|
220
|
+
email: row.email,
|
|
221
|
+
name: row.name,
|
|
222
|
+
avatar: row.avatar,
|
|
223
|
+
tier: row.tier,
|
|
224
|
+
permissions: JSON.parse(row.permissions),
|
|
225
|
+
organizations: JSON.parse(row.organizations),
|
|
226
|
+
apiKeys: JSON.parse(row.api_keys || '[]'),
|
|
227
|
+
createdAt: new Date(row.created_at),
|
|
228
|
+
updatedAt: new Date(row.updated_at),
|
|
229
|
+
lastLoginAt: row.last_login_at ? new Date(row.last_login_at) : undefined,
|
|
230
|
+
metadata: JSON.parse(row.metadata || '{}'),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
rowToSession(row) {
|
|
234
|
+
return {
|
|
235
|
+
id: row.id,
|
|
236
|
+
userId: row.user_id,
|
|
237
|
+
token: row.token,
|
|
238
|
+
expiresAt: new Date(row.expires_at),
|
|
239
|
+
createdAt: new Date(row.created_at),
|
|
240
|
+
metadata: JSON.parse(row.metadata || '{}'),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
generateSessionToken() {
|
|
244
|
+
return this.generateToken(48);
|
|
245
|
+
}
|
|
246
|
+
generateToken(length) {
|
|
247
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
248
|
+
let token = '';
|
|
249
|
+
for (let i = 0; i < length; i++) {
|
|
250
|
+
token += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
251
|
+
}
|
|
252
|
+
return token;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Singleton instance management
|
|
256
|
+
let userModelInstance = null;
|
|
257
|
+
export function getUserModel(db) {
|
|
258
|
+
if (!userModelInstance) {
|
|
259
|
+
userModelInstance = new UserModel(db);
|
|
260
|
+
}
|
|
261
|
+
return userModelInstance;
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=user.model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.model.js","sourceRoot":"","sources":["../../../src/models/user.model.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,12 +25,15 @@ export declare class AuthMiddleware {
|
|
|
25
25
|
private redis;
|
|
26
26
|
private rateLimiters;
|
|
27
27
|
private blacklistedTokens;
|
|
28
|
+
private userModel;
|
|
29
|
+
private db;
|
|
28
30
|
constructor(config: {
|
|
29
31
|
auth0Domain: string;
|
|
30
32
|
auth0Audience: string;
|
|
31
33
|
redisUrl: string;
|
|
32
34
|
jwtSecret?: string;
|
|
33
35
|
bypassAuth?: boolean;
|
|
36
|
+
dbPath?: string;
|
|
34
37
|
});
|
|
35
38
|
private initializeRateLimiters;
|
|
36
39
|
private setupTokenBlacklistSync;
|
|
@@ -51,8 +54,12 @@ export declare class AuthMiddleware {
|
|
|
51
54
|
* Organization access middleware
|
|
52
55
|
*/
|
|
53
56
|
requireOrganization: (req: AuthRequest, res: Response, next: NextFunction) => Response<any, Record<string, any>> | undefined;
|
|
57
|
+
private extractApiKey;
|
|
54
58
|
private extractToken;
|
|
55
59
|
private loadUser;
|
|
60
|
+
private determineTier;
|
|
61
|
+
private determinePermissions;
|
|
62
|
+
private extractOrganizations;
|
|
56
63
|
private getMockUser;
|
|
57
64
|
/**
|
|
58
65
|
* Revoke a token (add to blacklist)
|