- 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
- 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
- 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
- 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
- introduce a shared direct-notification message model for title and body rendering across channels
- route forgot-password verification delivery through the same channel senders instead of faking subscription reminder payloads
- keep test notifications on the unified message path so direct channels stay consistent
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- point API and Web Vitest directly at the shared package source
- avoid relying on packages/shared/dist existing before tests run in a clean CI checkout
- avoid reading app settings from Prisma when Wallos preview test options provide defaults
- restore latest Docker tags for release images
- 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
- 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
- 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
- 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
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
- add TZ to API compose defaults and example env config
- keep tzdata in the image without hardcoding a single timezone
- apply the runtime TZ value from entrypoint so users can switch timezones cleanly
# Conflicts:
# apps/api/.env.example
- 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
- 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
- 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
- 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
- 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
- share the built-in subscription prompt between frontend and backend
- show the built-in prompt directly inside the editable custom prompt field
- keep empty or unchanged prompt values falling back to the built-in default
- add /statistics/budgets endpoint with total and tag budget summaries
- introduce dedicated 预算统计 page and hide its sidebar entry when tag budgets are disabled
- move tag monthly budget editing into a dedicated modal on the budget page
- add dashboard tag budget overview cards when tag budgets are enabled
- remove duplicate upcoming renewals table from 费用统计 and keep that info on the dashboard
- invalidate menu and statistics queries after settings changes so budget navigation updates immediately
- default login sessions to non-persistent browser storage unless remember-me is enabled
- add remember-me checkbox to login page and load configurable remember duration from the server
- add rememberSessionDays to settings and persist it through the shared settings schema
- expose login options endpoint for unauthenticated clients
- move sidebar collapse trigger higher for long single-page layouts
- 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
- 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