@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.
Files changed (210) hide show
  1. package/README.md +296 -0
  2. package/dist/ai/bedrock-client.d.ts +1 -0
  3. package/dist/ai/bedrock-client.d.ts.map +1 -0
  4. package/dist/ai/bedrock-client.js +2 -0
  5. package/dist/ai/bedrock-client.js.map +1 -0
  6. package/dist/ai/knowledge-processor.d.ts +1 -0
  7. package/dist/ai/knowledge-processor.d.ts.map +1 -0
  8. package/dist/ai/knowledge-processor.js +2 -0
  9. package/dist/ai/knowledge-processor.js.map +1 -0
  10. package/dist/cli.d.ts +3 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +70 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/commands/ask.d.ts +3 -0
  15. package/dist/commands/ask.d.ts.map +1 -0
  16. package/dist/commands/ask.js +217 -0
  17. package/dist/commands/ask.js.map +1 -0
  18. package/dist/commands/audit.d.ts +3 -0
  19. package/dist/commands/audit.d.ts.map +1 -0
  20. package/dist/commands/audit.js +153 -0
  21. package/dist/commands/audit.js.map +1 -0
  22. package/dist/commands/auth.d.ts +3 -0
  23. package/dist/commands/auth.d.ts.map +1 -0
  24. package/dist/commands/auth.js +114 -0
  25. package/dist/commands/auth.js.map +1 -0
  26. package/dist/commands/config.d.ts +3 -0
  27. package/dist/commands/config.d.ts.map +1 -0
  28. package/dist/commands/config.js +72 -0
  29. package/dist/commands/config.js.map +1 -0
  30. package/dist/commands/embeddings.d.ts +3 -0
  31. package/dist/commands/embeddings.d.ts.map +1 -0
  32. package/dist/commands/embeddings.js +118 -0
  33. package/dist/commands/embeddings.js.map +1 -0
  34. package/dist/commands/experts.d.ts +3 -0
  35. package/dist/commands/experts.d.ts.map +1 -0
  36. package/dist/commands/experts.js +129 -0
  37. package/dist/commands/experts.js.map +1 -0
  38. package/dist/commands/export-import.d.ts +4 -0
  39. package/dist/commands/export-import.d.ts.map +1 -0
  40. package/dist/commands/export-import.js +285 -0
  41. package/dist/commands/export-import.js.map +1 -0
  42. package/dist/commands/git.d.ts +4 -0
  43. package/dist/commands/git.d.ts.map +1 -0
  44. package/dist/commands/git.js +274 -0
  45. package/dist/commands/git.js.map +1 -0
  46. package/dist/commands/impact.d.ts +3 -0
  47. package/dist/commands/impact.d.ts.map +1 -0
  48. package/dist/commands/impact.js +121 -0
  49. package/dist/commands/impact.js.map +1 -0
  50. package/dist/commands/insights.d.ts +3 -0
  51. package/dist/commands/insights.d.ts.map +1 -0
  52. package/dist/commands/insights.js +113 -0
  53. package/dist/commands/insights.js.map +1 -0
  54. package/dist/commands/learned.d.ts +3 -0
  55. package/dist/commands/learned.d.ts.map +1 -0
  56. package/dist/commands/learned.js +355 -0
  57. package/dist/commands/learned.js.map +1 -0
  58. package/dist/commands/onboard.d.ts +3 -0
  59. package/dist/commands/onboard.d.ts.map +1 -0
  60. package/dist/commands/onboard.js +141 -0
  61. package/dist/commands/onboard.js.map +1 -0
  62. package/dist/commands/recent.d.ts +3 -0
  63. package/dist/commands/recent.d.ts.map +1 -0
  64. package/dist/commands/recent.js +83 -0
  65. package/dist/commands/recent.js.map +1 -0
  66. package/dist/commands/secrets.d.ts +3 -0
  67. package/dist/commands/secrets.d.ts.map +1 -0
  68. package/dist/commands/secrets.js +203 -0
  69. package/dist/commands/secrets.js.map +1 -0
  70. package/dist/commands/stats.d.ts +3 -0
  71. package/dist/commands/stats.d.ts.map +1 -0
  72. package/dist/commands/stats.js +120 -0
  73. package/dist/commands/stats.js.map +1 -0
  74. package/dist/config/index.d.ts +12 -0
  75. package/dist/config/index.d.ts.map +1 -0
  76. package/dist/config/index.js +46 -0
  77. package/dist/config/index.js.map +1 -0
  78. package/dist/database/migrations.d.ts +13 -0
  79. package/dist/database/migrations.d.ts.map +1 -0
  80. package/dist/database/migrations.js +190 -0
  81. package/dist/database/migrations.js.map +1 -0
  82. package/dist/database/postgresql.d.ts +92 -0
  83. package/dist/database/postgresql.d.ts.map +1 -0
  84. package/dist/database/postgresql.js +382 -0
  85. package/dist/database/postgresql.js.map +1 -0
  86. package/dist/database/sqlite.d.ts +54 -0
  87. package/dist/database/sqlite.d.ts.map +1 -0
  88. package/dist/database/sqlite.js +337 -0
  89. package/dist/database/sqlite.js.map +1 -0
  90. package/dist/lambda/admin.d.ts +3 -0
  91. package/dist/lambda/admin.d.ts.map +1 -0
  92. package/dist/lambda/admin.js +818 -0
  93. package/dist/lambda/admin.js.map +1 -0
  94. package/dist/lambda/ai-services.d.ts +6 -0
  95. package/dist/lambda/ai-services.d.ts.map +1 -0
  96. package/dist/lambda/ai-services.js +472 -0
  97. package/dist/lambda/ai-services.js.map +1 -0
  98. package/dist/lambda/analytics.d.ts +3 -0
  99. package/dist/lambda/analytics.d.ts.map +1 -0
  100. package/dist/lambda/analytics.js +481 -0
  101. package/dist/lambda/analytics.js.map +1 -0
  102. package/dist/lambda/api-router.d.ts +3 -0
  103. package/dist/lambda/api-router.d.ts.map +1 -0
  104. package/dist/lambda/api-router.js +162 -0
  105. package/dist/lambda/api-router.js.map +1 -0
  106. package/dist/lambda/custom-topics.d.ts +3 -0
  107. package/dist/lambda/custom-topics.d.ts.map +1 -0
  108. package/dist/lambda/custom-topics.js +425 -0
  109. package/dist/lambda/custom-topics.js.map +1 -0
  110. package/dist/lambda/graph-builder.d.ts +3 -0
  111. package/dist/lambda/graph-builder.d.ts.map +1 -0
  112. package/dist/lambda/graph-builder.js +442 -0
  113. package/dist/lambda/graph-builder.js.map +1 -0
  114. package/dist/lambda/knowledge-ai.d.ts +3 -0
  115. package/dist/lambda/knowledge-ai.d.ts.map +1 -0
  116. package/dist/lambda/knowledge-ai.js +849 -0
  117. package/dist/lambda/knowledge-ai.js.map +1 -0
  118. package/dist/lambda/post-confirmation.d.ts +8 -0
  119. package/dist/lambda/post-confirmation.d.ts.map +1 -0
  120. package/dist/lambda/post-confirmation.js +92 -0
  121. package/dist/lambda/post-confirmation.js.map +1 -0
  122. package/dist/lambda/teams.d.ts +3 -0
  123. package/dist/lambda/teams.d.ts.map +1 -0
  124. package/dist/lambda/teams.js +568 -0
  125. package/dist/lambda/teams.js.map +1 -0
  126. package/dist/lib/export-helpers.d.ts +5 -0
  127. package/dist/lib/export-helpers.d.ts.map +1 -0
  128. package/dist/lib/export-helpers.js +137 -0
  129. package/dist/lib/export-helpers.js.map +1 -0
  130. package/dist/lib/import-helpers.d.ts +5 -0
  131. package/dist/lib/import-helpers.d.ts.map +1 -0
  132. package/dist/lib/import-helpers.js +185 -0
  133. package/dist/lib/import-helpers.js.map +1 -0
  134. package/dist/lib/insights-helpers.d.ts +123 -0
  135. package/dist/lib/insights-helpers.d.ts.map +1 -0
  136. package/dist/lib/insights-helpers.js +374 -0
  137. package/dist/lib/insights-helpers.js.map +1 -0
  138. package/dist/lib/search-helpers.d.ts +4 -0
  139. package/dist/lib/search-helpers.d.ts.map +1 -0
  140. package/dist/lib/search-helpers.js +124 -0
  141. package/dist/lib/search-helpers.js.map +1 -0
  142. package/dist/lib/secret-helpers.d.ts +2 -0
  143. package/dist/lib/secret-helpers.d.ts.map +1 -0
  144. package/dist/lib/secret-helpers.js +85 -0
  145. package/dist/lib/secret-helpers.js.map +1 -0
  146. package/dist/lib/stats-helpers.d.ts +41 -0
  147. package/dist/lib/stats-helpers.d.ts.map +1 -0
  148. package/dist/lib/stats-helpers.js +263 -0
  149. package/dist/lib/stats-helpers.js.map +1 -0
  150. package/dist/services/aws-api.d.ts +81 -0
  151. package/dist/services/aws-api.d.ts.map +1 -0
  152. package/dist/services/aws-api.js +388 -0
  153. package/dist/services/aws-api.js.map +1 -0
  154. package/dist/services/bedrock.d.ts +83 -0
  155. package/dist/services/bedrock.d.ts.map +1 -0
  156. package/dist/services/bedrock.js +434 -0
  157. package/dist/services/bedrock.js.map +1 -0
  158. package/dist/services/commit-learnings.d.ts +25 -0
  159. package/dist/services/commit-learnings.d.ts.map +1 -0
  160. package/dist/services/commit-learnings.js +180 -0
  161. package/dist/services/commit-learnings.js.map +1 -0
  162. package/dist/services/embedding-storage.d.ts +42 -0
  163. package/dist/services/embedding-storage.d.ts.map +1 -0
  164. package/dist/services/embedding-storage.js +124 -0
  165. package/dist/services/embedding-storage.js.map +1 -0
  166. package/dist/services/expert-engine.d.ts +21 -0
  167. package/dist/services/expert-engine.d.ts.map +1 -0
  168. package/dist/services/expert-engine.js +58 -0
  169. package/dist/services/expert-engine.js.map +1 -0
  170. package/dist/services/onboarding-accelerator.d.ts +118 -0
  171. package/dist/services/onboarding-accelerator.d.ts.map +1 -0
  172. package/dist/services/onboarding-accelerator.js +403 -0
  173. package/dist/services/onboarding-accelerator.js.map +1 -0
  174. package/dist/services/secret-detection.d.ts +46 -0
  175. package/dist/services/secret-detection.d.ts.map +1 -0
  176. package/dist/services/secret-detection.js +75 -0
  177. package/dist/services/secret-detection.js.map +1 -0
  178. package/dist/services/secret-manager-simple.d.ts +51 -0
  179. package/dist/services/secret-manager-simple.d.ts.map +1 -0
  180. package/dist/services/secret-manager-simple.js +119 -0
  181. package/dist/services/secret-manager-simple.js.map +1 -0
  182. package/dist/services/secret-manager.d.ts +150 -0
  183. package/dist/services/secret-manager.d.ts.map +1 -0
  184. package/dist/services/secret-manager.js +287 -0
  185. package/dist/services/secret-manager.js.map +1 -0
  186. package/dist/services/vector-embeddings.d.ts +70 -0
  187. package/dist/services/vector-embeddings.d.ts.map +1 -0
  188. package/dist/services/vector-embeddings.js +167 -0
  189. package/dist/services/vector-embeddings.js.map +1 -0
  190. package/dist/services/vector-search.d.ts +28 -0
  191. package/dist/services/vector-search.d.ts.map +1 -0
  192. package/dist/services/vector-search.js +192 -0
  193. package/dist/services/vector-search.js.map +1 -0
  194. package/dist/types/index.d.ts +86 -0
  195. package/dist/types/index.d.ts.map +1 -0
  196. package/dist/types/index.js +4 -0
  197. package/dist/types/index.js.map +1 -0
  198. package/dist/utils/formatting.d.ts +10 -0
  199. package/dist/utils/formatting.d.ts.map +1 -0
  200. package/dist/utils/formatting.js +82 -0
  201. package/dist/utils/formatting.js.map +1 -0
  202. package/dist/utils/git.d.ts +52 -0
  203. package/dist/utils/git.d.ts.map +1 -0
  204. package/dist/utils/git.js +182 -0
  205. package/dist/utils/git.js.map +1 -0
  206. package/dist/utils/validation.d.ts +17 -0
  207. package/dist/utils/validation.d.ts.map +1 -0
  208. package/dist/utils/validation.js +187 -0
  209. package/dist/utils/validation.js.map +1 -0
  210. 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,3 @@
1
+ import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
2
+ export declare const handler: (event: APIGatewayProxyEvent) => Promise<APIGatewayProxyResult>;
3
+ //# sourceMappingURL=api-router.d.ts.map
@@ -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