Skip to content

Latest commit

Β 

History

History
87 lines (62 loc) Β· 3.46 KB

File metadata and controls

87 lines (62 loc) Β· 3.46 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

# Development
npm run start:dev          # Start with file watch
npm run start:debug:watch  # Start with debugger + file watch

# Build
npm run build              # Compile TypeScript to dist/

# Tests
npm test                   # Run all unit tests (requires --experimental-vm-modules)
npm run test:watch         # Watch mode
npm run test:cov           # With coverage
npm run test:e2e           # E2E tests (./test/jest-e2e.json)

# Code quality
npm run lint               # ESLint check
npm run format             # Prettier format

To run a single test file:

npx jest src/domain/services/slack-message-processor.spec.ts

Architecture

perigee-bot is a NestJS microservice that listens for Slack app_mention events (via Slack Bolt socket mode) and saves thread message data to a Notion database.

Module structure

src/
β”œβ”€β”€ application/slack/   # Slack event listeners (entry point)
β”œβ”€β”€ domain/
β”‚   β”œβ”€β”€ models/          # Interfaces: SlackMessage, ExtractedMessageData
β”‚   └── services/        # Business logic (functional style)
β”œβ”€β”€ infrastructure/notion/  # Notion API client (uses raw fetch, not @notionhq/client)
└── config/              # NestJS ConfigModule setup, validation schema, Swagger

Request flow

  1. User mentions bot in a Slack thread
  2. SlackController (application layer) receives the event, validates it's in a thread, fetches the parent message
  3. extractMessageData() (domain layer) extracts URL, title, user, content, and permalink from the message
  4. NotionService (infrastructure layer) creates a new page in the configured Notion database

Configuration

All config is loaded via NestJS ConfigModule from environment variables. The ConfigValues object (in src/config/config.ts) is the canonical typed config shape used throughout the app. Key env vars:

Variable Required Notes
NOTION_INTEGRATION_TOKEN Yes
NOTION_DB_ID Yes Target database
NOTION_API_VERSION Yes e.g. 2025-09-03
SLACK_PERIGEE_BOT_TOKEN Yes Bot OAuth token
SLACK_PERIGEE_APP_TOKEN Yes Socket mode token
SLACK_PERIGEE_SIGNING_SECRET Yes
SLACK_WORKSPACE_DOMAIN No Used for permalink construction

See .env.tmp for a full template.

Key patterns

  • Functional style: Domain services use higher-order functions and avoid mutation. extractMessageData(client) returns an async function (curried). Prefer map/reduce/filter over loops.
  • Notion API: NotionService uses raw fetch() (not the @notionhq/client SDK) for all API calls.
  • Slack: Uses @slack/bolt socket mode β€” no HTTP webhooks required. Bot connects via websocket using the App Token.
  • Logging: nestjs-pino with pretty-print in development, JSON in production.

TypeScript notes

tsconfig.json has relaxed settings (strictNullChecks: false, noImplicitAny: false). ESLint also allows any. These are intentional trade-offs for this project β€” do not tighten them without explicit instruction.

Docker

Multi-stage Dockerfile builds to a minimal Alpine image running as unprivileged user obuser (UID 1001) on port 4000. Use docker-run.sh for local container runs.

Commit conventions

Commitlint enforces conventional commits (Husky hook). Format: type: description (e.g., feat:, fix:, chore:).