#pragma once #include class NetworkService; // Мета-поля задачи. Пустые/нулевые значения не попадают в text дампа // и в имя папки — выводятся только те, что релевантны конкретному типу задачи. struct TaskDumpMeta { QString materialId; double amount = 0; // 0 = нет QString phone; // пусто = нет (телефон получателя в транзакции) QString card; // пусто = нет QString bankProfileId; // серверный UUID банковского профиля (детект в общих логах) QString profilePhone; // телефон банковского профиля (не получателя) QString androidId; // стабильный android_id устройства (в отличие от adbSerial не меняется) }; class TaskDumpRecorder { public: // NetworkService, через который дамп отправляется на бэкенд (/monitoring/dump). // Вызывать один раз при старте приложения. Без него рекордер собирает дамп, // но не отправляет его — только пишет warning в лог. static void setNetworkService(NetworkService *service); // Доступ к зарегистрированному NetworkService для других потребителей, // которые тоже хотят дернуть /monitoring/dump (отправка ручных логов). static NetworkService* networkService(); // Возвращает рекордер текущего потока (nullptr если задача не начата). static TaskDumpRecorder* current(); // RAII-скоуп: при создании регистрирует рекордер на текущий поток, // при разрушении — финализирует (успех/ошибка определяются по errorPtr). // Если в текущем потоке уже есть активный рекордер (вложенный вызов из // другого скрипта), новый скоуп становится no-op — родитель остаётся // владельцем дампа, а внутренние скрины пишутся в его папку. class Scope { public: Scope(const QString &bank, const QString &taskKind, const QString &adbDeviceId, const TaskDumpMeta &meta, const QString *errorPtr); ~Scope(); Scope(const Scope &) = delete; Scope &operator=(const Scope &) = delete; private: const QString *m_errorPtr; bool m_owned; }; // Сохраняет XML-дамп в папку задачи. Имя файла: NNNN_.xml. void saveXml(int counter, const QString &xml); private: TaskDumpRecorder(const QString &bank, const QString &taskKind, const QString &adbDeviceId, const TaskDumpMeta &meta); static void begin(const QString &bank, const QString &taskKind, const QString &adbDeviceId, const TaskDumpMeta &meta); static void finish(const QString &errorMessage); void finishInternal(const QString &errorMessage); QString buildCaption(const QString &errorMessage) const; QString m_folder; QString m_bank; QString m_taskKind; QString m_adbDeviceIdRaw; QString m_adbDeviceIdSafe; TaskDumpMeta m_meta; bool m_finished = false; };