Add a new Lambda and CDK construct that scans the purchase-orders DynamoDB table (owned by po-ingest), converts each PO to markdown, uploads to S3 under the purchase-orders/ prefix, and triggers a Bedrock Knowledge Base ingestion job. Runs daily at 02:00 UTC via EventBridge alongside the existing Notion sync.
78 lines
3.7 KiB
TypeScript
78 lines
3.7 KiB
TypeScript
import * as cdk from 'aws-cdk-lib';
|
|
import { Construct } from 'constructs';
|
|
import { ConversationLogConstruct } from './constructs/conversation-log';
|
|
import { KnowledgeBaseConstruct } from './constructs/knowledge-base';
|
|
import { BedrockAgentConstruct } from './constructs/bedrock-agent';
|
|
import { SlackHandlerConstruct } from './constructs/slack-handler';
|
|
import { NotionSyncConstruct } from './constructs/notion-sync';
|
|
import { PoSyncConstruct } from './constructs/po-sync';
|
|
|
|
export class SeahavenSlackBotStack extends cdk.Stack {
|
|
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
|
super(scope, id, props);
|
|
|
|
// Wildcard cert ARN (*.seahaven.com) — set in cdk.json or via --context
|
|
const wildcardCertArn = this.node.tryGetContext('wildcardCertArn') as string | undefined;
|
|
if (!wildcardCertArn || wildcardCertArn.includes('CHANGE-ME')) {
|
|
throw new Error(
|
|
'Set wildcardCertArn in cdk.json or pass --context wildcardCertArn=arn:aws:acm:...\n' +
|
|
'Run: aws acm list-certificates --region us-east-1 to find your cert ARN.',
|
|
);
|
|
}
|
|
|
|
// ── Conversation history (DynamoDB) ───────────────────────────────────────
|
|
const conversationLog = new ConversationLogConstruct(this, 'ConversationLog');
|
|
|
|
// ── Bedrock Knowledge Base (OpenSearch Serverless + S3) ───────────────────
|
|
const knowledgeBase = new KnowledgeBaseConstruct(this, 'KnowledgeBase', {
|
|
accountId: this.account,
|
|
region: this.region,
|
|
});
|
|
|
|
// ── Bedrock Agent (Claude Sonnet + QBO + Google Maps action groups) ───────
|
|
const bedrockAgent = new BedrockAgentConstruct(this, 'BedrockAgent', {
|
|
accountId: this.account,
|
|
region: this.region,
|
|
knowledgeBaseId: knowledgeBase.knowledgeBase.knowledgeBaseId,
|
|
knowledgeBaseArn: knowledgeBase.knowledgeBase.knowledgeBaseArn,
|
|
});
|
|
|
|
// ── Notion → KB daily sync (EventBridge + Lambda) ────────────────────────
|
|
new NotionSyncConstruct(this, 'NotionSync', {
|
|
region: this.region,
|
|
kbDocsBucket: knowledgeBase.docsBucket,
|
|
knowledgeBaseId: knowledgeBase.knowledgeBase.knowledgeBaseId,
|
|
dataSourceId: knowledgeBase.dataSource.dataSourceId,
|
|
});
|
|
|
|
// ── Purchase Orders → KB daily sync (EventBridge + Lambda) ────────────────
|
|
new PoSyncConstruct(this, 'PoSync', {
|
|
region: this.region,
|
|
kbDocsBucket: knowledgeBase.docsBucket,
|
|
knowledgeBaseId: knowledgeBase.knowledgeBase.knowledgeBaseId,
|
|
dataSourceId: knowledgeBase.dataSource.dataSourceId,
|
|
});
|
|
|
|
// ── Slack webhook handler (API Gateway + Lambda) ───────────────────────────
|
|
new SlackHandlerConstruct(this, 'SlackHandler', {
|
|
accountId: this.account,
|
|
region: this.region,
|
|
agentId: bedrockAgent.agent.attrAgentId,
|
|
agentAliasId: bedrockAgent.agentAlias.attrAgentAliasId,
|
|
conversationTable: conversationLog.table,
|
|
wildcardCertArn,
|
|
});
|
|
|
|
// ── Stack outputs ─────────────────────────────────────────────────────────
|
|
new cdk.CfnOutput(this, 'KBDocsBucketName', {
|
|
value: knowledgeBase.docsBucket.bucketName,
|
|
description: 'Upload SA8000 docs, SOPs, and employee handbook here to populate the KB',
|
|
});
|
|
|
|
new cdk.CfnOutput(this, 'AgentId', {
|
|
value: bedrockAgent.agent.attrAgentId,
|
|
description: 'Bedrock Agent ID',
|
|
});
|
|
|
|
}
|
|
}
|