Zammad Development Assistant
This skill provides expert guidance for working on Zammad, an open-source helpdesk/customer support platform with a Ruby on Rails backend and multiple frontend applications.
What This Skill Does
Helps developers understand and contribute to the Zammad codebase by providing context about:
Project architecture (legacy CoffeeScript app + modern Vue 3 apps)Tech stack and tooling (Rails, GraphQL, Vue, TypeScript, Pinia, Apollo)Project structure and key directoriesCoding standards and best practicesTesting strategies and toolsInstructions
1. Understand the Application Architecture
Zammad has three frontend applications:
**desktop-app (legacy)**: Located in `app/assets/`, uses CoffeeScript, Spine.js MVC framework, Sprockets, and REST API**desktop-view (modern)**: Located in `app/frontend/apps/desktop/`, uses Vue 3, TypeScript, GraphQL**mobile (modern)**: Located in `app/frontend/apps/mobile/`, uses Vue 3, TypeScript, GraphQL**Backend**: Ruby on Rails with PostgreSQL, Redis, ActionCable, Delayed Job, and GraphQL API
2. Navigate the Project Structure
**Frontend code:**
`app/assets/` - Legacy desktop-app (CoffeeScript/Sprockets)`app/frontend/apps/desktop/` - Modern desktop Vue app`app/frontend/apps/mobile/` - Modern mobile Vue app`app/frontend/shared/` - Cross-app shared code (components, utils, stores, GraphQL, i18n)`app/frontend/tests/` - Vitest setup and test helpers**Backend code:**
`app/controllers/`, `app/models/`, `app/views/` - Standard Rails MVC`app/graphql/` - GraphQL API definitions and resolvers`app/services/` - Business logic modules`app/jobs/`, `app/mailers/`, `app/channels/`, `app/policies/` - Rails standard directories`lib/` - Core extensions, helpers, integrations (GitHub, GitLab, Microsoft Graph, etc.), and business logic modules**Configuration and documentation:**
`doc/developer_manual/` - **Source of truth** for setup, testing, and standards`package.json`, `Gemfile`, `config/database.yml` - Dependencies and environment config`vite.config.mjs`, `tsconfig.base.json`, `eslint.config.ts` - Frontend tooling config`Procfile.dev` - Development process definitions3. Follow Tech Stack Conventions
**For Legacy desktop-app:**
Use Spine.js MVC patterns (most modules are Spine classes)Interact with REST API endpointsFollow `coffeelint.json` linting rulesWrite QUnit tests in `test/` directory**Minimize changes** - prefer implementing new features in modern Vue apps**For Modern Vue apps (desktop-view and mobile):**
Use Vue 3 Composition API with TypeScriptUse Pinia for state managementUse Apollo Client for GraphQL queries/mutationsStyle with Tailwind CSS utilitiesUse VueUse composables where applicableFollow path aliases defined in `tsconfig.base.json`**Do not cross-import** between desktop and mobile apps (ESLint enforces this boundary)Write unit/component tests with Vitest and Testing LibraryWrite E2E tests with CypressLint with ESLint, Stylelint, and PrettierWrap all user-facing strings for i18n (see `eslint.config.ts` for rules)**For Backend (Rails):**
Follow standard Rails conventionsGraphQL resolvers go in `app/graphql/`Business logic in services (`app/services/`)Core extensions and integrations in `lib/`Write RSpec tests in `spec/` directory4. Consult Authoritative Documentation
**Always refer to:**
`doc/developer_manual/` (index at `doc/developer_manual/index.md`) for setup, troubleshooting, testing, and coding standardsConfiguration files for runtime constraints and tool versions`tsconfig.base.json` for TypeScript path aliases`eslint.config.ts` for linting rules, copyright requirements, and i18n conventions5. Development Workflow
**Before making changes:**
1. Check the Developer Manual for relevant setup and standards
2. Identify which app(s) your change affects (legacy, desktop-view, or mobile)
3. Review existing patterns in similar files
4. Check for shared utilities in `app/frontend/shared/` before creating new ones
**When implementing features:**
Prefer modern Vue apps over legacy app for new featuresKeep PRs focused and scopedInclude tests for all new codeFollow existing file organization patternsUse shared components and utilities where possibleRespect app boundaries (no cross-imports between desktop/mobile)**Testing:**
Legacy app: QUnit tests in `test/`Vue apps: Vitest + Testing Library for unit/component testsBackend: RSpec tests in `spec/`E2E: Cypress tests6. Common Tasks
**Adding a new Vue component:**
Determine if it's app-specific or sharedPlace in `app/frontend/apps/{desktop|mobile}/components/` or `app/frontend/shared/components/`Use TypeScript and Composition APIStyle with Tailwind utilitiesWrite Vitest testsEnsure i18n strings are properly wrapped**Adding a GraphQL query/mutation:**
Define schema in `app/graphql/`Create resolver in appropriate GraphQL moduleAdd frontend queries in `app/frontend/shared/graphql/` (shared) or app-specific directoriesUse Apollo Client composables in Vue components**Modifying backend logic:**
Check if logic belongs in controller, model, service, or `lib/`Follow Rails conventionsUpdate or add RSpec testsCheck `lib/` directory for related helpers or integrations**Working with integrations:**
Integration code lives in `lib/` (e.g., `lib/github/`, `lib/gitlab/`, `lib/microsoft_graph/`)Check existing integration patterns before implementing new onesExamples
**Example 1: Adding a new shared Vue component**
1. Create component file in `app/frontend/shared/components/MyComponent/MyComponent.vue`
2. Use Composition API with TypeScript: `<script setup lang="ts">`
3. Style with Tailwind: `<div class="flex items-center gap-2">`
4. Wrap user-facing text: `{{ __('My translatable text') }}`
5. Create test file: `MyComponent.spec.ts` with Vitest and Testing Library
6. Export from shared components index if needed
**Example 2: Adding a GraphQL mutation**
1. Define mutation in `app/graphql/mutations/my_mutation.rb`
2. Create frontend mutation file in `app/frontend/shared/graphql/mutations/myMutation.api.ts`
3. Use in Vue component with Apollo composable: `useMutation(MyMutationDocument)`
4. Handle loading, error, and success states
**Example 3: Understanding legacy code**
1. Navigate to `app/assets/javascripts/`
2. Recognize Spine.js patterns: classes extending `App.Controller` or `App.Model`
3. REST API calls use jQuery AJAX or custom wrappers
4. Reference `coffeelint.json` for style rules
5. Consider refactoring to modern Vue apps if making significant changes
Important Constraints
Do not cross-import between desktop and mobile Vue appsAlways consult `doc/developer_manual/` as the source of truthPrefer modern Vue apps for new features over legacy appInclude tests with all code changesFollow i18n requirements for user-facing stringsUse Tailwind utilities for styling (avoid custom CSS where possible)Respect path aliases defined in TypeScript configNotes
The legacy desktop-app is being gradually replaced by modern Vue appsShared code in `app/frontend/shared/` promotes code reuse between desktop and mobileThe `lib/` directory contains extensive business logic, helpers, and third-party integrationsAlways reference config files for authoritative runtime and environment detailsKeep PRs focused and well-tested