Skip to content

Refactor backend deleting, merging, undoing#4146

Closed
imnasnainaec wants to merge 19 commits intomasterfrom
frontier-delete-restore
Closed

Refactor backend deleting, merging, undoing#4146
imnasnainaec wants to merge 19 commits intomasterfrom
frontier-delete-restore

Conversation

@imnasnainaec
Copy link
Copy Markdown
Collaborator

@imnasnainaec imnasnainaec commented Feb 12, 2026

High-level goals:

  • For consistent control, only the WordService should directly add, update, or delete words with the WordRepository
    • LIFT import is the only exception
  • Any time a word is updated, the update should be complete before the old word is removed from the frontier
    • Reason: the update requires changes to two collections and cannot be done atomically in our current structure
  • When merging, for deleting children without a matching-guid parent, a copy of the child should be added to the words collection with Accessibility = Status.Deleted (to match when words are directly deleted)
  • On LIFT export, only words with Accessibility of Status.Deleted and with guid missing from the frontier should be added to the export as a 'deleted' word
    • The missing-from-Frontier requirement (previously the only requirement) is because people can undo a delete/merge; that only re-adds to the frontier and doesn't remove the deleted/merged copy from the word collection
    • The Accessibility requirement (new) is a safeguard against deleting words on import into FieldWorks that were unintentionally missing from the Frontier
    • This will require a database update to add Deleted copies of any words whose GUID is currently missing from the Frontier

This change is Reviewable

Summary by CodeRabbit

Release Notes

  • New Features

    • Added ability to retrieve word counts filtered by semantic domain.
  • Improvements

    • Enhanced word frontier retrieval to access complete frontier data.
    • Refactored word update and audio deletion operations for simplified workflows.
    • Updated word restoration logic with improved validation.
  • Changes

    • Audio deletion now returns the updated word identifier instead of the full word object.
    • Word restoration endpoint now returns status confirmation instead of a boolean flag.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 12, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR refactors the word frontier API by separating GetFrontier into two distinct operations: GetAllFrontier retrieves all frontier words for a project, while a new GetFrontier overload fetches a specific frontier word. IWordService.Update signature is simplified from four parameters to two, and DeleteAudio return type changes from Word? to string?. Corresponding implementations, controllers, services, tests, and frontend code are updated throughout.

Changes

Cohort / File(s) Summary
Interface Contracts
Backend/Interfaces/IWordRepository.cs, Backend/Interfaces/IWordService.cs
Replaced GetFrontier(projectId) with GetAllFrontier(projectId) and added GetFrontier(projectId, wordId, audioFileName) overload. Added GetWords(projectId, wordIds). Updated Update signature from four parameters to Update(userId, word). Changed DeleteAudio return type from Word? to string?. Removed DeleteFrontierWords method.
Repository Implementation
Backend/Repositories/WordRepository.cs
Renamed GetFrontier(projectId) to GetAllFrontier(projectId). Added GetFrontier(projectId, wordId, audioFileName) overload for single-word retrieval with optional audio filtering. Implemented new GetWords(projectId, wordIds) method. Removed DeleteFrontierWords bulk delete method.
Core Service Logic
Backend/Services/WordService.cs
Updated Update to signature Update(userId, word) with new frontier cloning and post-creation deletion pattern. Changed DeleteAudio to return string? (new word ID) instead of Word?. Reworked DeleteFrontierWord and RestoreFrontierWords to operate on frontier clones with updated validation and restoration semantics.
Supporting Services
Backend/Services/LiftService.cs, Backend/Services/MergeService.cs, Backend/Services/StatisticsService.cs
Replaced all GetFrontier(projectId) calls with GetAllFrontier(projectId). MergeService refactored merge/undo-merge logic with batch-like frontier deletion patterns. LiftService updated deletion filtering logic to use Deleted status and active GUID filtering.
Controller Updates
Backend/Controllers/AudioController.cs, Backend/Controllers/WordController.cs
Updated to use new method signatures: Update(userId, word) and DeleteAudio return type handling. Changed frontier retrieval from GetFrontier to GetAllFrontier where applicable. Added parameterized constructors with dependency injection. AudioController now uses GetFrontier(projectId, wordId) for specific word lookup. WordController added GetDomainWordCount endpoint.
Test Suites
Backend.Tests/Controllers/AudioControllerTests.cs, Backend.Tests/Controllers/WordControllerTests.cs, Backend.Tests/Controllers/LiftControllerTests.cs
Updated all frontier assertions to use GetAllFrontier(projectId). Adjusted expected result types and payloads for modified return signatures. Added test coverage for new validation scenarios (e.g., TestRestoreWordAlreadyInFrontier). Updated word update/delete flow expectations to match new API contracts.
Service Tests
Backend.Tests/Services/WordServiceTests.cs, Backend.Tests/Services/MergeServiceTests.cs
Updated test expectations to reflect new Update(userId, word) signature and DeleteAudio returning string?. Changed all frontier queries to GetAllFrontier(projectId). Adjusted assertions to validate new return shapes and Word.Guid vs Word.Id handling.
Mock Implementation
Backend.Tests/Mocks/WordRepositoryMock.cs
Renamed GetFrontier(projectId) to GetAllFrontier(projectId). Added GetFrontier(projectId, wordId, audioFileName) overload. Implemented GetWords(projectId, wordIds) helper. Updated GetWord to filter by both projectId and wordId. Removed DeleteFrontierWords stub.
Frontend
src/backend/index.ts, Backend/Models/Sense.cs
Changed restoreWord return type from Promise<boolean> to Promise<void>. Added trailing comma to Sense.Status.Protected enum member (formatting only).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

