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).
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 |