Notification parsing:
- Drop the account_bindings table/DAO/repo/entity/controller/screen; account
resolution now goes senderToAccount rule -> source_apps.defaultAccountId
(trusted) -> global default (untrusted -> Inbox), via v1->v2 migration.
- Add defaultAccountId to source_apps; per-app settings consolidated into
source_app_detail_screen (/settings/parsing/apps/:pkg).
- Inbox auto-learns an app default on first Confirm/CreateRule; account picker
on the card instead of a disabled button; parse_error_labels extracted.
Analytics:
- Replace placeholder screen with fl_chart cards (chart_card, chart_theme,
month_stepper, month_math domain helper); slim down habit_analysis_screen.
Android: add launcher icon (adaptive foreground + colors.xml) and app_name.
Tests: migration_v2, analytics (screen/month_math), AI retry, inbox
visibility; update resolver/gate/inbox suites for the new resolution path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Set up flutter_launcher_icons to generate Android launcher icons from assets/icon/app_icon.png. Move the app label into a string resource (@string/app_name) with a debug-only "Kitty finances debug" override.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the OpenRouter HTTP client with a DeepSeek client:
- data/openrouter/ -> data/deepseek/; OpenRouterClient -> DeepSeekClient
(+ DeepSeekCompletion / DeepSeek*Exception)
- base URL api.deepseek.com, drop OpenRouter-only headers
- DeepSeek has no strict json_schema: use response_format json_object
and rely on the prompt for shape (ai_schema.dart removed)
- secure-storage key openrouter_api_key -> deepseek_api_key
- default model deepseek/deepseek-v4-flash -> deepseek-chat
- l10n strings, test dart-defines (DEEPSEEK_API_KEY/_TEST_MODEL), docs
Also bundles in-progress findBodyIgnoreRule (body-level ignore rules
applied before the AI call) already present in the working tree.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>