Skip to content

refactor(cat): compose MobX workspace domains#1237

Merged
cungminh2710 merged 4 commits into
mainfrom
minhc/cat-mobx-refactor
Jul 5, 2026
Merged

refactor(cat): compose MobX workspace domains#1237
cungminh2710 merged 4 commits into
mainfrom
minhc/cat-mobx-refactor

Conversation

@cungminh2710

Copy link
Copy Markdown
Contributor

What changed

How to test

Checklist

  • I ran relevant checks locally (make fmt, make lint, make test)
  • I updated docs, comments, or examples when needed
  • This PR is scoped and ready for review

@cungminh2710
cungminh2710 requested a review from MuenYu as a code owner July 5, 2026 03:27
@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@vercel

vercel Bot commented Jul 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hyperlocalise Ignored Ignored Jul 5, 2026 4:27am

Request Review

@greptile-apps

greptile-apps Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR decomposes the monolithic CatWorkspaceStore into a composed architecture: a CatWorkspaceOrchestrator façade backed by three domain stores (CatQueueStore, CatSegmentStore, CatIntelligenceStore) and two controller classes (CatIntelligenceController, CatReviewController). The previous controller hook (use-cat-workspace-controller) is replaced by the slimmer useCatWorkspaceRuntime.

  • Ghost-segment bug fixed: mergeQueueMetaFromSnapshot now iterates segmentMeta.keys() (not just drafts.keys()) when pruning server-removed entries, and dirty segments filtered out by the server are retained in the queue with their selection preserved — verified by new unit and integration tests.
  • Controller lifecycle: controllers are wired and started via a single useEffect, with a configure() mechanism to update ports without restarting reactions when props like services or queueFilter change.
  • Context refactor: CatWorkspaceStoreProvider/useCatWorkspaceStore is replaced by CatWorkspaceProvider/useCatWorkspace, with the store created once per mount via an intentional empty useMemo dep (documented with an eslint-disable comment).

Confidence Score: 5/5

Safe to merge; the ghost-segment and dirty-selection regressions from prior reviews are addressed and covered by new tests, and no new correctness issues were introduced in the core data paths.

The refactor correctly moves the stale-segment pruning loop from iterating drafts to iterating segmentMeta, fixes selection retention for dirty filtered segments, and adds lifecycle tests that lock in these guarantees. The two findings are narrow edge cases (stale concordance after a runtime service swap, and unneeded MobX tracking on private fields) that do not affect normal operation.

cat-intelligence-controller.ts warrants a follow-up pass on the configure/in-flight interaction if lookupSegmentConcordance ever becomes a frequently-changing reference. cat-workspace-orchestrator.ts would benefit from explicitly opting its private lifecycle fields out of MobX observation.

Important Files Changed

