154 lines
5.0 KiB
Markdown
154 lines
5.0 KiB
Markdown
# 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/<non_helpdesk_issue_id>.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 <callum@safetagtracking.com>`.
|
|
- `semantic_index inspect preview-redmine --limit 3 --project customer-service`
|
|
showed contact metadata on issue, journal, and contact chunks before Qdrant
|
|
rebuild.
|