# Redmine Issue API Helpdesk Include Patch This repository carries a local RedmineUP Helpdesk API extension so external indexers can keep Redmine issues as the canonical object while still seeing Helpdesk customer metadata. ## Behavior `GET /issues/:id.json?include=journals,helpdesk` returns the normal Redmine issue API payload. When the issue also has a Helpdesk ticket, the issue object includes: ```json { "helpdesk_ticket": { "id": 35159, "contact_id": 1890, "message_id": "...", "source": 0, "is_incoming": true, "from_address": "customer@example.com", "to_address": "contact@ldrprep.com", "cc_address": "", "ticket_date": "2026-04-14T10:18:38Z", "contact": { "id": 1890, "name": "Customer Name", "company": "Customer Company", "email": "customer@example.com" } } } ``` For ordinary non-Helpdesk issues, callers must tolerate either `"helpdesk_ticket": null` or an omitted `helpdesk_ticket` field. The semantic indexer treats both as ordinary issue data with no Helpdesk contact metadata. ## Patch Locations - `plugins/redmine_contacts_helpdesk/app/views/issues/show.api.rsb` overrides Redmine 3.4.4's issue API view and adds the optional `include=helpdesk` block. - `plugins/redmine_contacts_helpdesk/lib/redmine_helpdesk/issue_api_serializer.rb` serializes Helpdesk ticket/contact fields without changing controller logic. - `plugins/redmine_contacts_helpdesk/lib/redmine_helpdesk.rb` loads the serializer during plugin preparation. ## Production Install Checklist Install these files into the production Redmine tree, preserving paths: ```text plugins/redmine_contacts_helpdesk/app/views/issues/show.api.rsb plugins/redmine_contacts_helpdesk/lib/redmine_helpdesk/issue_api_serializer.rb plugins/redmine_contacts_helpdesk/lib/redmine_helpdesk.rb plugins/redmine_contacts_helpdesk/LOCAL_CHANGELOG.md ``` Before copying, create a production rollback directory and preserve any existing versions of those files: ```sh stamp=$(date -u +%Y%m%dT%H%M%SZ) backup="$HOME/redmine-plugin-backups/helpdesk-issue-api-include-$stamp" mkdir -p "$backup" cd /usr/share/redmine for path in \ plugins/redmine_contacts_helpdesk/app/views/issues/show.api.rsb \ plugins/redmine_contacts_helpdesk/lib/redmine_helpdesk/issue_api_serializer.rb \ plugins/redmine_contacts_helpdesk/lib/redmine_helpdesk.rb \ plugins/redmine_contacts_helpdesk/LOCAL_CHANGELOG.md do if [ -e "$path" ]; then mkdir -p "$backup/$(dirname "$path")" cp -a "$path" "$backup/$path" fi done printf 'backup=%s\n' "$backup" ``` After copying, run syntax checks on the production host: ```sh cd /usr/share/redmine ruby -c plugins/redmine_contacts_helpdesk/lib/redmine_helpdesk.rb ruby -c plugins/redmine_contacts_helpdesk/lib/redmine_helpdesk/issue_api_serializer.rb ruby -c plugins/redmine_contacts_helpdesk/app/views/issues/show.api.rsb ``` Reload Passenger: ```sh cd /usr/share/redmine touch tmp/restart.txt ``` Then validate one known Helpdesk issue and one ordinary issue: ```sh curl -sS -H "X-Redmine-API-Key: $REDMINE_API_KEY" \ "$REDMINE_URL/issues/39779.json?include=journals,helpdesk" | jq '.issue.helpdesk_ticket' curl -sS -H "X-Redmine-API-Key: $REDMINE_API_KEY" \ "$REDMINE_URL/issues/.json?include=helpdesk" | jq '.issue.helpdesk_ticket' ``` The Helpdesk issue must include a ticket object with `contact.id`, `contact.name`, and `contact.email`. The non-Helpdesk issue should not error; `helpdesk_ticket` may be `null` or absent. Rollback is copying the backup files over the deployed files and touching `tmp/restart.txt` again. If a file did not exist before deployment, remove it during rollback. ## Reapplying After Redmine Core Upgrade 1. Compare the upgraded Redmine `app/views/issues/show.api.rsb` against this repository's override. 2. Copy any new upstream issue API fields into the plugin override. 3. Keep the `include_in_api_response?('helpdesk')` block after the issue timestamps and before optional child/attachment/relation/journal sections. 4. Run: ```sh ruby -c plugins/redmine_contacts_helpdesk/app/views/issues/show.api.rsb ruby tests/redmine_contacts_helpdesk/test_issue_api_serializer.rb ``` 5. On the LAN test instance, confirm: ```sh curl -H "X-Redmine-API-Key: $REDMINE_API_KEY" \ "http://192.168.50.170/issues/39779.json?include=journals,helpdesk" ``` The response should include `helpdesk_ticket.contact.id`, `helpdesk_ticket.contact.name`, and `helpdesk_ticket.contact.email` for a known Helpdesk issue. ## LAN Test Result On 2026-04-25, the patch was deployed to the LAN Redmine copy at `192.168.50.170`. - Remote backup: `/home/reddev/redmine-plugin-backups/helpdesk-issue-api-include-20260425T094236Z` - Syntax checks passed on the LAN host for the loader, serializer, and API view. - `GET /issues/39779.json?include=journals,helpdesk` returned contact `#1890 Callum Mackeonis `. - `semantic_index inspect preview-redmine --limit 3 --project customer-service` showed contact metadata on issue, journal, and contact chunks before Qdrant rebuild.