- Rename bot to Alex with friendly/professional persona (Bedrock Agent instruction rewrite) - Replace HTTP webhook Lambda with ECS Fargate Socket Mode service (persistent WebSocket) - Add payment/invoice lookup via PaymentsDashboard table (vendor, invoice, check search) - Switch from manual SiteAssignments to auto-populated verified-sites table - Add channel support via app_mention events (threaded replies) - Add App Home tab with Block Kit capabilities view - Add unanswered questions logging to seahaven-unanswered-questions DynamoDB table - Fix pre-existing compliance: add arm64 + 60-day log retention to all Lambdas - Remove webhook Lambda and seed-sites script (both obsolete)
40 lines
1.7 KiB
TypeScript
40 lines
1.7 KiB
TypeScript
import * as cdk from 'aws-cdk-lib';
|
|
import { Construct } from 'constructs';
|
|
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
|
|
|
|
export class ConversationLogConstruct extends Construct {
|
|
public readonly table: dynamodb.Table;
|
|
public readonly unansweredTable: dynamodb.Table;
|
|
|
|
constructor(scope: Construct, id: string) {
|
|
super(scope, id);
|
|
|
|
this.table = new dynamodb.Table(this, 'Table', {
|
|
tableName: 'seahaven-conversations',
|
|
// PK: Slack user ID (e.g. U0123456789)
|
|
partitionKey: { name: 'userId', type: dynamodb.AttributeType.STRING },
|
|
// SK: ISO-8601 timestamp — enables range queries for session lookup
|
|
sortKey: { name: 'timestamp', type: dynamodb.AttributeType.STRING },
|
|
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
|
|
removalPolicy: cdk.RemovalPolicy.RETAIN,
|
|
pointInTimeRecoverySpecification: { pointInTimeRecoveryEnabled: true },
|
|
// TTL attribute — records are automatically expired after 90 days
|
|
timeToLiveAttribute: 'ttl',
|
|
});
|
|
|
|
// GSI for looking up all turns in a given Bedrock session (for context retrieval)
|
|
this.table.addGlobalSecondaryIndex({
|
|
indexName: 'sessionId-index',
|
|
partitionKey: { name: 'sessionId', type: dynamodb.AttributeType.STRING },
|
|
sortKey: { name: 'timestamp', type: dynamodb.AttributeType.STRING },
|
|
});
|
|
|
|
this.unansweredTable = new dynamodb.Table(this, 'UnansweredTable', {
|
|
tableName: 'seahaven-unanswered-questions',
|
|
partitionKey: { name: 'questionId', type: dynamodb.AttributeType.STRING },
|
|
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
|
|
removalPolicy: cdk.RemovalPolicy.RETAIN,
|
|
timeToLiveAttribute: 'ttl',
|
|
});
|
|
}
|
|
}
|