Skip to content

refactor: comments and notifications doctype - #3700

Draft
RitvikSardana wants to merge 14 commits into
frappe:developfrom
RitvikSardana:refactor/comments-notifications-migration
Draft

refactor: comments and notifications doctype#3700
RitvikSardana wants to merge 14 commits into
frappe:developfrom
RitvikSardana:refactor/comments-notifications-migration

Conversation

@RitvikSardana

@RitvikSardana RitvikSardana commented Aug 15, 2026

Copy link
Copy Markdown
Member

Issue

Migrating helpdesk specific doctypes to their core equivalents.

  • HD Ticket Comment to Comment
  • HD Ticket Activity to Comment (Info), only tag, auto close and split rows
  • HD Notification to Notification Log
  • HD Comment Reaction reparented to Comment
  • File attachments repointed to Comment

Patches

  • setup_core_comments_schema: custom fields, notification types, permissions
  • migrate_ticket_comments_to_comment: name preserving insert select
  • migrate_ticket_activities_to_info_comments: rows with no Version row of their own
  • repoint_comment_reactions_and_files: reactions and attachments
  • migrate_hd_notifications_to_notification_log: notifications, with reopen rows retyped
  • relabel_comment_search_index: relabels stale FTS rows in place, falls back to a rebuild on failure

Notes

  • Comment names are preserved so existing mention links keep resolving
  • Every patch is chunked (50k) and idempotent, so an interrupted bench migrate resumes
  • Hash collisions are re detected on immutable fields and re inserted under a fresh name
  • Old patch entries are untouched, this only appends

Inside the patch: one HD Ticket Comment, one fate

What copy_chunk and resolve_name_collisions decide for each row on its way to core Comment. Every path is safe to reach twice, which is the whole idempotency story.

flowchart TD
    S["Next batch: 50,000 HD Ticket Comments<br/><i>name &gt; lower AND name ≤ upper</i>"] --> Q1{"Same name already exists<br/>as a core Comment?<br/><i>NOT EXISTS check</i>"}
    Q1 -- "no" --> INS["INSERT as core Comment,<br/>name + creation preserved"]
    INS --> COMMIT["Chunk commits,<br/>resumable checkpoint"]
    Q1 -- "yes, skipped by copy_chunk" --> Q2{"That core Comment has my creation<br/>and points at HD Ticket?"}
    Q2 -- "yes" --> MINE["It's my own migrated copy<br/>(re-run / resumed run), do nothing"]
    Q2 -- "no, a stranger owns my name" --> Q3{"Core Comment copy of me exists<br/>under ANY name?<br/><i>creation + owner fingerprint</i>"}
    Q3 -- "yes" --> FIXED["Prior run already resolved me,<br/>do nothing"]
    Q3 -- "no" --> FRESH["INSERT core Comment under fresh hash,<br/>relink reactions · files · notifications,<br/>log the rename"]

    style Q1 stroke:#9a6b1f,stroke-width:2px
    style Q2 stroke:#9a6b1f,stroke-width:2px
    style Q3 stroke:#9a6b1f,stroke-width:2px
    style INS stroke:#2e7d4f,stroke-width:2px
    style FRESH stroke:#2e7d4f,stroke-width:2px
    style MINE stroke-dasharray: 5 4
    style FIXED stroke-dasharray: 5 4
Loading

Crash anywhere? Committed chunks stay, the interrupted chunk rolled back atomically. Re-running bench migrate replays the same tree: finished rows land on a dashed no-op, unfinished rows take the green path. Same statement, same answer, no duplicates and no manual repair.

depends-on: frappe/frappe#41924

@RitvikSardana
RitvikSardana force-pushed the refactor/comments-notifications-migration branch from 7d2bd0d to aed3227 Compare August 15, 2026 08:58
@RitvikSardana
RitvikSardana force-pushed the refactor/comments-notifications-migration branch from 946d0cd to e021793 Compare August 15, 2026 16:08
@RitvikSardana RitvikSardana changed the title refactor: comments and notifications migration refactor: comments and notifications doctype Aug 15, 2026
Replace the hand-rolled ticket activity feed (TicketAgentActivities,
EmailArea, CommentBox, HistoryBox, FeedbackBox) with the framework's
ActivityTimeline + useActivityTimeline on both desktop and mobile.

- one shared fetch per ticket (SHARED_VISIBLE_TYPES); tabs filter client-side
- TimelineContainer bounds the feed; mobile page is a clamped column
- comment extras (reactions/attachments) via helpdesk.api.timeline
- deep links map ?highlight=comment-/communication- to timeline row keys
- drop dead server endpoints (get_ticket_activities, get_history,
  get_version_history, get_views)
- assert the Add Comment action lands in core Comment, not HD Ticket Comment
- reload the timeline after actions apply: the send-triggered reload races
  the action comment's socket append and can drop it until a refresh
- drop contact from the version fields worth a feed row
The page gated on prefetchActivityTimeline, which no longer exists — the
timeline store is only reachable through useActivityTimeline. TicketAgent now
starts the feed itself and latches its loading flag, so the doc and the feed
load behind a single spinner instead of two in sequence. Latched because a
doc_update reloads the feed, which must not blank the page.

Saved reply actions reload the feed through the mounted timeline, which
registers its refresh on the ticketMap entry, keyed per ticket so a reload
after a ticket switch hits the right feed.

Also moves the timeline imports to the @framework/ui/ActivityTimeline entry
point and picks up AttachmentChip for comment attachments.
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