Files
zammad/.dev/ai-agent-instructions.md

8.4 KiB

AI Agent Instructions

This file provides guidance on how to work with code in the Zammad repository.

Project Overview

Zammad is an open-source helpdesk/support platform. The backend is Ruby on Rails. There are two frontend stacks: the current production frontend is CoffeeScript (served via the Rails asset pipeline), and the new frontend is Vue 3 + TypeScript served via Vite (managed by pnpm), which is being built alongside it. PostgreSQL is used for persistence, Redis for ActionCable/GraphQL subscriptions, and GraphQL is the API layer between the new Vue apps and the backend.

Architecture

CoffeeScript frontend ──→ REST controllers ──→ Rails backend ──→ PostgreSQL
                                                    ↑
Vue 3 frontend (desktop/mobile) ──→ GraphQL API ────┘

New features target the Vue 3 + GraphQL stack. The CoffeeScript frontend uses REST controllers.

Key Directories (non-standard)

  • app/services/service/ — Service objects encapsulating business logic
  • app/graphql/gql/ — GraphQL schema, types, mutations, subscriptions
  • app/policies/ — Authorization policies (Pundit)
  • app/frontend/apps/desktop/ — Vue 3 desktop app
  • app/frontend/apps/mobile/ — Vue 3 mobile app
  • app/frontend/shared/ — Shared Vue components, composables, stores, GraphQL types, form system
  • app/assets/javascripts/ — CoffeeScript frontend (Spine + jQuery, legacy, still actively maintained)
  • lib/ — Library code, prefer minimal Rails coupling

General Guidelines

  • All new files except Markdown files (*.md) must include the Zammad copyright header.
  • Never edit translation files (i18n/*.po) directly — translations are managed via translations.zammad.org.

Code Comments

Comment only what the code cannot say itself: a non-obvious why, a workaround with its reason, a spec/protocol quirk, or a deliberate deviation from a pattern. Otherwise add no comment — clear naming and small methods are preferred over explanation.

  • One or two short lines, in the style of the surrounding file.
  • Never restate what the next line does, summarise a block, label sections (# --- setup ---), or narrate a change (# new, # was …, # fixed).
  • Keep out reasoning that belongs in the commit message, the issue or the MR description.
  • Never reference an issue from an internal repository (coordination-*) — this repository is publicly mirrored. Reference a public zammad/zammad issue, or state the reason without a link.
  • Never mark a fix for a security vulnerability as such — this repository is publicly mirrored, and the comment points at the vulnerable code in installations that are not updated yet.

UI Principles

  • Icon-only buttons need v-tooltip supplying the accessible name.
  • Hover/focus-only visible actions need to display on touch fallback
  • Responsive grids should adapt to their container
  • Translatable strings: use complete, meaningful source strings, sentence case for English source strings, and check for existing near-duplicate strings before adding new ones.
  • Red marks the point of no return: danger and remove stay only on controls that act immediately. A trigger that only opens a confirmation dialog or a confirming flyout is not red: a button becomes tertiary with an icon naming the action (trash3 for delete and discard, arrow-counterclockwise for reset), a menu item carries no variant, a remove icon button keeps its icon and takes the variant UX names per place. The decisive button in the dialog or flyout is danger.

Essential Commands

Backend

RAILS_ENV=test VITE_TEST_MODE=1 bundle exec rspec spec/path/to/file_spec.rb  # Run specific RSpec test
bundle exec rubocop --autocorrect app/path/to/file.rb                        # Lint specific Ruby file(s)

Frontend

Always use pnpm for frontend and cross-stack commands.

pnpm test --run app/frontend/path/to/file.spec.ts # Run specific Vitest test (never add `--`)
pnpm lint                                         # Run all linters
pnpm generate-graphql-api                         # Regenerate GraphQL types after schema changes
pnpm generate-setting-types                       # Regenerate Config types after setting changes

Development stack

A browser-clickable instance for this checkout. Start it via bin/dev rather than forego directly, and wait for it to answer before using it.

RAILS_ENV=development bundle exec rake db:create zammad:bootstrap:reset  # once per checkout
bin/dev                                                                  # does not exit; run it in the background

It serves on localhost:3000, with the websocket server on 6042 and Vite on 3036. Export ZAMMAD_RAILS_PORT, ZAMMAD_WEBSOCKET_PORT and VITE_RUBY_PORT before bin/dev to move them — the whole stack has to agree on them, so export, do not set them per process.

zammad:bootstrap:reset migrates, seeds and runs the auto wizard, which creates admin@example.com / test. Plain zammad:db:init skips the wizard and leaves the browser on the getting-started screen. Never run zammad:bootstrap:init or zammad:setup:db_config: they overwrite config/database.yml and prompt on stdin, which hangs a non-interactive session.

The test suite uses its own ports (3001 and 6043) and its own database, so it can run while the stack is up. Several checkouts, however, share the development database and Redis — only one stack per machine unless DATABASE_URL and REDIS_URL say otherwise.

Development Lifecycle

Issues are tracked on GitHub, code is developed on a self-hosted GitLab. GitHub hosts a read-only mirror. The agent uses the GitHub MCP server for issues and glab CLI for GitLab operations.

Stories are refined and broken down into task issues before this lifecycle starts (/refine-story → /plan-story). Bugs skip that and enter it directly.

Lifecycle: Understand → Research → Plan → Branch (/prepare-issue-branch) → Implement → Test → Review → Commit → MR (/create-mr) → Cherry-pick (/cherry-pick-to-stable)

See .dev/agent_docs/development_workflow.md for the full lifecycle and workflow rules.

Agent Reference Docs

You MUST read the relevant file(s) below before responding when working on that area — do NOT read them all upfront:

  • .dev/agent_docs/graphql_patterns.md — How to add/modify GraphQL types, mutations, queries, and subscriptions
  • .dev/agent_docs/frontend_patterns.md — Vue component conventions, composables, routing, and the form system
  • .dev/agent_docs/frontend_addon_layer.md — How an addon extends the Vue frontend via the build-time weave (Vapor-safe, multi-addon)
  • .dev/agent_docs/legacy_model_patterns.md — Concerns needed by new models used in the legacy stack: REST assets (one-to-one relations only) and client notifications
  • .dev/agent_docs/testing.md — How to write and run backend and frontend tests
  • .dev/agent_docs/testing_services_and_graphql.md — How to split spec coverage between a service and the query, mutation or subscription that calls it
  • .dev/agent_docs/service_patterns.md — Service object conventions and structure
  • .dev/agent_docs/knowledge_base_patterns.md — Knowledge base rules for the new stack (Vue/GraphQL/services) only: the single active knowledge base and the deliberate exceptions to it
  • .dev/agent_docs/database_migrations.md — How to write migrations and work with seeds

CodeGraph

In repositories indexed by CodeGraph (a .codegraph/ directory exists at the repo root), reach for it before grep/find or reading files when you need to understand or locate code:

  • MCP tool (when available): codegraph_explore answers most code questions in one call — the relevant symbols' verbatim source plus the call paths between them, including dynamic-dispatch hops grep can't follow. Name a file or symbol in the query to read its current line-numbered source. If it's listed but deferred, load it by name via tool search.
  • Shell (always works): pnpm exec codegraph explore "<symbol names or question>" prints the same output using the repository-pinned CodeGraph version.

If there is no .codegraph/ directory, skip CodeGraph entirely — indexing is the user's decision. If they ask to initialize it, run pnpm codegraph:init. Developer setup and removal are documented in doc/developer_manual/development_environment/codegraph-setup.md.