- CSRF: store OAuth state in Secure/HttpOnly cookie, validate on callback
- Cache-Control: add no-cache, no-store headers to all responses
- Sensitive info: callback errors now 302 redirect instead of returning HTML
- Logging: remove realmId and sanitize error logs to prevent QBO data leaks
Adds /qbo/connect, /qbo/callback, /qbo/disconnect, and /qbo/launch
routes to bot.seahaven.com for Intuit app store compliance. Also
updates qbo-lookup to persist rotated refresh tokens automatically.
- Create SiteAssignments DynamoDB table with state GSI for site code and
state-based queries
- Add lookup_site function to wo-po-lookup action group lambda
- Add seed script (scripts/seed-sites.ts) to load site CSV into DynamoDB
- Upload site list markdown to KB S3 bucket for semantic search
- Update agent instruction to include site lookup capability
- Update README with site assignment docs and maintenance notes
Vector search couldn't match exact work order/PO numbers, so queries
always came back empty. This adds a dedicated lambda that queries
DynamoDB directly by ID, wired as a Bedrock Agent action group.
- Upload S3 files 10x concurrently instead of sequentially
- Replace clear-then-write with overwrite-in-place + delete stale
to avoid S3 404s during concurrent KB ingestion jobs
- 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
Add a new Lambda and CDK construct that scans the WorkOrders and
WorkOrderComments DynamoDB tables (owned by workorder-ingest),
converts each work order + comment history to markdown, uploads
to S3 under the work-orders/ prefix, and triggers a Bedrock
Knowledge Base ingestion job. Runs daily at 02:00 UTC via
EventBridge alongside the existing Notion sync.
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.
Adds a scheduled Lambda that pulls all pages from the Office Operations
Notion teamspace, converts them to markdown, uploads to the KB S3 bucket
under a notion/ prefix, and triggers a Bedrock ingestion job. Runs daily
at 02:00 UTC via EventBridge. Notion API key stored in Secrets Manager at
seahaven/notion/api-key (placeholder — fill in post-deploy).
- Post '_Sea Haven Assistant is thinking..._' immediately on receipt,
then update the message with the real response (chat.update)
- Broaden Maps location parameter description so agent passes facility
names like 'Amazon BFI9' directly to Google Maps rather than asking
the user to provide a street address
- Update foundation model to us.anthropic.claude-sonnet-4-5-20250929-v1:0
(cross-region inference profile required for Claude 4.x on Bedrock Agents)
- Broaden agent role IAM policy to cover wildcard-region foundation model ARN
and inference profile ARN
- Force alias version bump via description change so CloudFormation creates
agent version 2 with the updated model
- Remove invalid includedType: 'contractor' from Google Maps Places API request
(caused 400 Bad Request — not a valid place type for searchText endpoint)
- CDK stack for Sea Haven Industries internal Slack assistant
- Bedrock Agent (Claude 3.5 Sonnet) with QBO + Google Maps action groups
- VectorKnowledgeBase via @cdklabs/generative-ai-cdk-constructs (AOSS + S3)
- Slack webhook/processor Lambdas with DM-only filtering
- API Gateway HTTP API on bot.seahaven.com
- DynamoDB conversation log with 90-day TTL
- Secrets Manager references for Slack, QBO OAuth, and Google Maps