Files
SandersandClaude Opus 4.8 eed9164150 Add CompanionDevice watch pairing and store raw AI responses
Two fixes for the notification-parsing pipeline:

- CompanionDeviceManager pairing (DEVICE_PROFILE_WATCH -> COMPANION_DEVICE_WATCH
  role -> RECEIVE_SENSITIVE_NOTIFICATIONS) via a new platform channel in
  MainActivity.kt, companion_device_channel.dart and companion_access_controller,
  surfaced as a card in parsing settings. Lifts the system "Confidential"
  redaction that hid VTB/T-Bank notification text from the listener.

- raw_messages.ai_response: the model's raw completion content is now persisted
  (schema v4 + migration) and shown in the parsing log detail panel. Unlike
  draftJson it survives inbox sweeps and is filled even for partial/ignored
  outcomes.

flutter analyze: no issues.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 22:04:39 +03:00

473 lines
25 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"@@locale": "ru",
"appTitle": "Kitty finances",
"navHome": "Главная",
"navInbox": "Входящие",
"navAnalytics": "Аналитика",
"navAccounts": "Счета",
"navProfile": "Профиль",
"allAccounts": "Все",
"comingSoon": "Скоро",
"budget": "БЮДЖЕТ",
"balance": "БАЛАНС",
"income": "ДОХОДЫ",
"expenses": "РАСХОДЫ",
"transactions": "Транзакции",
"transactionCount": "{count, plural, one{{count} операция} few{{count} операции} many{{count} операций} other{{count} операций}}",
"@transactionCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"allCategoriesFilter": "Все категории · все типы",
"filterByCategories": "Фильтр по категориям",
"clearFilter": "Сбросить",
"selectAll": "Выбрать все",
"categoriesSelectedCount": "{count, plural, one{{count} категория} few{{count} категории} many{{count} категорий} other{{count} категорий}}",
"@categoriesSelectedCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"moreCategories": "{count, plural, one{+ ещё {count} категория →} few{+ ещё {count} категории →} many{+ ещё {count} категорий →} other{+ ещё {count} категорий →}}",
"@moreCategories": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"todayWithDate": "Сегодня · {date}",
"@todayWithDate": {
"placeholders": {
"date": {
"type": "String"
}
}
},
"yesterdayWithDate": "Вчера · {date}",
"@yesterdayWithDate": {
"placeholders": {
"date": {
"type": "String"
}
}
},
"analyticsTitle": "Отчёты",
"analyticsSubtitle": "Аналитика",
"analyticsNoData": "Нет данных за этот месяц",
"accountsSubtitle": "Управление",
"profileSubtitle": "Настройки",
"darkTheme": "Тёмная тема",
"profileLanguageTile": "Язык",
"langEnglish": "English",
"langRussian": "Русский",
"profileHint": "Здесь появится профиль пользователя, валюта, локаль и другие настройки.",
"onboardingTitle": "Добро пожаловать",
"onboardingSubtitle": "Расскажите, как к вам обращаться.",
"onboardingNameLabel": "Ваше имя",
"onboardingNameHint": "Например, Алекс",
"onboardingContinue": "Продолжить",
"onboardingAccountTitle": "Ваш первый счёт",
"onboardingAccountSubtitle": "Добавьте счёт, чтобы учитывать деньги. Другие счета можно добавить позже.",
"txNewTitle": "Новая операция",
"txEditTitle": "Редактировать операцию",
"txTypeExpense": "Расход",
"txTypeIncome": "Доход",
"txTypeTransfer": "Перевод",
"txAmountHint": "0",
"txCategoryLabel": "Категория",
"txAccountLabel": "Счёт списания",
"txAccountFromLabel": "Откуда",
"txAccountToLabel": "Куда",
"txDateTimeLabel": "Дата и время",
"txBalanceAfter": "Остаток после",
"txTransferAfter": "После перевода",
"txNoteLabel": "Мерчант",
"txNoteHint": "Например, Пятерочка…",
"txExtraInfoLabel": "Доп. информация",
"txExtraInfoHint": "Например, продукты на неделю…",
"txSaveButton": "Добавить транзакцию",
"txSaveEditButton": "Сохранить",
"txTransferButton": "Перевести {amount}",
"@txTransferButton": {
"placeholders": {
"amount": { "type": "String" }
}
},
"txDeleteButton": "Удалить",
"txDeleteConfirmTitle": "Удалить транзакцию?",
"txDeleteConfirmMessage": "Действие нельзя отменить.",
"txDeleteConfirmYes": "Удалить",
"txDeleteConfirmNo": "Отмена",
"txPickCategory": "Выберите категорию",
"txPickAccount": "Выберите счёт",
"pickerAccountTitle": "Счёт",
"pickerAccountSubtitle": "{count, plural, one{{count} счёт} few{{count} счёта} many{{count} счетов} other{{count} счетов}}",
"@pickerAccountSubtitle": {
"placeholders": {
"count": { "type": "int" }
}
},
"pickerCategoryTitle": "Категория",
"pickerCategorySubtitle": "{count, plural, one{{count} категория} few{{count} категории} many{{count} категорий} other{{count} категорий}}",
"@pickerCategorySubtitle": {
"placeholders": {
"count": { "type": "int" }
}
},
"pickerAddAccount": "Добавить счёт",
"pickerCreateCategory": "Создать категорию",
"comingSoonShort": "Скоро",
"txValidationAmountRequired": "Введите сумму",
"txValidationAccountRequired": "Выберите счёт",
"txValidationCategoryRequired": "Выберите категорию",
"txValidationTransferSameAccount": "Счёт-источник и счёт-получатель должны отличаться",
"txValidationTransferDestRequired": "Выберите счёт получателя",
"categoriesScreenTitle": "Категории",
"categoriesEmpty": "Пока нет категорий. Нажмите +, чтобы создать первую.",
"categoryNewTitle": "Новая категория",
"categoryEditTitle": "Редактировать категорию",
"categoryNameLabel": "Название",
"categoryNameHint": "Например, Продукты",
"categoryIconLabel": "Иконка",
"categoryColorLabel": "Цвет",
"categorySaveButton": "Создать категорию",
"categoryArchiveButton": "В архив",
"categoryArchiveConfirmTitle": "Архивировать категорию?",
"categoryArchiveConfirmMessage": "Архивные категории исчезают из пикеров и списков. Существующие транзакции сохранят ссылку на неё.",
"categoryValidationNameRequired": "Введите название",
"categoryValidationNameTooLong": "Слишком длинное название (не больше 50 символов)",
"iconPickerTitle": "Выберите иконку",
"colorPickerTitle": "Выберите цвет",
"currencyPickerTitle": "Выберите валюту",
"currencyPickerSearchHint": "Поиск…",
"colorPickerAllUsed": "Все цвета палитры уже заняты другими категориями.",
"iconGroupFood": "Еда",
"iconGroupTransport": "Транспорт",
"iconGroupShopping": "Покупки",
"iconGroupHome": "Дом",
"iconGroupHealth": "Здоровье",
"iconGroupEntertainment": "Досуг",
"iconGroupWork": "Работа",
"iconGroupTravel": "Путешествия",
"iconGroupFinance": "Финансы",
"iconGroupOther": "Прочее",
"profileCategoriesTile": "Категории",
"profileAccountsTile": "Счета",
"accountsEmpty": "Счетов нет. Нажмите +, чтобы добавить.",
"accountNewTitle": "Новый счёт",
"accountEditTitle": "Редактировать счёт",
"accountNameLabel": "Название",
"accountNameHint": "напр. Кошелёк",
"accountTypeLabel": "Тип",
"accountTypeCash": "Наличные",
"accountTypeCard": "Карта",
"accountTypeBank": "Банк",
"accountTypeSavings": "Накопления",
"accountCurrencyLabel": "Валюта",
"accountInitialBalanceLabel": "Начальный баланс",
"accountIconLabel": "Иконка",
"accountColorLabel": "Цвет",
"accountIsDefaultLabel": "Счёт по умолчанию",
"accountIsDefaultHint": "Подставляется при создании транзакций",
"accountSaveButton": "Создать счёт",
"accountSaveEditButton": "Сохранить",
"accountArchiveButton": "Архивировать",
"accountArchiveConfirmTitle": "Архивировать счёт?",
"accountArchiveConfirmMessage": "Архивные счета исчезают из списков и пикеров. Существующие транзакции сохранят ссылку.",
"accountValidationNameRequired": "Введите название",
"accountValidationNameTooLong": "Слишком длинное название (макс. 50 символов)",
"accountSaveError": "Не удалось сохранить счёт. Попробуйте ещё раз.",
"accountArchiveError": "Не удалось архивировать счёт. Попробуйте ещё раз.",
"accountSetDefaultError": "Счёт сохранён, но не удалось сделать его умолчательным.",
"profileParsingTile": "Парсинг уведомлений",
"parsingSettingsTitle": "Парсинг уведомлений",
"parsingSettingsSubtitle": "Настройки",
"parsingEnableLabel": "Распознавать уведомления",
"parsingAutoApplyLabel": "Авто-добавление транзакций",
"parsingAutoApplyHint": "Добавлять без подтверждения, когда есть правило, сумма найдена в тексте сообщения и счёт определён надёжно.",
"parsingTransferPairingLabel": "Склеивать переводы между счетами",
"parsingTransferPairingHint": "Два уведомления об одном переводе (списание + зачисление) объединяются в одну транзакцию-перевод на подтверждение.",
"parsingDiagnosticModeLabel": "Режим диагностики",
"parsingDiagnosticModeHint": "Ловить каждое уведомление от мониторимых приложений (включая пустые/повторные) с полным дампом всех полей. Временно — для отладки, добавляет шум в журнал парсинга.",
"inboxWhyNotAuto": "Почему не автоматически: {reasons}",
"@inboxWhyNotAuto": { "placeholders": { "reasons": { "type": "String" } } },
"gateCheckRuleMatched": "нет правила для мерчанта",
"gateCheckAmountVerifiedInBody": "сумма не найдена в тексте сообщения",
"gateCheckCurrencyKnown": "валюта не распознана",
"gateCheckTypeMatchesRule": "тип операции отличается от правила",
"gateCheckAccountResolved": "счёт не определён",
"gateCheckAccountTrusted": "счёт не подтверждён для приложения",
"gateCheckAmountUnderCap": "слишком крупная сумма",
"gateCheckRuleAutoApplyEnabled": "авто-применение выключено у правила",
"parsingRulesTile": "Правила парсинга",
"parsingRulesCreatedCount": "Правил создано: {count}",
"@parsingRulesCreatedCount": { "placeholders": { "count": { "type": "int" } } },
"parsingAiSectionTitle": "AI (DeepSeek)",
"parsingAiComingSoon": "ИИ-распознавание появится в следующей версии.",
"parsingNotifAccessTitle": "Доступ к уведомлениям",
"parsingNotifAccessGranted": "Выдан — уведомления читаются",
"parsingNotifAccessDenied": "Не выдан — нажмите, чтобы открыть настройки",
"parsingNotifAccessOpenSettings": "Открыть настройки",
"parsingCompanionTitle": "Полный доступ к уведомлениям",
"parsingCompanionBound": "Часы привязаны — текст уведомлений приходит целиком",
"parsingCompanionNotBound": "Android скрывает текст банковских уведомлений. Привяжите часы, чтобы приложение стало доверенным.",
"parsingCompanionBind": "Привязать часы",
"parsingCompanionBindFailed": "Не удалось привязать: {error}",
"@parsingCompanionBindFailed": { "placeholders": { "error": { "type": "String" } } },
"parsingCompanionPickerTitle": "Выберите ваши часы",
"parsingCompanionPickerScan": "Другое устройство — системный поиск",
"parsingCompanionBtDenied": "Нет разрешения Bluetooth — выдайте его в настройках приложения",
"parsingDebugSectionTitle": "Отладка",
"parsingDebugInjectTile": "Вставить тестовое уведомление",
"parsingLogTile": "Журнал парсинга",
"parsingLogTitle": "Журнал парсинга",
"parsingLogEmpty": "Сообщений пока нет. Входящие уведомления появятся здесь.",
"parsingLogError": "Не удалось загрузить журнал.",
"parsingLogFilterAll": "Все",
"parsingLogFilterInbox": "Inbox",
"parsingLogFilterApplied": "Применённые",
"parsingLogFilterIgnored": "Игнорированные",
"parsingLogFilterFailed": "Ошибки",
"parsingStatusPending": "В очереди",
"parsingStatusInbox": "Inbox",
"parsingStatusApplied": "Применено",
"parsingStatusIgnored": "Игнорировано",
"parsingStatusFailed": "Ошибка",
"parsingStatusPendingAi": "Ждёт AI",
"parsingStatusParsedPartial": "Частично",
"parsingStatusWaitingPair": "Ждёт пару",
"parsingStatusPaired": "Объединено в перевод",
"parsingUnmergeTransfer": "Расклеить перевод",
"parsingLogOnline": "Онлайн",
"parsingLogOffline": "Офлайн",
"parsingLogFilterWaiting": "Ждёт сети",
"parsingDetailConfidence": "Уверенность",
"parsingDetailPipeline": "Pipeline",
"parsingDetailMessage": "Сообщение",
"parsingDetailDraft": "Черновик",
"parsingDetailRule": "Предложение правила",
"parsingDetailMeta": "Мета",
"parsingDetailDiagnostics": "Диагностика",
"parsingDetailAiResponse": "Ответ ИИ",
"parsingDetailAttempt": "Попытка {count}/{max}",
"@parsingDetailAttempt": { "placeholders": { "count": { "type": "int" }, "max": { "type": "int" } } },
"parsingDetailSource": "Источник",
"parsingDetailFailedChecks": "Почему не автоматически",
"parsingDetailAmountScore": "Сумма",
"parsingDetailAccountScore": "Счёт",
"parsingDetailTypeScore": "Тип",
"parsingDetailMerchantScore": "Мерчант",
"parsingDetailCategoryScore": "Категория",
"parsingDetailTitle": "Заголовок",
"parsingDetailBody": "Текст",
"parsingDetailCard": "Карта",
"parsingDetailCurrency": "Валюта",
"parsingDetailKind": "Вид",
"parsingDetailDate": "Дата",
"parsingDetailMerchantRaw": "Мерчант (сырой)",
"parsingDetailMerchantCanonical": "Мерчант (норм.)",
"parsingDetailCounterparty": "Контрагент",
"parsingDetailCategorySuggestion": "Подсказка категории",
"parsingDetailAccountId": "ID счёта",
"parsingDetailCategoryId": "ID категории",
"parsingDetailTransferTo": "Перевод на",
"parsingDetailRuleCategory": "Категория",
"parsingDetailTransactionId": "ID транзакции",
"parsingDetailDedupHash": "Dedup-хеш",
"parsingDetailReceivedAt": "Получено",
"parsingDetailCreatedAt": "Создано",
"inboxTitle": "Из уведомлений",
"inboxSubtitle": "Правило обучится с первого раза: следующие похожие сообщения подтвердятся автоматически.",
"inboxEmpty": "Inbox пуст. Новые уведомления появятся здесь.",
"inboxCreateRule": "Создать правило «{merchant} → {category}»",
"@inboxCreateRule": { "placeholders": { "merchant": { "type": "String" }, "category": { "type": "String" } } },
"inboxCreateRuleNoCategory": "Создать правило для «{merchant}»",
"@inboxCreateRuleNoCategory": { "placeholders": { "merchant": { "type": "String" } } },
"inboxConfirm": "Подтвердить",
"inboxCategoryRequiredHint": "Выберите категорию, чтобы подтвердить",
"inboxIgnore": "Игнорировать",
"inboxApplyAll": "Учесть все",
"inboxTransferPairTitle": "Перевод между счетами",
"inboxTransferFrom": "Счёт списания",
"inboxTransferTo": "Счёт зачисления",
"inboxTransferPickAccount": "Выбрать…",
"inboxUnpair": "Расклеить",
"inboxUnrecognized": "Не распознано",
"inboxParseErrorTitle": "Ошибка распознавания",
"inboxRetry": "Попробовать снова",
"inboxAddManually": "Добавить вручную",
"inboxNoCategory": "Без категории",
"inboxAccountUnknown": "Счёт не определён",
"inboxEditRuleTooltip": "Изменить перед сохранением",
"inboxWaitingNetworkTitle": "Ждёт сети",
"inboxStuckOffline": "Нет подключения к интернету. Разбор продолжится, когда появится сеть.",
"inboxStuckNetwork": "Сеть есть, но запрос к AI не прошёл. Повторим автоматически.",
"parseErrorOffline": "Не было соединения с интернетом",
"parseErrorNetwork": "Запрос к AI не прошёл (ошибка сети)",
"parseErrorRetryLimit": "Лимит AI-попыток исчерпан",
"rulesTitle": "Правила парсинга",
"rulesSubtitle": "Настройки",
"rulesFilterAll": "Все",
"rulesFilterMerchants": "Мерчанты",
"rulesFilterAccounts": "Счета",
"rulesFilterIgnore": "Игнор",
"rulesEmpty": "Правил пока нет. Создавайте их из Inbox в один тап.",
"ruleMatchesCount": "{count, plural, one{{count} совпадение} few{{count} совпадения} many{{count} совпадений} other{{count} совпадений}}",
"@ruleMatchesCount": { "placeholders": { "count": { "type": "int" } } },
"ruleDisabled": "Выключено",
"ruleEditorNewTitle": "Новое правило",
"ruleEditorEditTitle": "Правило",
"ruleEditorIfContains": "Если уведомление содержит",
"ruleEditorPatternHint": "напр. WBSPB",
"ruleEditorModeContains": "Содержит",
"ruleEditorModeExact": "Точно",
"ruleEditorModeRegex": "Regex",
"ruleEditorThen": "То это:",
"ruleEditorMerchant": "Мерчант",
"ruleEditorMerchantHint": "Напр. Wildberries",
"ruleEditorCategory": "Категория",
"ruleEditorAccount": "Счёт",
"ruleEditorAccountUnchanged": "— не менять —",
"ruleEditorApp": "Приложение",
"ruleEditorAppPick": "Выберите приложение",
"ruleEditorNoApps": "Сначала добавьте приложение-источник",
"rulesUnknownApp": "Неизвестное приложение",
"ruleEditorAdvanced": "Дополнительно",
"ruleEditorPriority": "Приоритет",
"ruleEditorMatchesTitle": "Совпадает с (последние 30 дней)",
"ruleEditorNoMatches": "Нет совпадений за 30 дней",
"ruleEditorSave": "Сохранить",
"ruleEditorDelete": "Удалить",
"ruleEditorEnabledLabel": "Активно",
"debugInjectTitle": "Тестовое уведомление",
"debugInjectSubtitle": "Отладка",
"debugInjectPackageLabel": "Пакет приложения",
"debugInjectTitleLabel": "Заголовок (необязательно)",
"debugInjectBodyLabel": "Текст уведомления",
"debugInjectSend": "Отправить в обработку",
"debugInjectSent": "Отправлено",
"debugInjectFillSample": "Пример: покупка",
"aiConsentKeyMissing": "API-ключ не указан",
"aiConsentSaved": "Настройки сохранены",
"aiConsentTitle": "Парсинг с ИИ",
"aiConsentBody": "Мы используем DeepSeek API для парсинга уведомлений с помощью ИИ. Ваши данные отправляются выбранной модели. Вам понадобится свой API-ключ. Расходуются токены.",
"aiConsentKeyLabel": "API-ключ DeepSeek",
"aiConsentKeyHint": "sk-...",
"aiConsentModelLabel": "Модель ИИ",
"aiConsentAllow": "Разрешить ИИ-парсинг",
"aiConsentRegexOnly": "Только Regex (Локально)",
"parsingAiConfigure": "Настроить ИИ",
"parsingAiTokensToday": "Токенов за сегодня: {tokens}",
"@parsingAiTokensToday": {
"placeholders": {
"tokens": {
"type": "int"
}
}
},
"parsingAiTokensTodayLimited": "Токенов за сегодня: {tokens} / {limit}",
"@parsingAiTokensTodayLimited": {
"placeholders": {
"tokens": {
"type": "int"
},
"limit": {
"type": "int"
}
}
},
"habitTrackingTile": "Анализ привычек трат",
"habitObligationRequired": "Обязательно",
"habitObligationOptional": "Не обязательно",
"habitObligationUnnecessary": "Не нужно",
"habitObligationOptionalShort": "Можно без",
"habitImpulseImpulsive": "Импульсивно",
"habitImpulseConsidered": "Обдуманно",
"habitNotMarked": "не отмечено",
"habitFilterAll": "Все",
"habitScaleImpulseCaps": "ИМПУЛЬСИВНОСТЬ",
"habitScaleObligationCaps": "ОБЯЗАТЕЛЬНОСТЬ",
"habitAnalysisTitle": "Транзакции",
"habitAnalysisTile": "Анализ привычек",
"profileSeedDemoTile": "Заполнить демо транзакциями",
"profileSeedDemoSuccess": "Демо транзакции добавлены",
"commonAdd": "Добавить",
"commonCancel": "Отмена",
"commonDelete": "Удалить",
"parsingAppsTile": "Приложения-источники",
"sourceAppsTitle": "Приложения-источники",
"sourceAppsAddedSection": "Отслеживаются",
"sourceAppsAvailableSection": "Доступные",
"sourceAppsEmpty": "Пока нет приложений. Выберите банк ниже или добавьте вручную.",
"sourceAppsAddManual": "Добавить вручную",
"sourceAppsPackageLabel": "Имя пакета",
"sourceAppsNameLabel": "Отображаемое имя (необязательно)",
"sourceAppsPickFromInstalled": "Выбрать из установленных",
"sourceAppsPickerTitle": "Установленные приложения",
"sourceAppsSearchHint": "Поиск",
"sourceAppsPickerEmpty": "Приложения не найдены",
"sourceAppsAlreadyAdded": "Уже добавлено",
"sourceAppsSelfMerchantLabel": "Мерчант — само приложение",
"sourceAppsSelfMerchantHint": "Уведомления не называют продавца: категория выбирается вручную, правила не предлагаются",
"appDetailEnabled": "Отслеживать уведомления",
"appDetailDefaultAccount": "Счёт по умолчанию",
"appDetailDefaultAccountNone": "Не задан",
"appDetailDefaultAccountHint": "Новые операции из этого приложения записываются на этот счёт. Запоминается автоматически при первом «Подтвердить» во Входящих.",
"appDetailRoutingRules": "Правила выбора счёта",
"appDetailRoutingRulesEmpty": "Если приложение пишет о нескольких счетах (карта, вклад), добавьте правило: паттерн в тексте → счёт. Правила важнее счёта по умолчанию.",
"appDetailAddRule": "Добавить",
"inboxAppDefaultSet": "Счёт сохранён как основной для приложения",
"ruleEditorAccountPick": "Выбрать счёт",
"ruleEditorAccountAuto": "Авто — счёт приложения",
"ruleEditorIgnoreLabel": "Игнорировать сообщение",
"ruleEditorIgnoreHint": "Совпавшие уведомления пропускаются без транзакции",
"ruleEditorAutoApplyLabel": "Применять автоматически",
"ruleEditorAutoApplyHint": "Выкл: совпадения приходят в Инбокс с префиллом на ручной разбор",
"ruleEditorTxType": "Тип операции",
"ruleEditorTxTypeAny": "Любой",
"ruleManualBadge": "вручную"
}