# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview 3CX TAPI is a dual-component integration that bridges the 3CX VoIP telephony web client with a CPA project management suite (CP Solutions) and a time tracking system (ZeitConsens). It is deployed as a Tampermonkey UserScript (client) communicating with a self-hosted ASP.NET Core API (server). ## Repository Structure ``` / ├── client/ # TypeScript UserScript (Tampermonkey) ├── server/ # C# ASP.NET Core 10.0 REST API └── 3CX_TAPI.user.js # Built distribution file (committed artifact) ``` ## Client Commands All commands run from `client/`: ```bash npm run build # Production webpack build → dist/3CX TAPI.prod.user.js npm run dev # Development build with live reload npm run lint # ESLint on TypeScript/JavaScript sources npm run anylize # Build with webpack-bundle-analyzer ``` ## Versioning & Release **Never edit these files manually — they are auto-generated:** - `client/package-lock.json` (generated by `npm install`) - `3CX_TAPI.user.js` (generated by build) To release a new version: 1. Bump `version` in `client/package.json` (1st digit = major, 2nd = feature, 3rd = bugfix/minor) 2. Build: `npm run build` (from `client/`) 3. Copy: `cp "dist/3CX TAPI.prod.user.js" ../3CX_TAPI.user.js` ## Server Commands All commands run from `server/src/CPATapi.Server/`: ```bash dotnet build # Debug build dotnet build -c Release # Release build dotnet publish -c Release -o /app/publish # Publish for deployment docker build -f Dockerfile -t cpatapi-server . # Docker image ``` No automated tests exist — only manual testing and client-side linting. ## Architecture ### Client (`client/src/`) A Tampermonkey UserScript injected into the 3CX web UI at `https://192.168.0.154:5001/*` and `https://cpsolution.my3cx.at:5001/*`. Entry point: `src/index.js`. Four main modules: - **`search.ts`** — Autocomplete contact lookup box injected near the call button. Debounces input and calls `GET /search?query=...`. On selection, dials the contact via 3CX. - **`call-history.ts`** — Monitors 3CX call history entries, does reverse lookup via `GET /callerid/{number}`, and adds a "PM Zeitbuchung" button that opens the Domizil PM time booking system with pre-filled metadata (contact ID, timestamp, duration). - **`call-notification.ts`** — Enriches incoming call GM notifications with contact name/medium fetched from TAPI directory. - **`status.ts`** — Polls `GET /availability/{user}` every 30 seconds and auto-syncs 3CX presence status with ZeitConsens login state (odd stamp count = logged in, even = logged out). User settings (username, enabled, status IDs) persist via `GM.setValue`. API base URL is configured in `src/config.ts` (`Config.tapi_server_url`). UserScript metadata (match URLs, GM grants, CORS) is in `config/metadata.cjs`. ### Server (`server/src/CPATapi.Server/`) ASP.NET Core 10.0 Web API using Dapper for SQL Server queries. Deployed as a Docker Linux container exposing port 8080. **API Endpoints:** | Endpoint | Description | |---|---| | `GET /search?query=` | Splits query into terms, searches `CP_TAPI_DIRECTORY` by name or number (top 10) | | `GET /contact` | Returns all contacts from `CP_TAPI_DIRECTORY` | | `GET /callerid/{number}` | Reverse lookup: extracts last 5 digits, returns first matching contact or 404 | | `GET /availability/users` | Lists active users from `MA_DATEN` | | `GET /availability/{user}` | Counts today's stamps in `BU` table; odd count = logged in | **Data flow:** Controllers → Repository interfaces → Dapper repositories → SQL Server. Two connection strings in `appsettings.json`: - `"Tapi"` — contacts database (`CP_TAPI_DIRECTORY` table) - `"ZeitConsens"` — time tracking database (`MA_DATEN`, `BU` tables) Logging uses Serilog with client IP, correlation ID, and user-agent enrichment.