feat: pubkey alias system for display name resolution#3
Open
feat: pubkey alias system for display name resolution#3
Conversation
Adds a new `pubkey_aliases` table so admins can assign human-readable display names to client public keys that never appear in the adverts table (e.g. MeshCore phone-app users whose device does not broadcast LoRa adverts). - sqlite_handler.py: `pubkey_aliases` table created on DB init plus migration 12 for existing databases; CRUD helpers set/get/delete/list - storage_collector.py: `get_node_name_by_pubkey()` now checks aliases first (highest priority), then falls back to the adverts table as before; new wrapper methods set/delete/list aliases forwarded to the DB handler - api_endpoints.py: new GET /api/pubkey_aliases and POST|DELETE /api/pubkey_alias endpoints; GET /api/resolve_pubkey_names batch lookup for the UI poll cycle; `acl_clients` response now includes `node_name` resolved via the same lookup chain Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The batch name-resolution endpoint was wired up in api_endpoints.py but
the resolve_pubkey_names method and its _get_companion_name_by_pubkey
helper were not yet present. Add both.
resolve_pubkey_names(pubkeys=<comma-separated hex>) returns a JSON map
of {pubkey: name|null} using the same priority chain as the rest of the
alias system: admin alias → adverts table → companion derivation.
44 tests across three files:
- test_sqlite_pubkey_aliases: CRUD against real in-memory SQLite
- test_storage_collector_name_resolution: alias-first priority chain
- test_resolve_pubkey_names_endpoint: batch resolution, companion
fallback, whitespace handling, empty input, and error path
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Migration 11 used MAX(id) to pick the canonical row per (room_hash,
client_pubkey) when rebuilding room_client_sync with the UNIQUE
constraint. This was wrong: eviction writes a new row with
last_activity=0, and when that row has the highest id the migration
silently preserved the evicted state, discarding real activity data.
Fix migration 11's INSERT SELECT to JOIN against a subquery that
computes both MAX(id) (for operational columns) and MAX(last_activity)
(so the best-ever activity timestamp survives, regardless of which row
had the highest id).
Add migration 13 ("fix_room_client_sync_last_activity") to repair
devices that already ran the flawed migration 11. For every client
where last_activity=0 but sync_since>0 (actively synced before the
bad migration), last_activity is restored to sync_since as the best
available estimate of when the client was last seen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pubkey_aliasestable so admins can assign human-readable display names to client public keys that never appear in the adverts table (e.g. MeshCore phone-app users whose device does not broadcast LoRa adverts)sqlite_handler.py:pubkey_aliasestable + migration 12; CRUD helpers set/get/delete/liststorage_collector.py:get_node_name_by_pubkey()checks aliases first (highest priority), falls back to adverts tableapi_endpoints.py:GET /api/pubkey_aliases,POST|DELETE /api/pubkey_alias,GET /api/resolve_pubkey_namesbatch lookup;acl_clientsresponse includesnode_nameTest plan
pytest tests/test_sqlite_pubkey_aliases.py: 17 testspytest tests/test_storage_collector_name_resolution.py: 16 testspytest tests/test_resolve_pubkey_names_endpoint.py: 11 testsPOST /api/pubkey_alias, verify name appears in UI