refactor, 🟨Medium

Suggested reviewers

  • jasonleenaylor

Poem

🐰 The frontier now wears a clearer dress,
All words at once, or one by one—no mess!
Update flows simpler, audio IDs return,
Each service adapts as the APIs turn.
With tests renewed and controllers aligned,
A refactored kingdom, well-designed! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.93% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (19 files):

⚔️ Backend.Tests/Controllers/AudioControllerTests.cs (content)
⚔️ Backend.Tests/Controllers/LiftControllerTests.cs (content)
⚔️ Backend.Tests/Controllers/WordControllerTests.cs (content)
⚔️ Backend.Tests/Mocks/WordRepositoryMock.cs (content)
⚔️ Backend.Tests/Services/MergeServiceTests.cs (content)
⚔️ Backend.Tests/Services/WordServiceTests.cs (content)
⚔️ Backend/Controllers/AudioController.cs (content)
⚔️ Backend/Controllers/WordController.cs (content)
⚔️ Backend/Interfaces/IWordRepository.cs (content)
⚔️ Backend/Interfaces/IWordService.cs (content)
⚔️ Backend/Models/Sense.cs (content)
⚔️ Backend/Repositories/WordRepository.cs (content)
⚔️ Backend/Services/LiftService.cs (content)
⚔️ Backend/Services/MergeService.cs (content)
⚔️ Backend/Services/StatisticsService.cs (content)
⚔️ Backend/Services/WordService.cs (content)
⚔️ src/backend/index.ts (content)
⚔️ src/components/SiteSettings/UserManagement/UserList.tsx (content)
⚔️ src/components/SiteSettings/UserManagement/index.tsx (content)

These conflicts must be resolved before merging into master.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Refactor backend deleting, merging, undoing' directly summarizes the main changes: refactoring the deletion, merging, and undo workflows in the backend services (WordService, MergeService) and related repository/controller updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch frontier-delete-restore

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.08%. Comparing base (30b5b90) to head (7a99eec).
⚠️ Report is 7 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##           master    #4146       +/-   ##
===========================================
+ Coverage   74.76%   86.08%   +11.31%     
===========================================
  Files         302       56      -246     
  Lines       11087     4843     -6244     
  Branches     1394      603      -791     
===========================================
- Hits         8289     4169     -4120     
+ Misses       2394      528     -1866     
+ Partials      404      146      -258     
Flag Coverage Δ
backend 86.08% <100.00%> (ø)
frontend ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

coderabbitai[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

@imnasnainaec

This comment was marked as resolved.

@coderabbitai

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

@imnasnainaec imnasnainaec force-pushed the frontier-delete-restore branch from 2021065 to 156ddc4 Compare February 13, 2026 20:02
@imnasnainaec
Copy link
Copy Markdown
Collaborator Author

Split off into many other prs, ultimately #4178

@imnasnainaec imnasnainaec deleted the frontier-delete-restore branch February 24, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant