This repository has been archived on 2026-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
seahaven-slack-bot/lib/constructs/po-sync.ts
Adam Moussa adbe19aa16 fix: concurrent uploads, overwrite-in-place, 15min timeout
- Bump Lambda timeout from 5min to 15min (9k+ POs need more time)
- Upload S3 files 25x concurrently instead of sequentially
- Replace clear-then-write with overwrite-in-place + delete stale
  to avoid S3 404s during concurrent KB ingestion jobs
2026-04-13 15:36:07 -04:00

71 lines
2.5 KiB
TypeScript

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as lambdaNodejs from 'aws-cdk-lib/aws-lambda-nodejs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as path from 'path';
export interface PoSyncProps {
region: string;
kbDocsBucket: s3.Bucket;
knowledgeBaseId: string;
dataSourceId: string;
}
export class PoSyncConstruct extends Construct {
public readonly syncLambda: lambdaNodejs.NodejsFunction;
constructor(scope: Construct, id: string, props: PoSyncProps) {
super(scope, id);
// Import the purchase-orders DynamoDB table (owned by po-ingest stack)
const poTable = dynamodb.Table.fromTableName(
this, 'PurchaseOrdersTable', 'purchase-orders',
);
// Lambda — scans purchase-orders table, uploads markdown to S3, triggers KB ingestion
this.syncLambda = new lambdaNodejs.NodejsFunction(this, 'SyncLambda', {
functionName: 'seahaven-po-sync',
entry: path.join(__dirname, '../../lambda/po-sync/index.ts'),
runtime: lambda.Runtime.NODEJS_22_X,
memorySize: 512,
timeout: cdk.Duration.minutes(15),
environment: {
PO_TABLE: poTable.tableName,
KB_BUCKET_NAME: props.kbDocsBucket.bucketName,
KNOWLEDGE_BASE_ID: props.knowledgeBaseId,
DATA_SOURCE_ID: props.dataSourceId,
REGION: props.region,
},
});
// Grant read access to the purchase-orders table
poTable.grantReadData(this.syncLambda);
// Grant read/write to the KB docs bucket (read to list+delete old, write new)
props.kbDocsBucket.grantReadWrite(this.syncLambda);
// Allow Lambda to start a Bedrock KB ingestion job
this.syncLambda.addToRolePolicy(
new iam.PolicyStatement({
actions: ['bedrock:StartIngestionJob'],
resources: [
`arn:aws:bedrock:${props.region}:*:knowledge-base/${props.knowledgeBaseId}`,
],
}),
);
// EventBridge rule — fires daily at 02:00 UTC
const dailyRule = new events.Rule(this, 'DailySyncRule', {
ruleName: 'seahaven-po-daily-sync',
description: 'Daily purchase-orders → KB sync at 02:00 UTC',
schedule: events.Schedule.cron({ minute: '0', hour: '2' }),
});
dailyRule.addTarget(new targets.LambdaFunction(this.syncLambda));
}
}