40 Commits

Author SHA1 Message Date
SmileQWQ
8235e77c4e fix: switch telegram delivery to markdownv2
- route direct-channel notifications through grouped template rendering so markdown-capable senders consume shared markdown bodies consistently
- replace Telegram's markdown-to-html bridge with a MarkdownV2 converter that preserves supported formatting and wraps bare urls safely
- refresh notification presentation and dispatch coverage for grouped templates, markdown fallback, and Telegram regression cases
2026-05-29 01:29:21 +08:00
SmileQWQ
34110e731b feat: add reusable notification templates
- add shared notification template defaults, validation, and settings persistence for text, markdown, and html groups
- add the settings page editor modal, preview flow, and form wiring with markdown and html first and plain text fallback last
- cover template storage and editor integration with focused shared, api, and web regression tests
2026-05-29 01:28:52 +08:00
SmileQWQ
88750bb00a fix: support self-hosted bark and gotify delivery
- allow full Bark urls and inline basic auth without appending /push
- permit private self-hosted Bark and Gotify endpoints in validation and dispatch
- cover custom-url and self-hosted delivery with targeted tests
2026-05-28 19:30:57 +08:00
SmileQWQ
a4d6c34d39 feat: add target-based apprise notification support
- extend shared settings, backend notification routes, and forgot-password or direct-channel delivery so Apprise can sync target lists to a stateful API key and send both broadcast and target-specific test notifications

- add the Apprise targets management modal, settings form handling, locale copy, and focused web/api regression coverage for sync status, validation, and target testing

- document the optional Apprise API deployment and configuration flow in the bilingual readmes and deployment guide without changing the default compose footprint
2026-05-28 18:25:14 +08:00
SmileQWQ
fb914a0f5d feat: add bark and notifyx direct notification channels
- extend shared settings, locale resources, backend dispatch, and web settings flows so Bark and NotifyX can be configured, tested, and used as direct notification channels

- add focused apprise-adjacent regression coverage for notification routing, test endpoints, forgot-password eligibility, and settings validation without changing the default deployment shape

- refresh the bilingual README notification lists and keep the English-facing copy aligned with the new channel names and settings summaries
2026-05-28 09:32:11 +08:00
SmileQWQ
be81928a78 fix: restore post-merge verification coverage
- update the api statistics and webhook test mocks for getResolvedAppLocale so the i18n merge does not leave hidden failing unit cases behind

- align the subscription detail drawer source assertion with locale-driven labels instead of hardcoded zh-CN copy

- tighten subscription detail and webhook payload typing so tsc, lint and the full build stay green after the fast-forward merge
2026-05-22 20:26:32 +08:00
SmileQWQ
c726df08d3 feat: localize backend runtime copy across imports and notifications
- route subscription, notification, ai, logo, import and scheduler runtime messages through shared locale keys instead of hardcoded copy or language branches

- pass request locales through the affected backend routes and translate nested error details so validation and warning payloads stay localized end to end

- refresh backend regression coverage and clean the leftover api type debt that blocked lint while keeping the runtime behavior unchanged
2026-05-17 22:44:42 +08:00
SmileQWQ
0f7be94900 feat: localize ai summary generation flow
- make dashboard AI summary generation locale-aware across prompts, fallback messages and cached metadata

- regenerate summaries when the cached locale no longer matches the current request locale and reuse the resolved app locale for backend fallbacks

- refresh the statistics summary query on locale changes and extend backend tests for localized summary behavior
2026-05-17 20:55:28 +08:00
SmileQWQ
b88659062a feat: unify app locale persistence and bootstrap flow
- add a dedicated app locale endpoint and move locale persistence from settings to appLocale with env-based defaults

- sync the app shell and login bootstrap flow against the resolved backend locale while keeping localStorage only as a cache

- reject locale updates through PATCH /settings and cover the migration and locale route behavior with regression tests
2026-05-17 20:55:28 +08:00
SmileQWQ
477fb25682 feat: add shared i18n foundation
- add shared locale schemas, key-based message catalogs and locale helpers for zh-CN and en-US

