[TECH-008] Universal Search Refactoring & Hardening Specification
Overview
This technical specification details the architectural hardening, safety protocols, DRY refactoring, and multi-type attachment search enhancements for the grm Universal Cross-Domain Search Engine (src/cmd_search.cpp).
These refactorings address edge cases identified during architectural review and prepare the module for implementation on the dedicated feature/refactor branch refactor/search-engine-hardening.
Architectural Weaknesses Identified
JSON Syntax Breakage via Unescaped Query Strings Direct string formatting using
std::format(R"({{"query": "{}"}})", query)fails whenquerycontains double quotes ("), backslashes (\), or control characters.Duplicated Candidate Resolution Loops (DRY Violation) The handlers
cmd_search_chats,cmd_search_supergroups, and universalcmd_searchduplicate identical logic for:Querying
searchChatsandsearchPublicChats.Calling
ensure_chat_loaded.Sending
getChatand parsing chat metadata intofmt::ChatItem.
Single-Type Media Scope in File Search Searching file attachments currently hardcodes
searchMessagesFilterDocument, omitting photo, video, audio, and general media attachments.
Technical Refactoring Requirements
1. Mandatory JSON String Escaping (Injection Protection)
All JSON payloads constructed for TDLib search requests MUST wrap query strings using escape_json_string() defined in include/grm/json_utils.hpp.
const std::string escaped_query = escape_json_string(query);
const std::string req = std::format(
R"({{"query": "{}", "limit": {}}})",
escaped_query, limit);
Target RPC Requests:
searchChatssearchPublicChatssearchContactssearchMessagessearchChatMessages
2. DRY Chat Item Resolver Helper Function
Consolidate chat metadata fetching and type classification into a single private helper method in include/grm/app.hpp and src/cmd_search.cpp:
struct ResolvedChatItems {
std::vector<fmt::ChatItem> chats;
std::vector<fmt::ChatItem> supergroups;
};
ResolvedChatItems resolve_chat_candidates(
const std::vector<int64_t> &chat_ids,
int limit);
Responsibilities:
Loop through candidate
chat_ids.Execute
ensure_chat_loaded(id)for each candidate.Fetch
getChatand classify intoBasic Group,Supergroup,Forum Supergroup,Channel, orPrivate Chat.Partition into
chatsandsupergroupsvectors.
Multi-Type File Attachment Search (
--typeOption)
Enhance grm search files <query> [options] to accept a --type <doc|photo|video|audio|all> option flag.
Supported Filters:
doc(default):searchMessagesFilterDocumentphoto:searchMessagesFilterPhotovideo:searchMessagesFilterVideoaudio:searchMessagesFilterAudioall: Aggregates matches across document, photo, video, and audio filters.
Command Specification Update in App::get_search_spec():
{"files", "<query> [options]", "Search file and media attachments",
{{"-t", "--type", "<doc|photo|video|audio|all>", "Filter attachment type (default: doc)", {"doc", "photo", "video", "audio", "all"}},
{"-n", "--limit", "<count>", "Maximum search results (default: 20)", {}},
{"-v", "--verbose", "", "Show verbose metadata", {}}}}
Execution & Verification Protocol
Branch Strategy
Checkout refactor branch:
git checkout -b refactor/search-engine-hardeningImplement
escape_json_stringwrapping across all RPC invocations insrc/cmd_search.cpp.Refactor candidate chat resolution using
resolve_chat_candidates().Implement
grm search files --typeflag handling.Update CTest suite in
tests/test_search.cpp.Run
make check(verify 100% CTest pass across all 16 test binaries).Run
make doc-check(verify zero rstcheck errors).Execute live account verification against Telegram account.
Commit using Conventional Commits trailers and push to remotes.
Unresolved Architectural Items & Future Optimization Roadmap
Note
Status: In Progress / Unresolved
While initial multi-domain search and offset pagination have been integrated, the search subsystem contains active architectural limitations currently undergoing design review:
Sequential Network Latency (6s-10s Time-To-First-Result): Candidate gathering currently executes TDLib RPC calls in serial for loops on a single thread. Future refactoring MUST transition to Asynchronous Parallel RPC Gathering using thread worker pools to collapse network latency to under 1.0s.
Progressive Output Streaming: CLI table output currently waits for the full batch (e.g. -n 100) to resolve in memory before printing. Future versions MUST stream matching result rows to stdout progressively as responses arrive, achieving time-to-first-result under 200ms.
Global Public Directory Supergroup Indexing: Telegram’s backend caps public directory queries (searchPublicChats) per keyword. Expanded handle extraction and linked discussion group resolution must be further extended to reach 100+ public discussion supergroups per query.