@benchcubed/today-cli 1.0.0
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/README.md +296 -0
- package/dist/ai/bedrock-client.d.ts +1 -0
- package/dist/ai/bedrock-client.d.ts.map +1 -0
- package/dist/ai/bedrock-client.js +2 -0
- package/dist/ai/bedrock-client.js.map +1 -0
- package/dist/ai/knowledge-processor.d.ts +1 -0
- package/dist/ai/knowledge-processor.d.ts.map +1 -0
- package/dist/ai/knowledge-processor.js +2 -0
- package/dist/ai/knowledge-processor.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +70 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/ask.d.ts +3 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +217 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/audit.d.ts +3 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +153 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +114 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +72 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/embeddings.d.ts +3 -0
- package/dist/commands/embeddings.d.ts.map +1 -0
- package/dist/commands/embeddings.js +118 -0
- package/dist/commands/embeddings.js.map +1 -0
- package/dist/commands/experts.d.ts +3 -0
- package/dist/commands/experts.d.ts.map +1 -0
- package/dist/commands/experts.js +129 -0
- package/dist/commands/experts.js.map +1 -0
- package/dist/commands/export-import.d.ts +4 -0
- package/dist/commands/export-import.d.ts.map +1 -0
- package/dist/commands/export-import.js +285 -0
- package/dist/commands/export-import.js.map +1 -0
- package/dist/commands/git.d.ts +4 -0
- package/dist/commands/git.d.ts.map +1 -0
- package/dist/commands/git.js +274 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/impact.d.ts +3 -0
- package/dist/commands/impact.d.ts.map +1 -0
- package/dist/commands/impact.js +121 -0
- package/dist/commands/impact.js.map +1 -0
- package/dist/commands/insights.d.ts +3 -0
- package/dist/commands/insights.d.ts.map +1 -0
- package/dist/commands/insights.js +113 -0
- package/dist/commands/insights.js.map +1 -0
- package/dist/commands/learned.d.ts +3 -0
- package/dist/commands/learned.d.ts.map +1 -0
- package/dist/commands/learned.js +355 -0
- package/dist/commands/learned.js.map +1 -0
- package/dist/commands/onboard.d.ts +3 -0
- package/dist/commands/onboard.d.ts.map +1 -0
- package/dist/commands/onboard.js +141 -0
- package/dist/commands/onboard.js.map +1 -0
- package/dist/commands/recent.d.ts +3 -0
- package/dist/commands/recent.d.ts.map +1 -0
- package/dist/commands/recent.js +83 -0
- package/dist/commands/recent.js.map +1 -0
- package/dist/commands/secrets.d.ts +3 -0
- package/dist/commands/secrets.d.ts.map +1 -0
- package/dist/commands/secrets.js +203 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/stats.d.ts +3 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +120 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/config/index.d.ts +12 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +46 -0
- package/dist/config/index.js.map +1 -0
- package/dist/database/migrations.d.ts +13 -0
- package/dist/database/migrations.d.ts.map +1 -0
- package/dist/database/migrations.js +190 -0
- package/dist/database/migrations.js.map +1 -0
- package/dist/database/postgresql.d.ts +92 -0
- package/dist/database/postgresql.d.ts.map +1 -0
- package/dist/database/postgresql.js +382 -0
- package/dist/database/postgresql.js.map +1 -0
- package/dist/database/sqlite.d.ts +54 -0
- package/dist/database/sqlite.d.ts.map +1 -0
- package/dist/database/sqlite.js +337 -0
- package/dist/database/sqlite.js.map +1 -0
- package/dist/lambda/admin.d.ts +3 -0
- package/dist/lambda/admin.d.ts.map +1 -0
- package/dist/lambda/admin.js +818 -0
- package/dist/lambda/admin.js.map +1 -0
- package/dist/lambda/ai-services.d.ts +6 -0
- package/dist/lambda/ai-services.d.ts.map +1 -0
- package/dist/lambda/ai-services.js +472 -0
- package/dist/lambda/ai-services.js.map +1 -0
- package/dist/lambda/analytics.d.ts +3 -0
- package/dist/lambda/analytics.d.ts.map +1 -0
- package/dist/lambda/analytics.js +481 -0
- package/dist/lambda/analytics.js.map +1 -0
- package/dist/lambda/api-router.d.ts +3 -0
- package/dist/lambda/api-router.d.ts.map +1 -0
- package/dist/lambda/api-router.js +162 -0
- package/dist/lambda/api-router.js.map +1 -0
- package/dist/lambda/custom-topics.d.ts +3 -0
- package/dist/lambda/custom-topics.d.ts.map +1 -0
- package/dist/lambda/custom-topics.js +425 -0
- package/dist/lambda/custom-topics.js.map +1 -0
- package/dist/lambda/graph-builder.d.ts +3 -0
- package/dist/lambda/graph-builder.d.ts.map +1 -0
- package/dist/lambda/graph-builder.js +442 -0
- package/dist/lambda/graph-builder.js.map +1 -0
- package/dist/lambda/knowledge-ai.d.ts +3 -0
- package/dist/lambda/knowledge-ai.d.ts.map +1 -0
- package/dist/lambda/knowledge-ai.js +849 -0
- package/dist/lambda/knowledge-ai.js.map +1 -0
- package/dist/lambda/post-confirmation.d.ts +8 -0
- package/dist/lambda/post-confirmation.d.ts.map +1 -0
- package/dist/lambda/post-confirmation.js +92 -0
- package/dist/lambda/post-confirmation.js.map +1 -0
- package/dist/lambda/teams.d.ts +3 -0
- package/dist/lambda/teams.d.ts.map +1 -0
- package/dist/lambda/teams.js +568 -0
- package/dist/lambda/teams.js.map +1 -0
- package/dist/lib/export-helpers.d.ts +5 -0
- package/dist/lib/export-helpers.d.ts.map +1 -0
- package/dist/lib/export-helpers.js +137 -0
- package/dist/lib/export-helpers.js.map +1 -0
- package/dist/lib/import-helpers.d.ts +5 -0
- package/dist/lib/import-helpers.d.ts.map +1 -0
- package/dist/lib/import-helpers.js +185 -0
- package/dist/lib/import-helpers.js.map +1 -0
- package/dist/lib/insights-helpers.d.ts +123 -0
- package/dist/lib/insights-helpers.d.ts.map +1 -0
- package/dist/lib/insights-helpers.js +374 -0
- package/dist/lib/insights-helpers.js.map +1 -0
- package/dist/lib/search-helpers.d.ts +4 -0
- package/dist/lib/search-helpers.d.ts.map +1 -0
- package/dist/lib/search-helpers.js +124 -0
- package/dist/lib/search-helpers.js.map +1 -0
- package/dist/lib/secret-helpers.d.ts +2 -0
- package/dist/lib/secret-helpers.d.ts.map +1 -0
- package/dist/lib/secret-helpers.js +85 -0
- package/dist/lib/secret-helpers.js.map +1 -0
- package/dist/lib/stats-helpers.d.ts +41 -0
- package/dist/lib/stats-helpers.d.ts.map +1 -0
- package/dist/lib/stats-helpers.js +263 -0
- package/dist/lib/stats-helpers.js.map +1 -0
- package/dist/services/aws-api.d.ts +81 -0
- package/dist/services/aws-api.d.ts.map +1 -0
- package/dist/services/aws-api.js +388 -0
- package/dist/services/aws-api.js.map +1 -0
- package/dist/services/bedrock.d.ts +83 -0
- package/dist/services/bedrock.d.ts.map +1 -0
- package/dist/services/bedrock.js +434 -0
- package/dist/services/bedrock.js.map +1 -0
- package/dist/services/commit-learnings.d.ts +25 -0
- package/dist/services/commit-learnings.d.ts.map +1 -0
- package/dist/services/commit-learnings.js +180 -0
- package/dist/services/commit-learnings.js.map +1 -0
- package/dist/services/embedding-storage.d.ts +42 -0
- package/dist/services/embedding-storage.d.ts.map +1 -0
- package/dist/services/embedding-storage.js +124 -0
- package/dist/services/embedding-storage.js.map +1 -0
- package/dist/services/expert-engine.d.ts +21 -0
- package/dist/services/expert-engine.d.ts.map +1 -0
- package/dist/services/expert-engine.js +58 -0
- package/dist/services/expert-engine.js.map +1 -0
- package/dist/services/onboarding-accelerator.d.ts +118 -0
- package/dist/services/onboarding-accelerator.d.ts.map +1 -0
- package/dist/services/onboarding-accelerator.js +403 -0
- package/dist/services/onboarding-accelerator.js.map +1 -0
- package/dist/services/secret-detection.d.ts +46 -0
- package/dist/services/secret-detection.d.ts.map +1 -0
- package/dist/services/secret-detection.js +75 -0
- package/dist/services/secret-detection.js.map +1 -0
- package/dist/services/secret-manager-simple.d.ts +51 -0
- package/dist/services/secret-manager-simple.d.ts.map +1 -0
- package/dist/services/secret-manager-simple.js +119 -0
- package/dist/services/secret-manager-simple.js.map +1 -0
- package/dist/services/secret-manager.d.ts +150 -0
- package/dist/services/secret-manager.d.ts.map +1 -0
- package/dist/services/secret-manager.js +287 -0
- package/dist/services/secret-manager.js.map +1 -0
- package/dist/services/vector-embeddings.d.ts +70 -0
- package/dist/services/vector-embeddings.d.ts.map +1 -0
- package/dist/services/vector-embeddings.js +167 -0
- package/dist/services/vector-embeddings.js.map +1 -0
- package/dist/services/vector-search.d.ts +28 -0
- package/dist/services/vector-search.d.ts.map +1 -0
- package/dist/services/vector-search.js +192 -0
- package/dist/services/vector-search.js.map +1 -0
- package/dist/types/index.d.ts +86 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/formatting.d.ts +10 -0
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/utils/formatting.js +82 -0
- package/dist/utils/formatting.js.map +1 -0
- package/dist/utils/git.d.ts +52 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +182 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/validation.d.ts +17 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +187 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handler = void 0;
|
|
4
|
+
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
+
// Initialize AWS clients
|
|
6
|
+
const dynamoClient = new client_dynamodb_1.DynamoDBClient({});
|
|
7
|
+
// Helper function to decode JWT token (without verification for simplicity)
|
|
8
|
+
// In production, you should verify the signature against Cognito public keys
|
|
9
|
+
function decodeJWT(token) {
|
|
10
|
+
try {
|
|
11
|
+
const parts = token.split('.');
|
|
12
|
+
if (parts.length !== 3)
|
|
13
|
+
return null;
|
|
14
|
+
const payload = Buffer.from(parts[1], 'base64').toString('utf8');
|
|
15
|
+
return JSON.parse(payload);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
console.error('Failed to decode JWT:', error);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Extract user info from Authorization header
|
|
23
|
+
function getUserFromAuth(event) {
|
|
24
|
+
const authHeader = event.headers?.Authorization || event.headers?.authorization;
|
|
25
|
+
if (!authHeader)
|
|
26
|
+
return null;
|
|
27
|
+
const token = authHeader.replace('Bearer ', '');
|
|
28
|
+
const decoded = decodeJWT(token);
|
|
29
|
+
if (!decoded || !decoded.sub)
|
|
30
|
+
return null;
|
|
31
|
+
return {
|
|
32
|
+
userId: decoded.sub,
|
|
33
|
+
teamId: decoded['custom:team_id'] || 'default'
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const handler = async (event) => {
|
|
37
|
+
const headers = {
|
|
38
|
+
'Content-Type': 'application/json',
|
|
39
|
+
'Access-Control-Allow-Origin': '*',
|
|
40
|
+
'Access-Control-Allow-Headers': 'Content-Type,Authorization',
|
|
41
|
+
'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTIONS',
|
|
42
|
+
};
|
|
43
|
+
console.log('Analytics Lambda event:', JSON.stringify(event, null, 2));
|
|
44
|
+
try {
|
|
45
|
+
const { httpMethod, path, pathParameters, queryStringParameters } = event;
|
|
46
|
+
// Extract the actual route from the proxy parameter or path
|
|
47
|
+
const routePath = pathParameters?.proxy || path.split('/').pop() || '';
|
|
48
|
+
// Handle routes like "analytics/metrics" -> "metrics" or just "metrics"
|
|
49
|
+
const route = routePath.split('/').pop() || routePath;
|
|
50
|
+
console.log('Analytics Lambda called:', { httpMethod, path, route, pathParameters, queryStringParameters });
|
|
51
|
+
// Handle OPTIONS requests for CORS preflight
|
|
52
|
+
if (httpMethod === 'OPTIONS') {
|
|
53
|
+
return {
|
|
54
|
+
statusCode: 200,
|
|
55
|
+
headers,
|
|
56
|
+
body: '',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// Handle public demo endpoint (no auth required)
|
|
60
|
+
if (route === 'demo' && httpMethod === 'GET') {
|
|
61
|
+
console.log('Handling public demo endpoint');
|
|
62
|
+
return await generateDemoMetrics();
|
|
63
|
+
}
|
|
64
|
+
// Handle metrics endpoint
|
|
65
|
+
if (route === 'metrics' && httpMethod === 'GET') {
|
|
66
|
+
// Extract user info from Authorization header
|
|
67
|
+
const userInfo = getUserFromAuth(event);
|
|
68
|
+
if (!userInfo) {
|
|
69
|
+
return {
|
|
70
|
+
statusCode: 401,
|
|
71
|
+
headers,
|
|
72
|
+
body: JSON.stringify({ error: 'Unauthorized' }),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const { userId, teamId } = userInfo;
|
|
76
|
+
const type = queryStringParameters?.type || 'roi';
|
|
77
|
+
const timeframe = queryStringParameters?.timeframe || '30d';
|
|
78
|
+
switch (type) {
|
|
79
|
+
case 'roi':
|
|
80
|
+
return await generateROIReport(teamId, timeframe);
|
|
81
|
+
case 'engagement':
|
|
82
|
+
return await calculateEngagementScore(userId, teamId);
|
|
83
|
+
case 'onboarding':
|
|
84
|
+
return await trackOnboardingImpact(userId, teamId);
|
|
85
|
+
default:
|
|
86
|
+
return await generateROIReport(teamId, timeframe);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// POST to record productivity metrics
|
|
90
|
+
if (route === 'metrics' && httpMethod === 'POST') {
|
|
91
|
+
// Extract user info from Authorization header
|
|
92
|
+
const userInfo = getUserFromAuth(event);
|
|
93
|
+
if (!userInfo) {
|
|
94
|
+
return {
|
|
95
|
+
statusCode: 401,
|
|
96
|
+
headers,
|
|
97
|
+
body: JSON.stringify({ error: 'Unauthorized' }),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const { userId, teamId } = userInfo;
|
|
101
|
+
const body = JSON.parse(event.body || '{}');
|
|
102
|
+
return await recordProductivityImpact(body, userId, teamId);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
statusCode: 404,
|
|
106
|
+
headers,
|
|
107
|
+
body: JSON.stringify({ error: 'Route not found', route, httpMethod }),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
console.error('Analytics Lambda error:', error);
|
|
112
|
+
return {
|
|
113
|
+
statusCode: 500,
|
|
114
|
+
headers,
|
|
115
|
+
body: JSON.stringify({
|
|
116
|
+
error: 'Internal server error',
|
|
117
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
118
|
+
}),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
exports.handler = handler;
|
|
123
|
+
async function generateROIReport(teamId, timeframe) {
|
|
124
|
+
const headers = {
|
|
125
|
+
'Content-Type': 'application/json',
|
|
126
|
+
'Access-Control-Allow-Origin': '*',
|
|
127
|
+
};
|
|
128
|
+
try {
|
|
129
|
+
// Calculate date range
|
|
130
|
+
const endDate = new Date();
|
|
131
|
+
const startDate = new Date();
|
|
132
|
+
const days = parseInt(timeframe.replace('d', '')) || 30;
|
|
133
|
+
startDate.setDate(endDate.getDate() - days);
|
|
134
|
+
// Query metrics from DynamoDB
|
|
135
|
+
const metricsResult = await dynamoClient.send(new client_dynamodb_1.ScanCommand({
|
|
136
|
+
TableName: process.env.METRICS_TABLE,
|
|
137
|
+
FilterExpression: 'begins_with(team_date, :teamPrefix) AND created_at BETWEEN :start AND :end',
|
|
138
|
+
ExpressionAttributeValues: {
|
|
139
|
+
':teamPrefix': { S: `${teamId}#` },
|
|
140
|
+
':start': { S: startDate.toISOString() },
|
|
141
|
+
':end': { S: endDate.toISOString() },
|
|
142
|
+
},
|
|
143
|
+
}));
|
|
144
|
+
let totalTimeSaved = 0;
|
|
145
|
+
let totalQuestionsAnswered = 0;
|
|
146
|
+
let expertConnectionsMade = 0;
|
|
147
|
+
let onboardingTasksCompleted = 0;
|
|
148
|
+
const contributorMap = new Map();
|
|
149
|
+
if (metricsResult.Items) {
|
|
150
|
+
for (const item of metricsResult.Items) {
|
|
151
|
+
if (item.metric_data?.S) {
|
|
152
|
+
try {
|
|
153
|
+
const impact = JSON.parse(item.metric_data.S);
|
|
154
|
+
totalTimeSaved += impact.timesSavedMinutes;
|
|
155
|
+
totalQuestionsAnswered += impact.duplicateQuestionsAvoided;
|
|
156
|
+
expertConnectionsMade += impact.expertConnectionsMade;
|
|
157
|
+
onboardingTasksCompleted += impact.onboardingTasksCompleted;
|
|
158
|
+
// Track contributors
|
|
159
|
+
if (!contributorMap.has(impact.userId)) {
|
|
160
|
+
contributorMap.set(impact.userId, { contributions: 0, impact: 0 });
|
|
161
|
+
}
|
|
162
|
+
const contributor = contributorMap.get(impact.userId);
|
|
163
|
+
contributor.contributions += 1;
|
|
164
|
+
contributor.impact += impact.timesSavedMinutes;
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
console.warn('Failed to parse metric data:', e);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Calculate ROI metrics
|
|
173
|
+
const avgDeveloperHourlyRate = 75; // USD
|
|
174
|
+
const estimatedCostSavings = (totalTimeSaved / 60) * avgDeveloperHourlyRate;
|
|
175
|
+
const productivityGain = Math.min(totalTimeSaved / (days * 8 * 60) * 100, 100); // Max 100%
|
|
176
|
+
// Top contributors
|
|
177
|
+
const topContributors = Array.from(contributorMap.entries())
|
|
178
|
+
.map(([userId, data]) => ({
|
|
179
|
+
userId,
|
|
180
|
+
name: `User ${userId.substring(0, 8)}`, // In real app, fetch from user service
|
|
181
|
+
contributions: data.contributions,
|
|
182
|
+
impact: data.impact,
|
|
183
|
+
}))
|
|
184
|
+
.sort((a, b) => b.impact - a.impact)
|
|
185
|
+
.slice(0, 5);
|
|
186
|
+
const roiReport = {
|
|
187
|
+
teamId,
|
|
188
|
+
timeframe,
|
|
189
|
+
totalTimeSaved,
|
|
190
|
+
totalQuestionsAnswered,
|
|
191
|
+
knowledgeGapsIdentified: Math.floor(totalQuestionsAnswered * 0.3), // Estimate
|
|
192
|
+
expertConnectionsMade,
|
|
193
|
+
onboardingAcceleration: onboardingTasksCompleted,
|
|
194
|
+
estimatedCostSavings,
|
|
195
|
+
productivityGain,
|
|
196
|
+
topContributors,
|
|
197
|
+
};
|
|
198
|
+
return {
|
|
199
|
+
statusCode: 200,
|
|
200
|
+
headers,
|
|
201
|
+
body: JSON.stringify({
|
|
202
|
+
success: true,
|
|
203
|
+
report: roiReport,
|
|
204
|
+
generatedAt: new Date().toISOString(),
|
|
205
|
+
}),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
console.error('Error generating ROI report:', error);
|
|
210
|
+
return {
|
|
211
|
+
statusCode: 500,
|
|
212
|
+
headers,
|
|
213
|
+
body: JSON.stringify({
|
|
214
|
+
error: 'Failed to generate ROI report',
|
|
215
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
216
|
+
}),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async function calculateEngagementScore(userId, teamId) {
|
|
221
|
+
const headers = {
|
|
222
|
+
'Content-Type': 'application/json',
|
|
223
|
+
'Access-Control-Allow-Origin': '*',
|
|
224
|
+
};
|
|
225
|
+
try {
|
|
226
|
+
// Query user's metrics
|
|
227
|
+
const userMetricsResult = await dynamoClient.send(new client_dynamodb_1.ScanCommand({
|
|
228
|
+
TableName: process.env.METRICS_TABLE,
|
|
229
|
+
FilterExpression: 'begins_with(team_date, :teamPrefix) AND user_id = :userId',
|
|
230
|
+
ExpressionAttributeValues: {
|
|
231
|
+
':teamPrefix': { S: `${teamId}#` },
|
|
232
|
+
':userId': { S: userId },
|
|
233
|
+
},
|
|
234
|
+
}));
|
|
235
|
+
let totalEntries = 0;
|
|
236
|
+
let helpfulnessRating = 0;
|
|
237
|
+
let knowledgeShared = 0;
|
|
238
|
+
let questionsAnswered = 0;
|
|
239
|
+
let expertConnections = 0;
|
|
240
|
+
if (userMetricsResult.Items) {
|
|
241
|
+
for (const item of userMetricsResult.Items) {
|
|
242
|
+
if (item.metric_data?.S) {
|
|
243
|
+
try {
|
|
244
|
+
const impact = JSON.parse(item.metric_data.S);
|
|
245
|
+
totalEntries += 1;
|
|
246
|
+
knowledgeShared += impact.knowledgeReused;
|
|
247
|
+
questionsAnswered += impact.duplicateQuestionsAvoided;
|
|
248
|
+
expertConnections += impact.expertConnectionsMade;
|
|
249
|
+
}
|
|
250
|
+
catch (e) {
|
|
251
|
+
console.warn('Failed to parse user metric data:', e);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Calculate engagement score
|
|
257
|
+
const baseScore = totalEntries * 10;
|
|
258
|
+
const helpfulnessBonus = helpfulnessRating * 5;
|
|
259
|
+
const sharingBonus = knowledgeShared * 3;
|
|
260
|
+
const answerBonus = questionsAnswered * 7;
|
|
261
|
+
const connectionBonus = expertConnections * 15;
|
|
262
|
+
const overallScore = baseScore + helpfulnessBonus + sharingBonus + answerBonus + connectionBonus;
|
|
263
|
+
// Determine level
|
|
264
|
+
let level;
|
|
265
|
+
if (overallScore >= 1000)
|
|
266
|
+
level = 'platinum';
|
|
267
|
+
else if (overallScore >= 500)
|
|
268
|
+
level = 'gold';
|
|
269
|
+
else if (overallScore >= 200)
|
|
270
|
+
level = 'silver';
|
|
271
|
+
else
|
|
272
|
+
level = 'bronze';
|
|
273
|
+
const engagementScore = {
|
|
274
|
+
userId,
|
|
275
|
+
teamId,
|
|
276
|
+
totalEntries,
|
|
277
|
+
helpfulnessRating,
|
|
278
|
+
knowledgeShared,
|
|
279
|
+
questionsAnswered,
|
|
280
|
+
expertConnections,
|
|
281
|
+
overallScore,
|
|
282
|
+
level,
|
|
283
|
+
};
|
|
284
|
+
return {
|
|
285
|
+
statusCode: 200,
|
|
286
|
+
headers,
|
|
287
|
+
body: JSON.stringify({
|
|
288
|
+
success: true,
|
|
289
|
+
engagement: engagementScore,
|
|
290
|
+
calculatedAt: new Date().toISOString(),
|
|
291
|
+
}),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
console.error('Error calculating engagement score:', error);
|
|
296
|
+
return {
|
|
297
|
+
statusCode: 500,
|
|
298
|
+
headers,
|
|
299
|
+
body: JSON.stringify({
|
|
300
|
+
error: 'Failed to calculate engagement score',
|
|
301
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
302
|
+
}),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
async function trackOnboardingImpact(userId, teamId) {
|
|
307
|
+
const headers = {
|
|
308
|
+
'Content-Type': 'application/json',
|
|
309
|
+
'Access-Control-Allow-Origin': '*',
|
|
310
|
+
};
|
|
311
|
+
try {
|
|
312
|
+
// Query onboarding-specific metrics
|
|
313
|
+
const onboardingResult = await dynamoClient.send(new client_dynamodb_1.ScanCommand({
|
|
314
|
+
TableName: process.env.METRICS_TABLE,
|
|
315
|
+
FilterExpression: 'begins_with(team_date, :teamPrefix) AND user_id = :userId AND metric_type = :type',
|
|
316
|
+
ExpressionAttributeValues: {
|
|
317
|
+
':teamPrefix': { S: `${teamId}#` },
|
|
318
|
+
':userId': { S: userId },
|
|
319
|
+
':type': { S: 'onboarding' },
|
|
320
|
+
},
|
|
321
|
+
}));
|
|
322
|
+
let tasksCompleted = 0;
|
|
323
|
+
let timeToProductivity = 0;
|
|
324
|
+
let knowledgeGapsIdentified = 0;
|
|
325
|
+
let mentorConnections = 0;
|
|
326
|
+
if (onboardingResult.Items) {
|
|
327
|
+
for (const item of onboardingResult.Items) {
|
|
328
|
+
if (item.metric_data?.S) {
|
|
329
|
+
try {
|
|
330
|
+
const data = JSON.parse(item.metric_data.S);
|
|
331
|
+
tasksCompleted += data.tasksCompleted || 0;
|
|
332
|
+
timeToProductivity = Math.max(timeToProductivity, data.timeToProductivity || 0);
|
|
333
|
+
knowledgeGapsIdentified += data.knowledgeGaps || 0;
|
|
334
|
+
mentorConnections += data.mentorConnections || 0;
|
|
335
|
+
}
|
|
336
|
+
catch (e) {
|
|
337
|
+
console.warn('Failed to parse onboarding data:', e);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Calculate improvement metrics
|
|
343
|
+
const baselineOnboardingDays = 30; // Industry average
|
|
344
|
+
const actualOnboardingDays = Math.max(timeToProductivity, 1);
|
|
345
|
+
const accelerationPercentage = Math.max(0, ((baselineOnboardingDays - actualOnboardingDays) / baselineOnboardingDays) * 100);
|
|
346
|
+
return {
|
|
347
|
+
statusCode: 200,
|
|
348
|
+
headers,
|
|
349
|
+
body: JSON.stringify({
|
|
350
|
+
success: true,
|
|
351
|
+
onboarding: {
|
|
352
|
+
userId,
|
|
353
|
+
teamId,
|
|
354
|
+
tasksCompleted,
|
|
355
|
+
timeToProductivityDays: actualOnboardingDays,
|
|
356
|
+
accelerationPercentage,
|
|
357
|
+
knowledgeGapsIdentified,
|
|
358
|
+
mentorConnections,
|
|
359
|
+
baselineComparison: {
|
|
360
|
+
industryAverage: baselineOnboardingDays,
|
|
361
|
+
timeSaved: Math.max(0, baselineOnboardingDays - actualOnboardingDays),
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
calculatedAt: new Date().toISOString(),
|
|
365
|
+
}),
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
console.error('Error tracking onboarding impact:', error);
|
|
370
|
+
return {
|
|
371
|
+
statusCode: 500,
|
|
372
|
+
headers,
|
|
373
|
+
body: JSON.stringify({
|
|
374
|
+
error: 'Failed to track onboarding impact',
|
|
375
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
376
|
+
}),
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
async function generateDemoMetrics() {
|
|
381
|
+
const headers = {
|
|
382
|
+
'Content-Type': 'application/json',
|
|
383
|
+
'Access-Control-Allow-Origin': '*',
|
|
384
|
+
};
|
|
385
|
+
try {
|
|
386
|
+
// Generate impressive demo metrics for competition
|
|
387
|
+
const demoMetrics = {
|
|
388
|
+
totalTimeSaved: 2400, // 40 hours
|
|
389
|
+
questionsAnswered: 156,
|
|
390
|
+
knowledgeGapsIdentified: 23,
|
|
391
|
+
expertConnectionsMade: 45,
|
|
392
|
+
onboardingAcceleration: 65, // 65% faster
|
|
393
|
+
estimatedCostSavings: 18000, // $18,000
|
|
394
|
+
productivityGain: 35, // 35% increase
|
|
395
|
+
teamSize: 12,
|
|
396
|
+
knowledgeEntries: 234,
|
|
397
|
+
activeUsers: 11,
|
|
398
|
+
weeklyGrowth: 15.5, // 15.5% week-over-week growth
|
|
399
|
+
satisfactionScore: 4.7, // out of 5
|
|
400
|
+
adoptionRate: 92, // 92% team adoption
|
|
401
|
+
};
|
|
402
|
+
return {
|
|
403
|
+
statusCode: 200,
|
|
404
|
+
headers,
|
|
405
|
+
body: JSON.stringify({
|
|
406
|
+
success: true,
|
|
407
|
+
demo: demoMetrics,
|
|
408
|
+
generatedAt: new Date().toISOString(),
|
|
409
|
+
note: 'Demo metrics for competition presentation',
|
|
410
|
+
}),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
catch (error) {
|
|
414
|
+
console.error('Error generating demo metrics:', error);
|
|
415
|
+
return {
|
|
416
|
+
statusCode: 500,
|
|
417
|
+
headers,
|
|
418
|
+
body: JSON.stringify({
|
|
419
|
+
error: 'Failed to generate demo metrics',
|
|
420
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
421
|
+
}),
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
async function recordProductivityImpact(impactData, userId, teamId) {
|
|
426
|
+
const headers = {
|
|
427
|
+
'Content-Type': 'application/json',
|
|
428
|
+
'Access-Control-Allow-Origin': '*',
|
|
429
|
+
};
|
|
430
|
+
try {
|
|
431
|
+
const now = new Date();
|
|
432
|
+
const dateKey = now.toISOString().split('T')[0]; // YYYY-MM-DD
|
|
433
|
+
const teamDateKey = `${teamId}#${dateKey}`;
|
|
434
|
+
const impact = {
|
|
435
|
+
userId,
|
|
436
|
+
teamId,
|
|
437
|
+
date: now.toISOString(),
|
|
438
|
+
timesSavedMinutes: impactData.timesSavedMinutes || 0,
|
|
439
|
+
duplicateQuestionsAvoided: impactData.duplicateQuestionsAvoided || 0,
|
|
440
|
+
knowledgeReused: impactData.knowledgeReused || 0,
|
|
441
|
+
expertConnectionsMade: impactData.expertConnectionsMade || 0,
|
|
442
|
+
onboardingTasksCompleted: impactData.onboardingTasksCompleted || 0,
|
|
443
|
+
estimatedCostSavings: (impactData.timesSavedMinutes || 0) / 60 * 75, // $75/hour
|
|
444
|
+
productivityIncrease: impactData.productivityIncrease || 0,
|
|
445
|
+
};
|
|
446
|
+
// Store in DynamoDB with TTL
|
|
447
|
+
const ttl = Math.floor(Date.now() / 1000) + (90 * 24 * 60 * 60); // 90 days
|
|
448
|
+
await dynamoClient.send(new client_dynamodb_1.PutItemCommand({
|
|
449
|
+
TableName: process.env.METRICS_TABLE,
|
|
450
|
+
Item: {
|
|
451
|
+
team_date: { S: teamDateKey },
|
|
452
|
+
metric_type: { S: `impact-${userId}-${now.getTime()}` },
|
|
453
|
+
user_id: { S: userId },
|
|
454
|
+
metric_data: { S: JSON.stringify(impact) },
|
|
455
|
+
created_at: { S: now.toISOString() },
|
|
456
|
+
ttl: { N: ttl.toString() },
|
|
457
|
+
},
|
|
458
|
+
}));
|
|
459
|
+
return {
|
|
460
|
+
statusCode: 201,
|
|
461
|
+
headers,
|
|
462
|
+
body: JSON.stringify({
|
|
463
|
+
success: true,
|
|
464
|
+
impact,
|
|
465
|
+
message: 'Productivity impact recorded successfully',
|
|
466
|
+
}),
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
catch (error) {
|
|
470
|
+
console.error('Error recording productivity impact:', error);
|
|
471
|
+
return {
|
|
472
|
+
statusCode: 500,
|
|
473
|
+
headers,
|
|
474
|
+
body: JSON.stringify({
|
|
475
|
+
error: 'Failed to record productivity impact',
|
|
476
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
477
|
+
}),
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/lambda/analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-router.d.ts","sourceRoot":"","sources":["../../src/lambda/api-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAkCzE,eAAO,MAAM,OAAO,GAAU,OAAO,oBAAoB,KAAG,OAAO,CAAC,qBAAqB,CAsIxF,CAAC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handler = void 0;
|
|
4
|
+
const CORS_HEADERS = {
|
|
5
|
+
'Access-Control-Allow-Origin': '*',
|
|
6
|
+
'Access-Control-Allow-Headers': 'Content-Type,Authorization',
|
|
7
|
+
'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTIONS',
|
|
8
|
+
'Content-Type': 'application/json'
|
|
9
|
+
};
|
|
10
|
+
// Import your existing handlers
|
|
11
|
+
const adminHandler = require('./admin').handler;
|
|
12
|
+
const analyticsHandler = require('./analytics').handler;
|
|
13
|
+
const knowledgeHandler = require('./knowledge-ai').handler;
|
|
14
|
+
const graphHandler = require('./graph-builder').handler;
|
|
15
|
+
const aiServicesHandler = require('./ai-services').handler;
|
|
16
|
+
let customTopicsHandler;
|
|
17
|
+
try {
|
|
18
|
+
customTopicsHandler = require('./custom-topics').handler;
|
|
19
|
+
console.log('✓ custom-topics handler loaded successfully');
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
console.error('✗ Failed to load custom-topics handler:', error);
|
|
23
|
+
customTopicsHandler = null;
|
|
24
|
+
}
|
|
25
|
+
let teamsHandler;
|
|
26
|
+
try {
|
|
27
|
+
teamsHandler = require('./teams').handler;
|
|
28
|
+
console.log('✓ teams handler loaded successfully');
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('✗ Failed to load teams handler:', error);
|
|
32
|
+
teamsHandler = null;
|
|
33
|
+
}
|
|
34
|
+
const handler = async (event) => {
|
|
35
|
+
console.log('API Router Event:', JSON.stringify(event, null, 2));
|
|
36
|
+
// Handle CORS preflight
|
|
37
|
+
if (event.httpMethod === 'OPTIONS') {
|
|
38
|
+
return {
|
|
39
|
+
statusCode: 200,
|
|
40
|
+
headers: CORS_HEADERS,
|
|
41
|
+
body: ''
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const path = event.path; // e.g., /competition/api/admin/auth
|
|
46
|
+
const pathParts = path.split('/').filter(p => p);
|
|
47
|
+
// Remove stage name if present (e.g., "competition")
|
|
48
|
+
const apiIndex = pathParts.indexOf('api');
|
|
49
|
+
if (apiIndex === -1) {
|
|
50
|
+
return {
|
|
51
|
+
statusCode: 404,
|
|
52
|
+
headers: CORS_HEADERS,
|
|
53
|
+
body: JSON.stringify({ error: 'Not found' })
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// Get the route after /api
|
|
57
|
+
const route = pathParts.slice(apiIndex + 1); // e.g., ['admin', 'auth'] or ['analytics', 'metrics']
|
|
58
|
+
const routePrefix = route[0]; // 'admin', 'analytics', 'knowledge', 'experts', 'graph'
|
|
59
|
+
console.log('Route:', route, 'Prefix:', routePrefix);
|
|
60
|
+
// Auth check for protected routes (except /admin/auth which is public)
|
|
61
|
+
const protectedRoutes = ['admin', 'knowledge', 'experts', 'ai', 'secrets', 'storage', 'search', 'entries', 'graph', 'custom-topics', 'teams'];
|
|
62
|
+
const fullRoutePath = '/' + route.join('/');
|
|
63
|
+
const isAdminAuth = fullRoutePath.startsWith('/admin/auth');
|
|
64
|
+
const isTeamsJoin = /^\/teams\/join\/[^/]+$/.test(fullRoutePath);
|
|
65
|
+
const needsAuth = protectedRoutes.includes(routePrefix) && !isAdminAuth && !isTeamsJoin;
|
|
66
|
+
if (needsAuth) {
|
|
67
|
+
const authHeader = event.headers?.Authorization || event.headers?.authorization;
|
|
68
|
+
if (!authHeader) {
|
|
69
|
+
return {
|
|
70
|
+
statusCode: 401,
|
|
71
|
+
headers: CORS_HEADERS,
|
|
72
|
+
body: JSON.stringify({ error: 'Authorization header required' })
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// Auth verification happens in the individual handlers
|
|
76
|
+
}
|
|
77
|
+
// Route to appropriate handler
|
|
78
|
+
let result;
|
|
79
|
+
switch (routePrefix) {
|
|
80
|
+
case 'admin':
|
|
81
|
+
result = await adminHandler(event);
|
|
82
|
+
break;
|
|
83
|
+
case 'analytics':
|
|
84
|
+
result = await analyticsHandler(event);
|
|
85
|
+
break;
|
|
86
|
+
case 'search':
|
|
87
|
+
// Rewrite search to knowledge endpoint for compatibility
|
|
88
|
+
const searchEvent = { ...event, path: event.path.replace('/search', '/knowledge') };
|
|
89
|
+
result = await knowledgeHandler(searchEvent);
|
|
90
|
+
break;
|
|
91
|
+
case 'entries':
|
|
92
|
+
// Rewrite entries to knowledge endpoint
|
|
93
|
+
const entriesEvent = { ...event, path: event.path.replace('/entries', '/knowledge') };
|
|
94
|
+
result = await knowledgeHandler(entriesEvent);
|
|
95
|
+
break;
|
|
96
|
+
case 'knowledge':
|
|
97
|
+
case 'experts':
|
|
98
|
+
result = await knowledgeHandler(event);
|
|
99
|
+
break;
|
|
100
|
+
case 'graph':
|
|
101
|
+
result = await graphHandler(event);
|
|
102
|
+
break;
|
|
103
|
+
case 'ai':
|
|
104
|
+
case 'secrets':
|
|
105
|
+
case 'storage':
|
|
106
|
+
result = await aiServicesHandler(event);
|
|
107
|
+
break;
|
|
108
|
+
case 'custom-topics':
|
|
109
|
+
if (customTopicsHandler) {
|
|
110
|
+
console.log('Calling custom-topics handler');
|
|
111
|
+
result = await customTopicsHandler(event);
|
|
112
|
+
console.log('custom-topics handler result:', result);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.error('custom-topics handler not available');
|
|
116
|
+
result = {
|
|
117
|
+
statusCode: 500,
|
|
118
|
+
headers: CORS_HEADERS,
|
|
119
|
+
body: JSON.stringify({ error: 'Custom topics handler not loaded' })
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
case 'teams':
|
|
124
|
+
if (!teamsHandler) {
|
|
125
|
+
console.error('teams handler not available');
|
|
126
|
+
result = {
|
|
127
|
+
statusCode: 500,
|
|
128
|
+
headers: CORS_HEADERS,
|
|
129
|
+
body: JSON.stringify({ error: 'Teams handler not loaded' })
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
console.log('Calling teams handler');
|
|
134
|
+
result = await teamsHandler(event);
|
|
135
|
+
console.log('teams handler result:', result);
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
default:
|
|
139
|
+
result = {
|
|
140
|
+
statusCode: 404,
|
|
141
|
+
headers: CORS_HEADERS,
|
|
142
|
+
body: JSON.stringify({ error: 'Route not found' })
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Ensure CORS headers are present
|
|
146
|
+
result.headers = { ...CORS_HEADERS, ...result.headers };
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error('Router Error:', error);
|
|
151
|
+
return {
|
|
152
|
+
statusCode: 500,
|
|
153
|
+
headers: CORS_HEADERS,
|
|
154
|
+
body: JSON.stringify({
|
|
155
|
+
error: 'Internal server error',
|
|
156
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
157
|
+
})
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
exports.handler = handler;
|
|
162
|
+
//# sourceMappingURL=api-router.js.map
|