- route API errors, notifications and default AI prompts through locale-aware message lookups with request and settings fallbacks

- cover locale parsing, settings defaults and i18n-aware backend flows with regression tests
2026-05-17 20:49:11 +08:00
SmileQWQ
3edff87727 perf: trim main statistics and ai summary inputs
- keep the existing overview DTO surface while reducing duplicated projected statistics work under the hood

- shrink dashboard AI summary inputs to top and non-empty slices so generated copy stays lighter without changing the response contract

- add regression coverage for overview field compatibility and the reduced AI summary payload shape
2026-05-16 21:13:58 +08:00
SmileQWQ
080e8c81c6 perf: steady main cron renewal and debug paths
- reuse timezone and exchange-rate context across auto-renew batches while adding VPS-friendly renewal guard rails

- expose auto-renew batch tuning through env and keep notification scan debug candidates off the default cron path

- cover the new renewal limits and scan-debug routing with targeted regression tests
2026-05-16 21:13:58 +08:00
SmileQWQ
86d1c83a5f perf: batch main backup import writes
- batch SubTracker backup payment record restores and narrow append duplicate checks to reduce SQLite write churn

- skip append order rewrites when the import is a no-op while keeping replace and restore behavior unchanged

- add route and service regression coverage for stable backup commit responses and batched restore semantics
2026-05-16 20:45:49 +08:00
SmileQWQ
59b5ed7042 fix: dedupe merged notification deliveries by reminder entry
- carry merged reminder dispatch through per-entry dedup metadata so count changes do not resend the same cycle

- route direct channels through shared presentation and dispatch helpers so pending-entry filtering and single-entry fallback stay consistent

- add regression coverage for merged reminder count changes, direct-channel fallback and webhook retry behavior
2026-05-12 15:35:49 +08:00
SmileQWQ
1ed1e01f8d feat: add in-app release update notices
- add a public version updates endpoint that reads GitHub releases and filters tags above the current app version

- show a brand-area update dot and release modal in the web app with shared DTOs and query helpers

- cover the endpoint and sidebar indicator flow with regression tests
2026-05-10 18:40:06 +08:00
SmileQWQ
c36cfec236 feat: improve subscription deletion and detail metrics
- prevent direct deletion of active subscriptions and allow batch delete to skip active items with clearer feedback

- add current cycle and remaining value metrics to subscription detail and convert remaining value into the base currency

- render compact reminder rule entries and cover the new batch delete and detail behavior with regression tests
2026-05-10 17:36:27 +08:00
SmileQWQ
262f7e738e feat: add notification-based password recovery
- add shared schemas, auth routes and channel delivery for password reset verification codes

- gate forgot-password availability on the settings switch plus direct notification channels

- surface login and settings controls in the web app with regression coverage
2026-05-10 17:35:35 +08:00
SmileQWQ
8c3a61b17e feat: add ai summary backend flow
- add shared ai summary prompt and dto fields for the latest-only summary state
- implement in-memory summary generation, preview caching, and dashboard summary routes
- cover the backend summary flow with route and service tests
2026-05-03 04:47:45 +08:00
SmileQWQ
7254f21ad1 fix: align main backup copy and timezone naming
- sync the backup modal and restore success wording on main with the confirmed lite copy
- generate exported backup filenames in the configured app timezone instead of UTC
- extend web and api regression tests for the updated backup wording and filename behavior
2026-05-03 00:43:23 +08:00
SmileQWQ
3f6717ce23 feat: add zip backup import and restore flow
- add shared and api contracts for SubTracker backup inspect, commit and export

- add ZIP backup modal and settings entry for backup and migration flows

