3 Commits
Author SHA1 Message Date
jared 1d03800ab2 Widen bulk_operations.status so partial bulk results can be recorded (#21)
Lint / PHP (phpcs PSR-12) (push) Successful in 26s
Lint / JS (eslint) (push) Successful in 9s
Lint / PHP requirements (version + extensions) (push) Successful in 22s
Lint / Notify on failure (push) Skipped
Security / PHP Security (semgrep) (push) Successful in 1m8s
Lint / Deploy (push) Successful in 3s
Found while verifying #21 against the live schema: the model writes
'completed_with_errors' (21 chars) when a bulk operation finishes with
per-ticket failures, but bulk_operations.status was varchar(20), so the
write failed with "Data too long for column 'status'".

This was latent — bulk status changes previously forced every transition
through, so failed was always 0. Now that they honour the Workflow
Designer, a partially-skipped batch is a normal outcome and hits it.

- migrations/001 widens the column to varchar(32) (idempotent).
- The baseline is updated to match, for fresh installs.
- The bookkeeping UPDATE is wrapped in a try/catch: it runs after the
  ticket changes are committed, so an instance deployed ahead of its
  migrations must not turn a completed operation into an error response.

Verified against the live database with a disposable-ticket harness:
comment-required rejection changes nothing, undefined transitions are
refused per ticket with a reason, allowed transitions still work, mixed
batches apply the valid half, and an already-Closed ticket is a no-op.
2026-08-07 22:40:48 -04:00
jaredandClaude Opus 4.8 5cf5aa9591 API keys: add read/read_write scopes + admin scope selector & pagination
Foundation for extending the Bearer API beyond create-only:
- api_keys gains a scope column (read | read_write); baseline schema updated
  and the column applied to the live DB. Existing keys default to
  read_write so the hwmon create key keeps working.
- ApiKeyModel: createKey() takes a validated scope; validateKey() always
  surfaces scope (defaults read_write); getAllKeys() is paginated
  ({keys,total,page,perPage}, key_hash stripped).
- ApiKeyAuth: expose getKeyContext() (scope/key_name/created_by/api_key_id)
  and requireScope() (403 on insufficient scope); existing return values
  unchanged.
- create_ticket_api.php: require read_write scope (a read key can't create).
- Admin /admin/api-keys: scope selector on the create form, a scope column,
  and pagination (revoked keys were stacking up).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 18:24:50 -04:00
jaredandClaude Opus 4.8 d6214a0339 Add schema baseline, fix cron/retention, restore cleanup, correct docs
Lint / PHP (phpcs PSR-12) (push) Successful in 26s
Lint / JS (eslint) (push) Successful in 12s
Lint / PHP requirements (version + extensions) (push) Successful in 21s
Security / PHP Security (semgrep) (push) Successful in 1m11s
Lint / Deploy (push) Successful in 2s
Lint / Notify on failure (push) Has been skipped
Lint / PHP (phpcs PSR-12) (pull_request) Successful in 47s
Lint / JS (eslint) (pull_request) Successful in 12s
Lint / PHP requirements (version + extensions) (pull_request) Successful in 59s
Security / PHP Security (semgrep) (pull_request) Successful in 1m6s
Lint / Deploy (pull_request) Has been skipped
Lint / Notify on failure (pull_request) Has been skipped
- migrations/000_baseline.sql: full schema baseline captured from prod
  (validated on a throwaway DB: 17 tables/17 FKs), so the schema is
  reproducible for fresh installs / disaster recovery
- create_recurring_tickets cron: send the Matrix ticket-created
  notification and invalidate the stats cache like the other create paths
- create_ticket_api.php + TicketController::create: invalidate the stats
  cache on create/escalate/reopen so dashboard counts aren't stale
- scripts/cleanup_orphan_uploads.php: restored, made safe (24h mtime
  grace, 9-digit-dir only, skips avatars/symlinks, matches the unique
  filename column, --dry-run)
- cron/cleanup_audit_log.php: enforce the configured audit-log retention
  (deleteOldLogs was implemented but never called)
- README: correct CSRF-rotation, hwmon dedup (no 24h window), SLA (no P3),
  stats-cache callers, and the project structure/endpoint listing
- .env.example: document TRUSTED_PROXIES fail-open risk and .env quoting

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 16:11:26 -04:00