Skip to main content
Whilst is a monorepo containing a Next.js web application, AWS Lambda services, and shared TypeScript packages orchestrated via pnpm workspaces.

High-Level Architecture

┌──────────────────────────────────────────────────────────┐
│  Slack Workspace                                          │
│  User mentions @whilst → Slack Events API                 │
└────────────────────┬─────────────────────────────────────┘

┌──────────────────────────────────────────────────────────┐
│  AWS (Backend Services)                                   │
│                                                           │
│  API Gateway ──► Event Intake Lambda                      │
│                    ├─ Validates Slack signatures           │
│                    ├─ Normalises events                    │
│                    └─ Enqueues to SQS                      │
│                          ▼                                │
│                    SQS Queue                               │
│                          ▼                                │
│                  Job Worker Lambda                         │
│                    ├─ Resolves workspace credentials       │
│                    ├─ Calls MCP adapters                   │
│                    ├─ Runs Knowledge Pipeline              │
│                    └─ Publishes Slack updates              │
│                          ▼                                │
│              Neon Postgres (pgvector)                      │
└──────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────┐
│  Vercel (Web Application)                                 │
│  Next.js 14 App Router                                    │
│    ├─ Document management (TipTap editor)                 │
│    ├─ AI Sidekick (chat, search, actions)                 │
│    ├─ WorkOS authentication                               │
│    └─ Real-time sync (AWS AppSync Events)                 │
└──────────────────────────────────────────────────────────┘

Component Map

Communication Adapters

Normalise events from Slack (future: Discord, Teams) into a channel-agnostic format and publish to the intake Lambda via API Gateway.

Event Intake Lambda

  • Validates adapter-specific request signatures (Slack X-Slack-Signature)
  • Converts raw events into NormalisedEvent payloads
  • Enqueues SQS jobs
  • Responds within 3 seconds

Job Worker Lambda

  • Triggered by SQS (batch size 1 for ordering)
  • Resolves per-workspace credentials
  • Sends acknowledgement via communication adapter
  • Calls MCP client adapter and streams status updates
  • Implements retry/backoff on 429/5xx
  • Updates Postgres and pushes audit events

MCP Client Library

Shared TypeScript package with typed adapters per source (GitHub, Linear, Notion). Normalises responses into { answer, citations[], raw }.

Credential Resolver

Multi-tenant credential lookup from AWS Secrets Manager. Provides per-workspace auth tokens with caching for the duration of a job.

Web Application (Next.js 14)

  • Server Components + App Router
  • TipTap rich text editor
  • pgvector semantic search
  • React Query + Zustand state management
  • WorkOS authentication
  • Deployed on Vercel

Persistence Layer

  • PostgreSQL (Neon) — primary database with pgvector extension
  • Workspace configs, encrypted credentials, documents, embeddings, jobs
  • All keyed by workspace_id for tenant isolation

Observability

  • CloudWatch logs/metrics
  • X-Ray tracing across Lambdas, SQS, Postgres
  • DLQ for SQS with replay Lambda
  • Slack alerts via SNS

Data Flow

1

User mentions @whilst

User asks a question in Slack, e.g. “What’s the latest open PR about churn?”
2

Event intake

Slack sends app_mention to API Gateway. Intake Lambda verifies signature, persists job stub, enqueues SQS item, responds 200.
3

Job processing

Job Worker pulls the message, resolves workspace credentials, sends acknowledgement to Slack.
4

MCP query + Knowledge Pipeline

MCP adapter fetches data (e.g. GitHub PRs). Knowledge Pipeline analyzes the thread for topics, decisions, and action items.
5

Response delivered

Final answer posted as Slack thread update. Auto-generated doc saved to Postgres. Job marked complete.

Monorepo Structure

whilst-slack-bot/
├── apps/
│   └── web-app/              # Next.js 14 (main UI)
├── services/
│   ├── event-intake/         # Lambda: Slack event ingestion
│   ├── job-worker/           # Lambda: Background job processor
│   └── user-resolver/        # Lambda: User context resolution
├── packages/
│   ├── shared/               # Shared utilities, types
│   ├── communication-slack/  # Slack API client
│   ├── mcp-clients/          # MCP integrations
│   ├── tenant-store/         # Workspace data access layer
│   ├── job-store/            # Job queue management
│   └── knowledge-pipeline/   # Thread analysis + auto-doc
├── infra/                    # AWS CDK infrastructure
└── docs/                     # Technical documentation

Data Model

Key tables in the PostgreSQL schema:
TablePurpose
workspacesSlack workspace registrations and bot tokens
tenant_accountsMulti-tenant account/organization records
tenant_usersUser accounts within tenants
jobsJob queue tracking (requested → complete)
docsGenerated documents with embeddings
conversationsIngested Slack thread metadata
messagesIndividual thread messages
actorsParticipant identities
relationshipsCollaboration graph edges
mcp_credentialsPer-workspace MCP source credentials
api_keysMCP Server API keys