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'; 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, }); // ── 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', }); } }