link-stack/CLAUDE.md
2026-02-13 18:34:13 +01:00

6.4 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Repository Overview

This is a monorepo for CDR Link - a Zammad addon and supporting services built by the Center for Digital Resilience. It adds Signal, WhatsApp, and voice channel support to Zammad via a custom .zpm addon package, along with a standalone WhatsApp bridge service. It uses pnpm workspaces and Turborepo for orchestration.

Tech Stack:

  • Zammad 6.5.x as the core helpdesk platform
  • Ruby (Rails initializers, controllers, models, jobs) for the Zammad addon
  • TypeScript/Node.js for build tooling and the WhatsApp bridge
  • CoffeeScript for Zammad legacy UI extensions
  • Vue 3 for Zammad desktop UI extensions
  • Docker for containerization
  • PostgreSQL, Redis, Memcached as backing services

Project Structure

apps/
  bridge-whatsapp/         # Standalone WhatsApp bridge (Hapi.js + Baileys)
packages/
  zammad-addon-link/       # Zammad addon source (Ruby, CoffeeScript, Vue, TS)
    src/                   # Addon source files (installed into /opt/zammad/)
    scripts/build.ts       # Builds .zpm package from src/
    scripts/migrate.ts     # Generates new migration stubs
docker/
  zammad/                  # Custom Zammad Docker image
    Dockerfile             # Extends zammad/zammad-docker-compose base image
    install.rb             # Extracts addon files from .zpm at build time
    setup.rb               # Registers addon packages at container startup
    addons/                # Built .zpm files (gitignored, generated by turbo build)
  compose/                 # Docker Compose service definitions

Common Development Commands

pnpm install                        # Install all dependencies
turbo build                         # Build all packages (generates .zpm files)
npm run docker:zammad:build         # Build custom Zammad Docker image
npm run docker:all:up               # Start all Docker services
npm run docker:all:down             # Stop all Docker services
npm run docker:zammad:restart       # Restart railsserver + scheduler (after Ruby changes)
npm run update-version <version>    # Update version across all packages
npm run clean                       # Remove all build artifacts and dependencies

Zammad Addon Architecture

Addon Build & Deploy Pipeline

  1. turbo build runs tsx scripts/build.ts in packages/zammad-addon-link/
  2. Build script base64-encodes all files under src/, produces docker/zammad/addons/zammad-addon-link-v{version}.zpm
  3. docker/zammad/Dockerfile builds a custom image:
    • Copies .zpm files and runs install.rb to extract addon files into the Zammad directory tree
    • Rebuilds Vite frontend (bundle exec vite build) to include addon Vue components
    • Precompiles assets (rake assets:precompile) to include addon CoffeeScript
    • Applies sed patches (OpenSearch compatibility, entrypoint injection)
  4. At container startup, setup.rb registers the addon via Package.install() and runs migrations

How the Addon Extends Zammad

New files (no upstream conflict risk): Controllers, channel drivers, jobs, routes, policies, library classes, views, CSS, SVG icons, frontend plugins. These add Signal/WhatsApp/voice channel support.

Replaced stock files (HIGH conflict risk - must be manually merged on Zammad upgrades):

  • app/frontend/apps/desktop/pages/ticket/components/TicketDetailView/ArticleReply.vue - Adds channel whitelist filtering via cdr_link_allowed_channels setting
  • app/frontend/apps/desktop/pages/personal-setting/views/PersonalSettingNotifications.vue - Adds Signal notification recipient field
  • app/frontend/apps/desktop/components/Form/fields/FieldNotifications/FieldNotificationsInput.vue - Adds Signal column to notification matrix
  • app/frontend/apps/desktop/components/Form/fields/FieldNotifications/types.ts - Extended notification types
  • app/assets/javascripts/app/controllers/_profile/notification.coffee - Signal notification prefs (legacy UI)
  • app/assets/javascripts/app/controllers/_ui_element/notification_matrix.coffee - Signal column (legacy UI)
  • app/assets/javascripts/app/lib/mixins/ticket_notification_matrix.coffee - Notification matrix mixin
  • app/assets/javascripts/app/views/generic/notification_matrix.jst.eco - Notification matrix template
  • app/assets/javascripts/app/views/profile/notification.jst.eco - Notification profile template

Runtime monkey-patches (HIGH conflict risk):

  • config/initializers/opensearch_compatibility.rb - Prepends to SearchIndexBackend._mapping_item_type_es() to replace 'flattened' with 'flat_object' for OpenSearch
  • config/initializers/cdr_signal.rb - Injects after_create callbacks into Ticket::Article and Link models
  • config/initializers/cdr_whatsapp.rb - Injects after_create callback into Ticket::Article

Dockerfile-level patches:

  • lib/search_index_backend.rb - sed replaces 'flattened' with 'flat_object'
  • /docker-entrypoint.sh - sed injects addon install commands after # es config anchor
  • contrib/nginx/zammad.conf - Adds /link proxy location in embedded mode

Key Zammad API Dependencies

The addon depends on these Zammad interfaces remaining stable:

  • Channel::Driver interface (fetchable?, disconnect, deliver, streamable?)
  • Ticket::Article model callbacks and Sender/Type lookup by name
  • Link model and Link::Type/Link::Object
  • SearchIndexBackend._mapping_item_type_es method
  • Transaction backend registration system
  • Package.install(file:) / Package.uninstall(name:, version:) API
  • CreatesTicketArticles controller concern
  • Policy naming convention (controllers/<name>_controller_policy.rb)

Zammad Development Notes

  • After changing any Ruby files, restart railsserver and scheduler: npm run docker:zammad:restart
  • The addon must be rebuilt (turbo build) and the Docker image rebuilt (npm run docker:zammad:build) for changes to take effect in Docker
  • Use /zammad-compat <version> to check upstream Zammad for breaking changes before upgrading
  • The current Zammad base version is set in docker/zammad/Dockerfile as ARG ZAMMAD_VERSION

Docker Services

Defined in docker/compose/:

  • zammad.yml: zammad-init, zammad-railsserver, zammad-nginx, zammad-scheduler, zammad-websocket, zammad-memcached, zammad-redis
  • bridge-whatsapp.yml: bridge-whatsapp
  • postgresql.yml: postgresql
  • signal-cli-rest-api.yml: signal-cli-rest-api
  • opensearch.yml: opensearch + dashboards