# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Repository Structure This is a multi-project repository containing: - **web-app/**: Next.js 14 utility bills tracking application - **docker-stack/**: Docker Compose configurations and deployment scripts - **housekeeping/**: Database backup and maintenance scripts - **email-server-worker/**: Background worker service with HTTP health monitoring Each project is self-contained with its own dependencies. ## Development Commands All commands should be run from within the respective project directory. **Web App** (`cd web-app`): - `npm install` - Install dependencies - `npm run dev` - Start development server - `npm run build` - Build production version - `npm start` - Start production server - `npm run prettier` - Format code - `npm run seed` - Seed database with initial data **Housekeeping** (`cd housekeeping`): - `./db-backup--standalone.sh` - Run standalone database backup - `./db-backup--swarm.sh` - Run swarm database backup - `./db-dump--standalone.sh` - Run standalone database dump - See housekeeping/README.md for more details **Email Server Worker** (`cd email-server-worker`): - `npm install` - Install dependencies - `npm run start` - Start development server with nodemon - `npm run build` - Build TypeScript to JavaScript - `npm run test` - Run tests with Jest in watch mode - `npm run run-server` - Run built server from ./build directory ## Deployment Commands **Building Docker Image** (`cd web-app`): - `./build.sh ` - Build Docker image **Deploying** (`cd docker-stack`): - `./deploy-standalone.sh ` - Deploy with docker-compose (standalone) - `./deploy-swarm.sh ` - Deploy with Docker Swarm ## Architecture Overview This is a Next.js 14 utility bills tracking application ("Evidencija Režija") with the following key components: ### Tech Stack - **Framework**: Next.js 14 with App Router and standalone output for Docker - **Authentication**: NextAuth v5 with Google OAuth - **Database**: MongoDB with connection pooling - **Internationalization**: next-intl (Croatian/English) - **Styling**: Tailwind CSS with DaisyUI components - **Deployment**: Docker with MongoDB 4.4.27 (AVX compatibility) ### Core Architecture Patterns **Multi-user Data Isolation**: All database operations use the `withUser` higher-order function from `web-app/app/lib/auth.ts:102` to automatically inject authenticated user ID into queries, ensuring data isolation between users. **Server Actions Pattern**: Form handling uses Next.js Server Actions with Zod validation. Actions are defined in `web-app/app/lib/actions/` and follow the pattern: ```typescript export const actionName = withUser(async (user: AuthenticatedUser, ...args) => { // Server action implementation with automatic user context }); ``` **Internationalization**: Uses next-intl with locale-based routing. Messages are in `web-app/messages/` directory. The middleware handles both auth and i18n routing. ### Key Files & Responsibilities - `web-app/middleware.ts` - Handles authentication and i18n routing, defines public pages - `web-app/app/lib/auth.ts` - NextAuth configuration, `withUser` HOF for user context - `web-app/app/lib/dbClient.ts` - MongoDB connection with development/production handling - `web-app/app/lib/actions/` - Server actions for data mutations (locations, bills, months) - `web-app/app/i18n.ts` - Internationalization configuration (Croatian default) - `web-app/next.config.js` - Standalone build config with `serverActions.allowedOrigins` for Docker deployment - `housekeeping/` - Database backup and maintenance scripts ### Database Schema - **Collections**: Locations, Bills, Months (year-month periods) - **User Association**: All documents include `userId` field for multi-tenant isolation - **Database Name**: "utility-bills" ### Docker Deployment Notes - Uses standalone Next.js build for Docker optimization - MongoDB 4.4.27 required for older CPU compatibility (no AVX instructions) - `HOSTNAME=0.0.0.0` with `serverActions.allowedOrigins` config to handle reverse proxy headers - Environment variables: `MONGODB_URI`, `GOOGLE_ID`, `GOOGLE_SECRET`, `AUTH_SECRET` ### Barcode/QR Code Feature - Uses `@zxing/library` and `@zxing/browser` for PDF document scanning - Heavy barcode decoding operations should be moved to background threads if performance issues arise - PDF processing with `pdfjs-dist` for utility bill scanning ### Testing & Code Quality - ESLint with Next.js and Prettier configurations - No specific test framework configured - check with user before assuming testing approach ## Email Server Worker Architecture The email-server-worker is a TypeScript-based background worker service that combines periodic task execution with HTTP health monitoring and metrics collection. ### Tech Stack - **Runtime**: Node.js with TypeScript - **Framework**: Express for HTTP endpoints - **Metrics**: Prometheus (prom-client) with custom PRTG adapter - **Testing**: Jest with TypeScript support ### Core Architecture: Worker Pattern The service implements a **self-contained worker pattern** that runs periodic background tasks while exposing HTTP endpoints for monitoring. **Entry Point** (`email-server-worker/src/entry.ts:1`): - Creates Express HTTP server with graceful shutdown support (stoppable) - Starts the worker via `startSyncWorker()` from `email-server-worker/src/workRunner.ts:134` - Handles SIGTERM/SIGINT for graceful shutdown (Docker-compatible) - Calls `disposeSyncWorker()` on shutdown to allow pending work to complete **Work Runner** (`email-server-worker/src/workRunner.ts:1`): The work runner implements a self-scheduling loop with the following characteristics: - **Self-Scheduling Loop**: After completing work, schedules next execution via `setTimeout(workRunner, PULL_INTERVAL)` at `email-server-worker/src/workRunner.ts:113` - **Graceful Shutdown**: Tracks pending work via Promise, allows in-flight operations to complete before shutdown - **Status Tracking**: Exports `workerRunnerInfo` with `status` and `lastWorkTime` for health monitoring - **Error Isolation**: Worker errors don't crash the process - caught, logged, and execution continues - **Metrics Integration**: Automatic Prometheus metrics collection (duration, success/failure counters) - **Single Work Instance**: Ensures only one work cycle runs at a time via `pendingWork` Promise Work Runner States (WorkerRunnerStatus enum): - `init` - Initial state before first run - `beginWork` - Work cycle started - `workDone` - Work completed successfully - `disposed` - Worker stopped, no longer scheduling - Other states track Prometheus stats updates **Worker Implementation Pattern**: Workers must export a `doWork` function with signature: ```typescript export const doWork = async () => { // Perform periodic work here // Throw errors to increment failedRequestCounter // Return normally to increment successfulRequestCounter }; ``` The work runner imports and calls this function at `email-server-worker/src/workRunner.ts:88`. ### Key Files & Responsibilities **Core Worker Files**: - `email-server-worker/src/entry.ts` - HTTP server setup, signal handling, worker lifecycle management - `email-server-worker/src/workRunner.ts` - Self-scheduling loop, graceful shutdown, metrics integration - `email-server-worker/src/app.ts` - Express app configuration, route registration - `email-server-worker/src/lib/logger.ts` - Debug logger factory (uses 'debug' package) **HTTP Routes** (`email-server-worker/src/routes/`): - `healthcheckRouter.ts` - Health check endpoint (checks worker status via `workerRunnerInfo`) - `metricsRouter.ts` - Prometheus metrics endpoint - `prtgMetricsRouter.ts` - PRTG-compatible metrics adapter - `pingRouter.ts` - Simple ping/pong endpoint - `errorRouter.ts` - Structured error handler for expected errors - `finalErrorRouter.ts` - Catch-all error handler for unexpected errors **Infrastructure**: - `email-server-worker/src/lib/metricsCounters.ts` - Prometheus counter/histogram definitions - `email-server-worker/src/lib/initTools.ts` - Utility functions (coalesce, etc.) - `email-server-worker/src/lib/serializeError.ts` - Error serialization for logging - `email-server-worker/src/lib/Prometheus2Prtg.ts` - Converts Prometheus metrics to PRTG XML format ### Environment Variables **Required**: - `PULL_INTERVAL` - Milliseconds between work cycles (default: "10000") **Optional**: - `PORT` - HTTP server port (default: "3000") - `PROMETHEUS_APP_LABEL` - App label for Prometheus metrics (default: "evo-open-table-sync-svc") - `PROMETHEUS_HISTOGRAM_BUCKETS` - Histogram bucket sizes (default: "0.1, 0.5, 1, 5, 10") - `DEBUG` - Debug namespaces for console logging (e.g., "server:server") - `ENV` - Environment mode: "dev", "jest" (affects logging behavior) ### Creating a New Worker To implement a new worker task: 1. **Create worker file** (e.g., `email-server-worker/src/myWorker.ts`): ```typescript export const doWork = async () => { // Implement your periodic task here logger.info("Work Title", "Work completed successfully"); // Throw errors to mark as failed: // throw new Error("Something went wrong"); }; ``` 2. **Update `workRunner.ts`** import at line 6: ```typescript import { doWork } from "./myWorker"; ``` 3. **Add environment variables** to `email-server-worker/src/types/environment.d.ts` as needed 4. **Update `package.json` metadata** if the service purpose changes (name, description) ### Docker Deployment - Uses `stoppable` library for graceful shutdown (10-second timeout before force-close) - Health check endpoint at `/healthcheck` verifies worker is running and not stalled - Prometheus metrics at `/metrics` for monitoring - PRTG-compatible metrics at `/prtg` for legacy monitoring systems - Graceful shutdown ensures work in progress completes before container stops ### Testing - **Framework**: Jest with esbuild-jest for TypeScript - **Test Location**: `email-server-worker/tests/` - **Mocks**: Common mocks in `email-server-worker/tests/__mocks__/` (prom-client) - **Test Pattern**: Co-located with source in `tests/` mirroring `src/` structure - **Run Tests**: `npm run test` (watch mode)