Files
2026-04-10 11:34:45 +02:00

3.9 KiB

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/:

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/:

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.