| name | Agent Guide |
|---|---|
| description | Agent guide for Webhook Debugger & Logger codebase |
This document provides essential information for agents working in this repository.
- Type: Apify Actor (Node.js/Express)
- Language: JavaScript with JSDoc type annotations
- Runtime: Node.js 20+
- Storage: Apify Dataset + DuckDB (read model)
# All tests
npm test
# Run specific test file
npm test -- tests/unit/rate_limiter.test.js
# Unit tests only
npm test tests/unit/
# Integration tests
npm test tests/integration/
# E2E tests
npm test tests/e2e/
# With coverage (requires 90% threshold)
npm test -- --coverage
npm run test:coverage
# Stress tests
npm run test:stress
# Watch mode
npm test -- --watch# Lint all source
npm run lint
# Auto-fix lint issues
npm run lint:fix
# Type check (TypeScript-style checking for JS)
npm run typecheck
# Format code
npm run format
# Check formatting without changes
npm run format:check# Run locally
apify run
# Deploy to Apify
apify push- Each file should have a header comment block:
/**
* @file src/path/to/file.js
* @description Brief description of file purpose
* @module module/path
*/- Group imports: external libs → internal modules → utilities
- Use named exports for all modules
- Use ES modules (
import { x } from './module.js')
This project uses JSDoc with strict TypeScript checking:
- Define shared types in
src/typedefs.js - Use
@typedeffor complex object shapes - Use
@paramand@returnsfor all functions - Import types with
@typedef {import('./path').TypeName}
/** @typedef {import('./typedefs.js').WebhookEvent} WebhookEvent */
/**
* @param {WebhookEvent} event
* @returns {string}
*/
function processEvent(event) { ... }- Classes: PascalCase (
LogRepository,CircuitBreaker) - Functions/variables: camelCase (
executeQuery,findLogs) - Constants: UPPER_CASE in
src/consts/files - Private methods: Prefix with
#(class fields, e.g.,#buildWhereClause)
- Use centralized error handler middleware
- Log errors with structured logging (Pino)
- Sanitize error responses (never expose internal details for 5xx errors)
- Use typed error objects with
@typedef {import('./typedefs.js').CommonError}
- NEVER concatenate user input into SQL queries
- ALWAYS use parameterized queries (
$paramName) - Whitelist fields in SELECT statements
- Validate and sanitize JSON paths before use
- Import
setupCommonMocksBEFORE source code - Use shared helpers from
tests/setup/helpers/ - Prefer
waitForConditionoversleep() - Use
assertType<T>()instead of@type {any} - Always close DuckDB in
afterEachto prevent file locks
- Database access goes through
src/repositories/ - SQL queries use parameterized statements
- Results are mapped to typed objects
- Business logic in
src/services/ - Use circuit breaker pattern for external calls
- Express middleware in
src/middleware/ - Error handler should be last middleware
- All constants in
src/consts/ - Use index files for exporting related constants
| Path | Purpose |
|---|---|
src/main.js |
Actor entry point |
src/typedefs.js |
Shared type definitions |
src/repositories/LogRepository.js |
DuckDB data access |
src/db/duckdb.js |
Database connection |
src/routes/ |
Express API routes |
src/services/ |
Business logic |
src/consts/ |
All constants |
tests/setup/helpers/ |
Test utilities |
- Use parameterized queries to prevent SQL injection
- Convert BigInt to Number for JSON serialization
- Define schema in SQL constants files
- Tests must close DB connection in
afterEach
- Runtime: Express, Apify SDK, axios, DuckDB
- Dev: Jest, ESLint, Prettier, TypeScript
- Linting: ESLint with sonarjs plugin (strict)
- Formatting: Prettier (enforce with pre-commit hook)
- The project uses JSDoc with TypeScript strict mode (
tsconfig.jsonhascheckJs: true) - All tests run with
--runInBand(sequential) to avoid DB conflicts - ESLint rules: no magic numbers (except -1, 0, 1), no undefined variables
- Tests have 90% coverage threshold
- Use
useMockCleanup()for proper mock isolation