- remove legacy CSV and JSON subscription export path in favor of backup flow
2026-05-02 16:46:11 +08:00
SmileQWQ
7a7cc54f1b fix: clean old notification dedup records
- keep notification idempotency records for 90 days
- clean only Setting rows with the notification: prefix
- run cleanup through a once-per-day local-time gate instead of every scan
- add unit coverage for the retention cutoff and daily gate
2026-05-01 19:53:37 +08:00
SmileQWQ
6009ea1938 fix: make reminder scans diagnosable
- allow same-day makeup scans after the configured reminder time without crossing into the next day
- include subscription-specific and legacy reminder windows when selecting scan candidates
- keep reminder delivery idempotent through period keys, including merged notifications
- add a dry-run scan-debug endpoint for manual diagnosis
- replace noisy cron output with concise user-readable scan and channel summaries
- add regression tests for reminder makeup windows and scan-debug routing
2026-05-01 18:32:43 +08:00
SmileQWQ
85f6430907 feat: improve batch and tag management UX
- add batch status override for active, paused, and cancelled subscriptions
- support selecting and clearing the current rendered/page subscriptions in batch mode
- switch multi-tag subscription filtering to AND semantics
- add paused resume behavior while keeping paused subscriptions out of budgets
- clear the create subscription form after successful save
- remove tag icon selection and display while preserving backend compatibility
- add regression tests for batch status, tag filtering, budget, and tag UI
2026-05-01 18:32:15 +08:00
SmileQWQ
9b8d33fffb feat: align app timezone behavior on main
- add configurable business timezone handling across settings, calendar, notifications, statistics, renewals, and subscription forms

- preserve TZ as the default runtime fallback while letting saved settings override business date calculations

- port Wallos source-timezone preview handling from worker and store imported business dates using the active app timezone

- gate daily refresh cron execution against settings.timezone so low-frequency tasks follow the configured business day
2026-04-25 21:16:51 +08:00
SmileQWQ
1aa5a95a61 fix: harden subscription form validation 2026-04-25 16:00:35 +08:00
SmileQWQ
4003e24e47 feat: align wallos import semantics and refresh highlights 2026-04-25 01:50:17 +08:00
SmileQWQ
6c7470d020 feat: add notification providers and theme support
- add SMTP/Resend provider switching plus Server 酱 and Gotify settings, validation, and test endpoints
- keep email config backward compatible while reworking the notification settings grid into a compact 3-column layout
- add local-only light/dark theme preference with a floating sidebar toggle and dark theme styling across cards, pages, charts, logo pickers, and drawers
- tighten notification target URL validation, update exchange rate provider naming, and refresh API/web tests for the new settings and theme behavior
2026-04-24 10:49:31 +08:00
SmileQWQ
5004c3b3c8 perf: port reusable worker improvements to main
Port cross-runtime improvements from the cf-worker branch back to main without bringing Worker-free specific tradeoffs.

Frontend:
- add single-flight request coalescing for save, settings, tag, and AI actions
- add explicit saving/loading states for subscription save and AI recognition
- unify settings data access behind useSettingsQuery with a shared query key
- stop AI autofill from overwriting advance/overdue reminder rules
- deep-clone settings query data before binding form state so nested notification and AI inputs remain editable
- refine AI loading copy layout and adjust calendar card wording for clearer UX

Backend:
- split getAppSettings hot-path reads into narrow getters for login options, AI config, reminder defaults, and notification channel/scan settings
- cache auth session secret, stored credentials, and mustChangePassword in memory to avoid repeated password verification work on every request
- slim statistics and calendar reads to only fetch fields required by each view
- reduce exchange-rate read duplication by reusing resolved base currency instead of re-reading settings unnecessarily
- batch Wallos import writes via createMany for tags, subscriptions, and subscription-tag joins, then append subscription order once

Tests:
- add auth service cache coverage
- add Wallos commit batching coverage
- add single-flight, settings-form clone, and AI recognition status unit tests
- update auth, AI, and statistics tests for the new main-branch implementation strategy