Filename Overview
apps/hyperlocalise-web/src/components/cat/workspace/cat-workspace-orchestrator.ts New central façade composing CatQueueStore, CatSegmentStore, and CatIntelligenceStore; correctly fixes ghost-segment and dirty-selection bugs from prior PR comments; private lifecycle fields unintentionally made observable by makeAutoObservable.
apps/hyperlocalise-web/src/components/cat/workspace/controllers/cat-intelligence-controller.ts New controller for TM/concordance/context lookups; stale in-flight concordance responses can write stale data after configure() swaps the service.
apps/hyperlocalise-web/src/components/cat/workspace/controllers/cat-review-controller.ts New controller for validation, approval, draft-save, comments, and bulk actions; correctly handles AbortController, sequence-based staleness checks, and debounced format checks.
apps/hyperlocalise-web/src/components/cat/workspace/use-cat-workspace-runtime.ts Replaces use-cat-workspace-controller with a slimmer hook that wires the orchestrator and two controllers together; dependency arrays are complete and effects run in correct order.
apps/hyperlocalise-web/src/components/cat/workspace/cat-workspace-context.tsx New provider that mints a CatWorkspaceOrchestrator once per mount; deliberate empty useMemo deps are clearly documented, and the hook throws on missing context.
apps/hyperlocalise-web/src/components/cat/workspace/store/cat-queue-store.ts New domain store for queue selection, checked state, and segment metadata; replace/merge/reconcile methods all look correct and are covered by unit tests.
apps/hyperlocalise-web/src/components/cat/workspace/store/cat-segment-store.ts New domain store for segment drafts, comments, and loading flags; clean separation from queue concerns.
apps/hyperlocalise-web/src/components/cat/workspace/store/cat-intelligence-store.ts New domain store for format checks, segment intelligence, and loading flags; straightforward MobX observable class.
apps/hyperlocalise-web/src/components/cat/workspace/cat-workspace-container.tsx Updated to use CatWorkspaceProvider and useCatWorkspaceRuntime; removed initialState from inner observer props correctly, initialSegmentKeyOrId still flows to CatQueryBridge as needed.

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
  class CatWorkspaceOrchestrator {
    +CatQueueStore queue
    +CatSegmentStore segments
    +CatIntelligenceStore intelligenceState
    +attachControllers(...controllers)
    +start()
    +dispose()
    +hydrateFromServerSnapshot()
    +mergeQueueMetaFromSnapshot()
  }
  class CatQueueStore {
    +selectedSegmentId
    +segmentMeta Map
    +checkedSegmentIds Set
    +replace(segments)
    +merge(segments)
    +reconcileVisibleIds(ids)
  }
  class CatSegmentStore {
    +drafts Map
    +comments Map
    +hasDirtySegments bool
    +setTargetText()
    +markSaved()
  }
  class CatIntelligenceStore {
    +formatChecks
    +bySegment Record
    +contextLoadingSegmentIds Set
    +setChecks()
    +mergeSegment()
  }
  class CatIntelligenceController {
    -ports CatIntelligenceControllerPorts
    +configure(ports)
    +start()
    +dispose()
    +loadConcordance()
    +panelVisible()
    +askQuestion()
  }
  class CatReviewController {
    -ports CatReviewControllerPorts
    +configure(ports)
    +start()
    +dispose()
    +runChecks()
    +approve()
    +bulkApprove()
  }
  class useCatWorkspaceRuntime {
    <<hook>>
    creates CatIntelligenceController
    creates CatReviewController
    calls store.attachControllers()
    calls store.start()
  }
  CatWorkspaceOrchestrator *-- CatQueueStore
  CatWorkspaceOrchestrator *-- CatSegmentStore
  CatWorkspaceOrchestrator *-- CatIntelligenceStore
  CatIntelligenceController --> CatWorkspaceOrchestrator : reads/writes
  CatReviewController --> CatWorkspaceOrchestrator : reads/writes
  useCatWorkspaceRuntime --> CatWorkspaceOrchestrator : attaches controllers
  useCatWorkspaceRuntime --> CatIntelligenceController : owns
  useCatWorkspaceRuntime --> CatReviewController : owns
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
classDiagram
  class CatWorkspaceOrchestrator {
    +CatQueueStore queue
    +CatSegmentStore segments
    +CatIntelligenceStore intelligenceState
    +attachControllers(...controllers)
    +start()
    +dispose()
    +hydrateFromServerSnapshot()
    +mergeQueueMetaFromSnapshot()
  }
  class CatQueueStore {
    +selectedSegmentId
    +segmentMeta Map
    +checkedSegmentIds Set
    +replace(segments)
    +merge(segments)
    +reconcileVisibleIds(ids)
  }
  class CatSegmentStore {
    +drafts Map
    +comments Map
    +hasDirtySegments bool
    +setTargetText()
    +markSaved()
  }
  class CatIntelligenceStore {
    +formatChecks
    +bySegment Record
    +contextLoadingSegmentIds Set
    +setChecks()
    +mergeSegment()
  }
  class CatIntelligenceController {
    -ports CatIntelligenceControllerPorts
    +configure(ports)
    +start()
    +dispose()
    +loadConcordance()
    +panelVisible()
    +askQuestion()
  }
  class CatReviewController {
    -ports CatReviewControllerPorts
    +configure(ports)
    +start()
    +dispose()
    +runChecks()
    +approve()
    +bulkApprove()
  }
  class useCatWorkspaceRuntime {
    <<hook>>
    creates CatIntelligenceController
    creates CatReviewController
    calls store.attachControllers()
    calls store.start()
  }
  CatWorkspaceOrchestrator *-- CatQueueStore
  CatWorkspaceOrchestrator *-- CatSegmentStore
  CatWorkspaceOrchestrator *-- CatIntelligenceStore
  CatIntelligenceController --> CatWorkspaceOrchestrator : reads/writes
  CatReviewController --> CatWorkspaceOrchestrator : reads/writes
  useCatWorkspaceRuntime --> CatWorkspaceOrchestrator : attaches controllers
  useCatWorkspaceRuntime --> CatIntelligenceController : owns
  useCatWorkspaceRuntime --> CatReviewController : owns
Loading

Reviews (4): Last reviewed commit: "fix(cat): preserve dirty segments and ex..." | Re-trigger Greptile

@cungminh2710
cungminh2710 force-pushed the minhc/cat-mobx-refactor branch from 0584951 to ecfe818 Compare July 5, 2026 03:51
@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

Keep unsaved segments visible across queue refresh and local filter changes,
scope context loading to the selected segment, and only advance selection on
approve when the approved segment is still selected. Add unit tests for
controllers, domain stores, segment view composition, and store utilities.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@cungminh2710
cungminh2710 merged commit 05fd427 into main Jul 5, 2026
11 checks passed
@cungminh2710
cungminh2710 deleted the minhc/cat-mobx-refactor branch July 5, 2026 04:37
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