Skip to content

feat: detect channel moves on startup, migrate messages and permissions#2433

Merged
Yeraze merged 3 commits intomainfrom
feat/startup-channel-migration
Mar 25, 2026
Merged

feat: detect channel moves on startup, migrate messages and permissions#2433
Yeraze merged 3 commits intomainfrom
feat/startup-channel-migration

Conversation

@Yeraze
Copy link
Owner

@Yeraze Yeraze commented Mar 25, 2026

Summary

When channels are rearranged externally (e.g., via the official Meshtastic app), MeshMonitor now detects the changes on config sync and automatically migrates messages and permissions.

Closes #2425

What happens on startup

  1. Snapshot channel PSKs before config sync starts
  2. Compare after configComplete - detect moves/swaps by PSK matching
  3. Migrate messages to follow channel content to new slots (transactional)
  4. Migrate permissions so user access follows the channel
  5. New channels default to no permissions for non-admin users
  6. Audit log records all detected changes

Also included

  • Permission migration wired into the existing drag-and-drop reorder endpoint
  • New migratePermissionsForChannelMoves method on AuthRepository

Changes

File Change
src/server/meshtasticManager.ts Snapshot on connect, detect+migrate on configComplete
src/db/repositories/auth.ts migratePermissionsForChannelMoves() method
src/server/server.ts Permission migration in reorder endpoint

Test plan

  • npx vitest run - all tests pass
  • npm run build - no TypeScript errors
  • Swap channels via official app, restart MeshMonitor, verify messages and permissions follow

When channels are rearranged externally (e.g., via the official Meshtastic
app), MeshMonitor now detects the changes on config sync and automatically:

1. Migrates messages to follow channel content to new slots
2. Migrates user permissions to match new channel assignments
3. Logs new/unknown channels (default: no permissions for non-admins)
4. Audit logs all detected changes

Detection works by snapshotting channel PSKs before config sync starts,
then comparing after configComplete. Also wired permission migration into
the drag-and-drop reorder endpoint.

Closes #2425

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 25, 2026

Claude encountered an error —— View job


I'll analyze this and get back to you.

PSK-only matching could produce false positives when multiple channels
share the same key. Now both PSK and channel name must match to confirm
a channel has moved between slots.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 25, 2026

Claude finished @Yeraze's task —— View job


Code Review Complete ✅

Reviewing PR #2433 for code quality, potential issues, and best practices:

  • Read and analyze meshtasticManager.ts changes
  • Review auth.ts permission migration logic
  • Check server.ts integration changes
  • Assess code quality and best practices
  • Identify potential bugs or edge cases
  • Evaluate performance considerations
  • Check for security concerns
  • Review test coverage adequacy
  • Provide comprehensive feedback

🟢 Strengths

Code Quality & Design:

  • Robust channel identity matching: Using both PSK + name comparison (lines 10940-10943) prevents false positives from PSK collisions
  • Transaction safety: Message migration uses proper transaction handling with rollback on failure
  • Comprehensive error handling: All database operations wrapped in try/catch with detailed logging
  • Audit trail: Changes logged to audit_log for accountability
  • Consistent patterns: Permission migration follows the same swap/move pattern as message migration

Security & Safety:

  • Safe defaults: New channels have no permissions by default (restrictive)
  • Admin-only operation: Channel reordering requires channel_0 write permission
  • SQL injection prevention: Uses Drizzle ORM parameterized queries throughout

🟡 Areas for Improvement

Test Coverage - Critical Gap:

// ❌ Missing: No tests for the new migration methods
await databaseService.auth.migratePermissionsForChannelMoves(moves);
await databaseService.messages.migrateMessagesForChannelMoves(moves);

Recommendation: Add unit tests for auth.ts:720-753 and integration tests for the startup migration flow in meshtasticManager.ts:10930-10995

Error Handling:

  • auth.ts:742-752 - Permission migration failures don't roll back, unlike message migration
  • meshtasticManager.ts:10949-10959 - Migration errors are logged but don't prevent startup completion

