Skip to content

Track topic status-change history in a new table - #1

Merged
darreneid merged 5 commits into
stagingfrom
feature/track-status-history-in-new-table
Jul 28, 2026
Merged

Track topic status-change history in a new table#1
darreneid merged 5 commits into
stagingfrom
feature/track-status-history-in-new-table

Conversation

@darreneid

Copy link
Copy Markdown
Collaborator

What

Adds a community_custom_fields_topic_status_changes table that records a row every time a topic's support status changes, for audit/analytics.

How

  • New TopicStatusChange model with record as the single writer; no-ops unless status actually changes.
  • Called from the two places transitions happen: the admin PUT controller (source: "api_update") and the post_created handler (source: "post_creation"). topic_created is intentionally not recorded.
  • Each row captures from_status/to_status, assignee_id (the assignee before the change), the trigger (user_id for api_update, post_id for post_creation), duration (seconds in the status being left), and source.
  • duration derives from the prior recorded change, falling back to the status field's set-time (topic_custom_fields) for pre-existing topics, then topic.created_at. The migration backfills existing rows from history.
  • Controller now validates status against new/open/snoozed/closed (422 otherwise).

Testing

Verified end-to-end against a Discourse dev host (real HTTP PUT + real PostCreator): recording on both paths, trigger/assignee/duration columns, duration chaining + pre-existing-topic fallback, no-row-on-no-change, status enforcement, and migration backfill + NOT NULL. 12/12 checks pass.

🤖 Generated with Claude Code

darreneid and others added 5 commits July 23, 2026 18:07
- add TopicStatusChange model + migration
- record changes from the admin controller (api_update) and post_created
- enforce allowed statuses in the controller

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- new migration adds user_id, post_id, and duration (bigint, NOT NULL),
  backfilling duration for existing rows from their created_at history
- record the acting user (api_update) or triggering post (post_creation)
- compute duration as seconds spent in the status being left, chained
  off the prior change and falling back to topic.created_at

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
For a topic with no existing status-change row, fall back to when the
current status was set (its topic_custom_fields row, captured before the
change) rather than topic.created_at, so pre-existing topics get an
accurate first duration instead of time-since-creation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- format Ruby files per the plugin's .streerc (trailing commas, 100-col
  wrap); routes/engine/spec were pre-existing violations
- add the schema annotation block to TopicStatusChange for the
  annotations_tests check

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@darreneid
darreneid changed the base branch from main to staging July 28, 2026 16:38
@darreneid
darreneid merged commit b119f6a into staging Jul 28, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant