Skip to content

Conversation

@torlando-tech
Copy link
Owner

@torlando-tech torlando-tech commented Jan 28, 2026

Summary

  • Fix "Clear All Announces" deleting contact announces, which caused "Node not found" errors when opening conversations with saved contacts
  • Adds deleteAllAnnouncesExceptContacts(identityHash) to DAO using a SQL subquery that exempts contacts scoped to the active identity
  • Routes ViewModel through identity-aware delete with fallback to original deleteAllAnnounces() when no active identity exists
  • Updates dialog text to inform users that contacts are preserved
  • Adds 6 DAO tests (Robolectric + in-memory Room) and 3 ViewModel tests (MockK) covering deletion, preservation, identity scoping, edge cases, and regression

Test plan

  • Full project builds: assembleDebug
  • All unit tests pass: testDebugUnitTest
  • Code quality: detektCheck
  • Manual: Tap "Clear All Announces" → non-contact announces removed, contact announces preserved
  • Manual: Open conversation with saved contact after clearing → no "Node not found" error
  • Manual: Switch identities → only active identity's contacts are preserved

Closes #365

🤖 Generated with Claude Code

torlando-tech and others added 9 commits January 27, 2026 20:01
Phase 2.1: Clear Announces Preserves Contacts
- Room DAO query modification identified
- SQL subquery pattern documented
- Identity-scoped filtering strategy defined
- Test infrastructure mapped
Phase 02.1: Clear Announces Preserves Contacts (#365)
- 2 plan(s) in 2 wave(s)
- Wave 1: Production fix (DAO + Repository + ViewModel + UI)
- Wave 2: Tests (DAO + ViewModel tests)
- Ready for execution
- Add deleteAllAnnouncesExceptContacts(identityHash) to AnnounceDao
- SQL subquery excludes contact announces for the given identity
- Repository method delegates to DAO
- Original deleteAllAnnounces() preserved for backward compatibility
- ViewModel deleteAllAnnounces() now uses identity-aware delete
- Gets active identity and calls deleteAllAnnouncesExceptContacts()
- Falls back to deleteAllAnnounces() if no active identity
- Updated dialog text to mention contact preservation
Tasks completed: 2/2
- Task 1: Add identity-aware delete to DAO and Repository layers
- Task 2: Update ViewModel and UI dialog to preserve contacts

SUMMARY: .planning/phases/02.1-clear-announces-preserves-contacts/02.1-01-SUMMARY.md
- Add 6 Robolectric tests using in-memory Room database
- Test non-contact deletion, contact preservation, identity scoping
- Test edge cases: empty contacts, empty announces, other identities
- Regression test: original deleteAllAnnounces still deletes everything
- All tests execute real SQL queries against Room database

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add mock setup for deleteAllAnnouncesExceptContacts in setup()
- Update existing test to verify identity-aware delete is called
- Update error handling test to use new method
- Add new test for null-identity fallback behavior
- All tests use MockK to verify repository method calls

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tasks completed: 2/2
- Task 1: Add DAO tests for deleteAllAnnouncesExceptContacts
- Task 2: Add ViewModel tests for identity-aware delete routing

SUMMARY: .planning/phases/02.1-clear-announces-preserves-contacts/02.1-02-SUMMARY.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sentry
Copy link

sentry bot commented Jan 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 28, 2026

Greptile Overview

Greptile Summary

This PR fixes a bug where "Clear All Announces" was deleting contact announces, causing "Node not found" errors when opening conversations with saved contacts.

Implementation:

  • Added deleteAllAnnouncesExceptContacts(identityHash) to AnnounceDao using a SQL subquery that filters contacts by the active identity
  • Routed AnnounceStreamViewModel.deleteAllAnnounces() through identity-aware deletion with fallback to original deleteAllAnnounces() when no active identity exists
  • Updated UI dialog text to inform users that contacts are preserved
  • Added comprehensive test coverage: 6 DAO tests (Robolectric + in-memory Room) and 3 ViewModel tests (MockK)

Key changes:

  • The SQL query correctly uses a NOT IN subquery to exempt announces whose destinationHash matches contacts scoped to the active identity
  • Identity scoping ensures proper data isolation in multi-identity scenarios
  • Tests cover preservation, deletion, identity scoping, edge cases, and regression scenarios
  • All builds and tests pass according to the PR description

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is clean, well-tested, and uses proper SQL patterns. The SQL subquery correctly preserves identity-scoped contacts while deleting other announces. The fallback mechanism ensures backward compatibility when no active identity exists. Test coverage is comprehensive with 9 tests covering all scenarios including edge cases. Code style improvements are minor formatting changes. No security vulnerabilities or logical errors identified.
  • No files require special attention

Important Files Changed

Filename Overview
data/src/main/java/com/lxmf/messenger/data/db/dao/AnnounceDao.kt Added deleteAllAnnouncesExceptContacts(identityHash) SQL query using subquery to preserve contact announces, formatting improvements
data/src/main/java/com/lxmf/messenger/data/repository/AnnounceRepository.kt Added repository method deleteAllAnnouncesExceptContacts(identityHash) delegating to DAO, code style improvements
app/src/main/java/com/lxmf/messenger/viewmodel/AnnounceStreamViewModel.kt Updated deleteAllAnnounces() to use identity-aware deletion with fallback to original method when no active identity, formatting improvements
app/src/main/java/com/lxmf/messenger/ui/screens/AnnounceStreamScreen.kt Updated dialog text to inform users that contacts are preserved when clearing announces, formatting improvements
data/src/test/java/com/lxmf/messenger/data/db/dao/AnnounceDaoTest.kt Added 6 comprehensive tests for deleteAllAnnouncesExceptContacts covering preservation, identity scoping, edge cases, and regression
app/src/test/java/com/lxmf/messenger/viewmodel/AnnounceStreamViewModelTest.kt Added 3 ViewModel tests verifying identity-aware delete routing, error handling, and fallback behavior when no active identity

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as AnnounceStreamScreen
    participant VM as AnnounceStreamViewModel
    participant Repo as AnnounceRepository
    participant DAO as AnnounceDao
    participant DB as Room Database
    
    User->>UI: Tap "Clear All Announces"
    UI->>UI: Show ClearAllAnnouncesDialog
    User->>UI: Confirm deletion
    UI->>VM: deleteAllAnnounces()
    
    VM->>VM: Get active identity
    alt Active identity exists
        VM->>Repo: deleteAllAnnouncesExceptContacts(identityHash)
        Repo->>DAO: deleteAllAnnouncesExceptContacts(identityHash)
        DAO->>DB: DELETE FROM announces<br/>WHERE destinationHash NOT IN<br/>(SELECT destinationHash FROM contacts<br/>WHERE identityHash = :identityHash)
        DB-->>DAO: Contact announces preserved
        DAO-->>Repo: Success
        Repo-->>VM: Success
        VM->>VM: Log: "Deleted non-contact announces"
    else No active identity
        VM->>Repo: deleteAllAnnounces()
        Repo->>DAO: deleteAllAnnounces()
        DAO->>DB: DELETE FROM announces
        DB-->>DAO: All announces deleted
        DAO-->>Repo: Success
        Repo-->>VM: Success
        VM->>VM: Log: "Deleted all announces (no active identity)"
    end
    
    VM-->>UI: Operation complete
    UI->>User: Dialog dismissed, list updated
Loading

@torlando-tech torlando-tech merged commit 683e8f9 into main Jan 28, 2026
10 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.

Clearing all announces function should not delete the announces in My Contacts

2 participants