Code Organization:

  • 121-line addition to already large meshtasticManager.ts - consider extracting to a separate ChannelMigrationService

🟠 Potential Edge Cases

  1. Race condition risk: meshtasticManager.ts:10932 - What if channels change between snapshot and configComplete?

  2. Empty name handling: meshtasticManager.ts:10942-10943

    (ch.name || '') === (oldCh.name || '')  // Could match two unnamed channels incorrectly
  3. Permission resource naming: auth.ts:731-741 - Hard-coded 'channel_' prefix could break if channel resource naming changes

  4. Circular moves: The algorithm doesn't detect circular moves (A→B→C→A), only pairs

🔵 Performance Considerations

Database Operations:

  • auth.ts:731-741 - Three sequential UPDATE statements per swap (could be optimized with CASE statements)
  • meshtasticManager.ts:10933-10934 - Two full channel table scans on every startup
  • No indexes assumed on permissions.resource column

Memory Usage:

  • Channel snapshots stored in memory until migration complete - minimal impact for typical 8-channel setups

🔒 Security Assessment

No major security concerns identified

  • SQL queries use parameterized statements via Drizzle ORM
  • Resource name construction follows existing patterns
  • No user input directly used in SQL construction
  • Permission requirements properly enforced

📊 Recommendations

High Priority:

  1. Add comprehensive tests for migration methods - this is critical before merging
  2. Handle empty channel names more robustly to prevent false matches
  3. Add transaction wrapper around permission migration for consistency

Medium Priority:
4. Consider extracting migration logic to separate service class
5. Add performance monitoring for migration operations on large datasets
6. Consider optimizing permission updates with batch operations

Low Priority:
7. Document the channel identity matching algorithm in code comments
8. Add metrics for migration success/failure rates

Overall Assessment: 🟢 APPROVE with Test Requirements

This is a well-designed feature that addresses a real user need. The code quality is high with proper error handling and follows existing patterns. The main blocker is the lack of test coverage for critical migration logic. Once tests are added, this should be safe to merge.

Migration detection logic is sound, database operations are safe, and security practices are followed. The implementation correctly handles the complex cases of channel swaps and moves.


9 tests for migrateMessagesForChannelMoves:
- Empty moves, simple moves, swaps, mixed moves
- Zero affected rows, one-sided swaps, channel DB isolation

7 tests for migratePermissionsForChannelMoves:
- Empty moves, simple moves, swaps, mixed moves
- Multi-user swaps, non-channel permission isolation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 25, 2026

Claude finished @Yeraze's task —— View job


Code Review Complete ✅

Reviewing PR #2433 for code quality, potential issues, and best practices:

  • Read and analyze the main implementation files
  • Review the new test files for coverage improvements
  • Assess code quality and best practices
  • Identify potential bugs or edge cases
  • Evaluate performance considerations
  • Check for security concerns
  • Review test coverage adequacy
  • Provide comprehensive feedback

🟢 Major Improvement: Test Coverage

Excellent response to previous feedback - The missing test coverage has been thoroughly addressed:

  • auth.migration.test.ts - 189 lines covering permission migration with swap/move scenarios
  • messages.migration.test.ts - 214 lines covering message migration with transaction safety

Both test suites are comprehensive and test edge cases like empty moves, swaps with missing data, and complex multi-channel scenarios.

🟢 Strengths

Code Quality & Design:

  • Robust channel identity matching: Using both PSK + name comparison (meshtasticManager.ts:10940-10943) prevents false positives from PSK collisions
  • Transaction safety: Message migration uses proper transaction handling with rollback on failure (messages.ts:461-483)
  • Comprehensive error handling: All database operations wrapped in try/catch with detailed logging
  • Audit trail: Changes logged to audit_log for accountability (meshtasticManager.ts:11013-11019)
  • Consistent patterns: Permission migration follows the same swap/move pattern as message migration

