kyd-shared-badge 0.3.14 → 0.3.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/lib/context.ts +20 -10
- package/src/lib/routes.ts +9 -2
package/package.json
CHANGED
package/src/lib/context.ts
CHANGED
|
@@ -8,46 +8,51 @@ import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
|
8
8
|
import { GraphInsightsPayload } from '../types';
|
|
9
9
|
|
|
10
10
|
const region = process.env.AWS_REGION!;
|
|
11
|
-
const usersTableName = process.env.USER_TABLE_NAME
|
|
11
|
+
const usersTableName = process.env.USER_TABLE_NAME
|
|
12
12
|
const doc = DynamoDBDocumentClient.from(new DynamoDBClient({ region }));
|
|
13
13
|
const s3 = new S3Client({ region });
|
|
14
14
|
const providerDataBucket = process.env.PROVIDER_DATA_BUCKET_NAME!;
|
|
15
15
|
const badgeTableName = process.env.BADGE_TABLE_NAME!;
|
|
16
16
|
|
|
17
17
|
export async function aggregateUserData(userId: string, enterpriseMode?: boolean, companyId?: string | null): Promise<any> {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
let userResp;
|
|
19
|
+
if (enterpriseMode) {
|
|
20
|
+
const linkTableName = process.env.USER_COMPANY_LINK_TABLE_NAME
|
|
21
|
+
userResp = await doc.send(new GetCommand({ TableName: linkTableName, Key: { userId, companyId } }));
|
|
22
|
+
} else {
|
|
23
|
+
userResp = await doc.send(new GetCommand({ TableName: usersTableName, Key: { userId } }));
|
|
24
|
+
}
|
|
20
25
|
const user = userResp.Item || {};
|
|
21
|
-
|
|
26
|
+
|
|
22
27
|
if (enterpriseMode && companyId) {
|
|
23
28
|
// Optionally merge enterprise overlay later; keeping simple for MVP.
|
|
24
|
-
|
|
29
|
+
user.companyId = companyId;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
// For each provider_* entry, fetch filtered_data_key JSON from S3 and attach under <provider>_analysis
|
|
28
|
-
const providerKeys = Object.keys(
|
|
33
|
+
const providerKeys = Object.keys(user).filter(k => k.startsWith('provider_'));
|
|
29
34
|
const fetches = providerKeys.map(async (key) => {
|
|
30
35
|
try {
|
|
31
|
-
const providerData =
|
|
36
|
+
const providerData = user[key];
|
|
32
37
|
if (!providerData || typeof providerData !== 'object') return;
|
|
33
38
|
const filteredKey = providerData['filtered_data_key'];
|
|
34
39
|
if (!filteredKey || typeof filteredKey !== 'string') return;
|
|
35
40
|
const obj = await getJsonFromS3(providerDataBucket, filteredKey);
|
|
36
41
|
const providerName = key.replace(/^provider_/, '');
|
|
37
42
|
const analysisKey = `${providerName}_analysis`;
|
|
38
|
-
|
|
43
|
+
user[analysisKey] = obj;
|
|
39
44
|
} catch (e) {
|
|
40
45
|
console.error('Failed to load provider filtered data', e);
|
|
41
46
|
// Non-fatal; annotate error
|
|
42
47
|
try {
|
|
43
48
|
const providerName = key.replace(/^provider_/, '');
|
|
44
|
-
|
|
49
|
+
user[`${providerName}_analysis`] = { error: 'Failed to load provider filtered data' };
|
|
45
50
|
} catch {}
|
|
46
51
|
}
|
|
47
52
|
});
|
|
48
53
|
await Promise.all(fetches);
|
|
49
54
|
|
|
50
|
-
return
|
|
55
|
+
return user;
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -150,4 +155,9 @@ async function getJsonFromS3(bucket: string, key: string): Promise<any> {
|
|
|
150
155
|
export async function getReportGraphData(badgeId: string): Promise<GraphInsightsPayload | undefined> {
|
|
151
156
|
const badge = await doc.send(new GetCommand({ TableName: badgeTableName, Key: { badgeId } }));
|
|
152
157
|
return badge.Item?.assessmentResult?.graph_insights as GraphInsightsPayload | undefined;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export async function getBadgeUserId(badgeId: string): Promise<string> {
|
|
161
|
+
const badge = await doc.send(new GetCommand({ TableName: badgeTableName, Key: { badgeId } }));
|
|
162
|
+
return badge.Item?.userId as string;
|
|
153
163
|
}
|
package/src/lib/routes.ts
CHANGED
|
@@ -6,7 +6,13 @@ import { streamText } from 'ai';
|
|
|
6
6
|
import { bedrock } from '@ai-sdk/amazon-bedrock';
|
|
7
7
|
|
|
8
8
|
import { getHistory, putMessage } from './chat-store';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
aggregateUserData,
|
|
11
|
+
cleanDeveloperProfile,
|
|
12
|
+
buildAllContextPrompt,
|
|
13
|
+
getReportGraphData,
|
|
14
|
+
getBadgeUserId
|
|
15
|
+
} from './context';
|
|
10
16
|
import { checkAndConsumeToken } from './rate-limit';
|
|
11
17
|
|
|
12
18
|
import { createSession } from './chat-store';
|
|
@@ -29,7 +35,8 @@ export async function chatStreamRoute(req: NextRequest, userId: string, companyI
|
|
|
29
35
|
|
|
30
36
|
await putMessage({ sessionId, role: 'user', content });
|
|
31
37
|
|
|
32
|
-
const
|
|
38
|
+
const badgeUserId = await getBadgeUserId(badgeId);
|
|
39
|
+
const aggregated = await aggregateUserData(badgeUserId, !!companyId, companyId);
|
|
33
40
|
const cleaned = cleanDeveloperProfile(aggregated);
|
|
34
41
|
const graphData = await getReportGraphData(badgeId);
|
|
35
42
|
const system = buildAllContextPrompt(cleaned, graphData, { concise: true });
|