Validation:
- targeted API tests passed
- targeted web tests passed
- npm run lint passed
- npm run build passed
2026-04-23 09:10:06 +08:00
SmileQWQ
eeaf5dab55 feat: add flexible reminder rule configuration
- replace fixed reminder day controls with configurable reminder rule strings for advance and overdue notifications
- add shared parsing and normalization helpers, subscription-level override fields, and default seeded rules
- switch reminder scanning to minute-level rule matching while preserving merged notification behavior
- update settings, subscription forms, detail views, and types to use tooltip-guided rule inputs and normalized save flow
- refresh API and tests to cover the new reminder rule settings, storage, and notification matching behavior
2026-04-20 18:47:08 +08:00
SmileQWQ
59196858b0 feat: harden login and notification formatting 2026-04-20 16:51:51 +08:00
SmileQWQ
364c758add feat: add merged reminder notifications
- add a basic settings toggle for merged reminder delivery

- default merged notifications to enabled and send one scan summary per run
2026-04-20 11:10:34 +08:00
SmileQWQ
2c537aca2c feat: add admin hardening and subscription management improvements
- enforce default admin password change with a blocking post-login flow
- add Telegram bot notification settings and test endpoint
- move Wallos import into Settings and add subscription CSV/JSON export
- enable batch subscription actions for renew, pause, cancel, and guarded delete
- expand frontend and API typing/tests for the new auth, settings, and subscription flows
2026-04-20 10:07:37 +08:00
SmileQWQ
d6913fef1a feat: add configurable reminder settings and app version display
- add notifyOnDueDay and overdueReminderDays to shared settings schema and defaults

- wire reminder settings through API settings service, notification scan logic, seed data, and tests

- update settings page with 默认提前提醒天数 label, 到期当天提醒 switch, and 过期提醒 multi-select

- show current app version under SubTracker branding and inject VITE_APP_VERSION during web builds

- add GPLv3 LICENSE and update README with license and acknowledgements
2026-04-19 22:55:36 +08:00
SmileQWQ
34b59ebe4b feat: refine statistics, subscriptions, and deployment docs
- add monthly subscription spend TOP10 to statistics overview and UI

- improve subscriptions pagination with per-page persistence and note-row handling

- make login validation messages friendlier on both client and server

- clarify API-only upgrade flow for static web assets

- move web unit tests into apps/web/tests/unit
2026-04-19 21:52:20 +08:00
SmileQWQ
5d9cd12cc3 fix: validate required settings for notifications and AI 2026-04-19 16:34:36 +08:00
SmileQWQ
b374992156 feat: upgrade AI multimodal compatibility
- add provider presets for Aliyun Bailian, Tencent Hunyuan, and Volcengine Ark
- switch to explicit vision and structured-output capability flags
- add separate connection and vision test flows
2026-04-19 16:27:18 +08:00
SmileQWQ
33b3185511 feat: refine renewal notifications and webhook settings 2026-04-17 15:52:12 +08:00
SmileQWQ
cc1c90c167 feat: align calendar renewals with projected statistics
- unify calendar events with projected renewal generation across a date range
- add shared projected renewal service and unit coverage for monthly, weekly, expired, and filtered states
- update statistics trend and upcoming-by-day aggregation to reuse projected events
- keep calendar summary, list view, and day detail on the same predicted event source
- refresh shared/web statistics types for projected trend metadata and distribution charts
2026-04-15 15:43:20 +08:00
SmileQWQ
264db1a0a6 feat: refactor subscriptions to tags and add Wallos import pipeline
- replace legacy category-based subscription flow with tag-based models, routes, types and UI management

- rebuild Prisma schema around Tag and SubscriptionTag, remove legacy category relation fields, and reseed defaults

- add unified Wallos import inspect/commit flow for JSON, SQLite and ZIP packages with ZIP logo ingestion and DB-version compatibility

- add auto-renew execution in scheduler plus payment record drawer entry in subscription actions

- rename user-facing renewal wording to 续订 in key views and align subscription form with tag selection and auto-renew

- improve logo handling with local library support, remote import persistence, and ZIP asset matching fallback
2026-04-15 11:42:11 +08:00
SmileQWQ
81418ea57d feat: initialize SubTracker repository 2026-04-11 13:36:43 +08:00