Security & Safety:

  • Safe defaults: New channels have no permissions by default (restrictive approach)
  • Admin-only operation: Channel reordering requires channel_0 write permission
  • SQL injection prevention: Uses Drizzle ORM parameterized queries throughout
  • Resource name validation: Hardcoded 'channel_' prefix prevents injection

🟡 Areas for Improvement

Transaction Consistency Gap:

// ❌ Messages have transaction safety, permissions do not
await databaseService.messages.migrateMessagesForChannelMoves(moves); // Has BEGIN/COMMIT/ROLLBACK
await databaseService.auth.migratePermissionsForChannelMoves(moves);   // No transaction wrapper

Impact: Permission migration could partially fail, leaving inconsistent state

Error Handling:

  • meshtasticManager.ts:10978-10994 - Migration errors are logged but don't prevent startup completion
  • auth.ts:741-753 - Individual UPDATE statements not wrapped in transaction (unlike messages)

Empty String Edge Case:

  • meshtasticManager.ts:10942-10943 - (ch.name || '') === (oldCh.name || '') could incorrectly match two channels with null/undefined names

🔵 Performance Considerations

Database Operations:

  • auth.ts:741-743 - Three sequential UPDATE statements per swap (could be optimized with single CASE statement)
  • meshtasticManager.ts:10932-10933 - Two full channel table scans on every startup (minimal impact for 8 channels)
  • Startup migration only runs once per channel change event

Memory Usage:

  • Channel snapshots stored until migration complete - negligible for typical deployments

🟠 Potential Edge Cases

  1. Circular moves not detected: Algorithm handles pairs (A↔B) but not cycles (A→B→C→A)

  2. Race condition window: meshtasticManager.ts:10932 - Channels could theoretically change between snapshot and configComplete

  3. Duplicate prevention logic: meshtasticManager.ts:10945-10946 - The reverse-check logic looks correct but is complex

  4. Channel naming constraints: Empty/null names are handled but could create false positive matches

🔒 Security Assessment

No security concerns identified

  • All SQL uses parameterized queries via Drizzle ORM
  • Resource naming follows established patterns
  • No user input directly incorporated into SQL
  • Permission requirements properly enforced
  • Audit logging captures all changes

📊 Test Coverage Assessment

Excellent test coverage (major improvement from previous review)

  • Permission migration: Covers moves, swaps, edge cases, multiple users
  • Message migration: Covers transaction rollback, complex scenarios, boundary conditions
  • Edge cases tested: Empty moves, one-sided swaps, channel boundaries
  • Both SQLite and database-agnostic patterns tested

Final Recommendations

High Priority:

  1. Add transaction wrapper around permission migration to match message migration safety
  2. Handle empty/null channel names more robustly to prevent false matches

Medium Priority:
3. Consider batching permission UPDATEs for better performance
4. Add integration test for the full startup migration flow

Low Priority:
5. Document the PSK+name matching algorithm in code comments
6. Add metrics for migration success/failure rates

Overall Assessment: 🟢 APPROVE

This is a significant improvement over the previous version. The comprehensive test coverage addresses the main blocker identified in the earlier review. The code quality is high, follows established patterns, and implements the requested feature correctly.

Key improvements:

  • Critical gap filled: Comprehensive test coverage added
  • Transaction safety: Message migration is properly protected
  • Edge cases handled: Tests cover complex scenarios
  • Security practices followed: No injection vulnerabilities

The remaining recommendations are enhancements rather than blockers. The permission transaction consistency issue is the only moderate concern, but doesn't prevent merging since permission operations are typically small and atomic.

This PR successfully implements channel migration with proper safety mechanisms and is ready for merge.


@Yeraze Yeraze merged commit 858cd76 into main Mar 25, 2026
17 checks passed
@Yeraze Yeraze deleted the feat/startup-channel-migration branch March 25, 2026 19:32
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.

[FEAT] Channel Migration on container start

1 participant