Files
Jason Thistlethwaite 9ee9eb3ec6 Organized
2026-10-17 20:50:35 -04:00

3.4 KiB
Raw Permalink Blame History

Feature detail: Ticket sync foundation

Parent roadmap: ../features-for-redmine_tickets-sync
Status: largely implemented (2026-07-14); cron wiring still open
Primary script: redmine_tickets.py
Target project (first): customer-service

Intent

Durable, incremental local mirror of Redmine issues so humans and agents can work offline-first, cron-refresh frequently, and not re-pull full payloads for unchanged tickets.

Requirements

  • Sync tickets updated within a window (e.g. past 30 days) into a stable cache path (not timestamped per run).
  • Skip full fetch when cached updated_on still matches the list stub.
  • Support frequent refresh (every few minutes / couple times per hour) using a tight remote window after the initial warm-up.
  • Never delete old ticket JSON unless explicitly asked.
  • Optional small run-stats ring buffer for cron observability.

Cache locations

Environment Path
Production (https://rm.ldrprep.com) /home/jason/projects/redmine/cache/redmine_tickets
Dev / LAN (http://192.168.50.170) /home/jason/projects/redmine/cache-dev/redmine_tickets

Layout:

<cache-dir>/
  manifest.json
  run-stats.json          # optional, with --run-log
  <project>/
    <issue-id>.json

Server-side vs local filters (sync)

Flag Side Meaning
--status-id / --remote-status-id remote Redmine API status_id (*, open, closed, numeric)
--remote-updated-on remote Raw Redmine syntax: >=2026-06-14, >=2014-01-02T08:12:32Z, ><a|b
--remote-updated-since remote Convenience → >=... (YYYY-MM-DD, ISO, 30d, 2 days ago, …)
--remote-updated-before remote Convenience → <=...; with since → ><since|before
--updated-since / --updated-before / --status / --category local Post-filters after API list only

Implementation notes:

  • List stubs intentionally omit heavy include=journals,helpdesk; full include is only on per-ticket fetch when should_fetch is true.
  • Progress on by default; --quiet for cron.
  • Unit tests: tests/test_redmine_tickets_remote_filters.py
  • Run log: --run-log → default <cache-dir>/run-stats.json, keep last N (--run-log-keep, default 3).
cd /home/jason/projects/redmine

# Initial 30-day window (server-side)
./redmine_tickets.py \
  --base-url https://rm.ldrprep.com \
  --project customer-service \
  --cache-dir /home/jason/projects/redmine/cache/redmine_tickets \
  sync \
  --remote-status-id '*' \
  --remote-updated-since 30d \
  --run-log

# Frequent refresh
./redmine_tickets.py \
  --base-url https://rm.ldrprep.com \
  --project customer-service \
  --cache-dir /home/jason/projects/redmine/cache/redmine_tickets \
  sync \
  --remote-status-id '*' \
  --remote-updated-since 2h \
  --run-log \
  --quiet

Raw Redmine form:

./redmine_tickets.py ... sync --remote-updated-on '>=2026-06-14' --status-id '*'

Open

  • Scripts under cron-scripts/ installed + crontab running (live + dev)
  • ADJUST LATER (do not forget): cron still uses --remote-updated-since 30d on a few-minute cadence. Fine while validating (~3–4s/run after warm cache) but should tighten to 2h/6h (or marker-based since-last-success) so list pages stay cheap long-term. run-log-keep 20 is already set.
  • Optional: master storage + symlink organization of JSON (see parent roadmap)