Skip to content

feat: enhance recurrence with RRULE & month-end patterns - #548

Merged
kantorge merged 3 commits into
release/v4from
feat/budget-schedule-month-end-patterns
Sep 20, 2026
Merged

kantorge merged 3 commits into
release/v4from
feat/budget-schedule-month-end-patterns

Conversation

@kantorge

@kantorge kantorge commented Sep 19, 2026

Copy link
Copy Markdown
Owner

Adds two new month-scoped recurrence patterns ("N days before month end" and "last business day of month") and fundamentally redesigns how all recurrence rules are stored and processed.

This change introduces significant benefits:

  • New Recurrence Patterns: Users can now define schedules and budgets that recur "N days before the end of the month" or on the "last business day of the month," addressing long-standing feature requests. These patterns require no new database columns.
  • Simplified Storage Model: All recurrence fields (frequency, interval, count, end date, ordinal weekday, month, and the new month-end patterns) are now consolidated into a single RFC 5545 RRULE string column on transaction_schedules and budgets. This allows for easier future expansion of recurrence capabilities without requiring database schema changes.
  • Transparent Client Experience: The API and user interface continue to work with discrete recurrence fields. A new HasRecurrenceRule trait transparently composes and decomposes the rrule string, ensuring no breaking changes for clients.
  • Streamlined Backend Logic: The RecurrenceRuleService is refactored to operate directly on the rrule string, simplifying its method signatures and improving maintainability.
  • Robust Data Migration: Existing transaction_schedules data is automatically migrated to the new rrule format through a guarded, three-step migration sequence, preserving all historical recurrence settings. New budgets are created directly with the rrule column.

This redesign improves flexibility, simplifies future development of recurrence features, and maintains data integrity during the upgrade process.

Closes #546

Summary by CodeRabbit

  • New Features

    • Added monthly and yearly recurrence options for a specified number of days before month-end and the last business day of the month.
    • Added support for displaying these patterns in schedules, budgets, forecasts, and transaction instances.
    • Recurrence settings remain available through familiar schedule and budget forms.
  • Bug Fixes

    • Improved recurrence validation, including mutually exclusive patterns, frequency restrictions, and valid day ranges.
  • Documentation

    • Updated upgrade guidance and recurrence documentation, including the new storage format and migration requirements.

@coderabbitai

coderabbitai Bot commented Sep 19, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 08e04f6a-1f83-4264-a437-b167ec75f277

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change adds two month-end recurrence patterns and stores budget and schedule recurrence data in one RFC 5545 rrule column. Virtual model attributes preserve the existing request and response fields. Migrations, validation, frontend flows, and tests are updated.

Changes

RRULE storage and backend recurrence flow

Layer / File(s) Summary
RRULE-backed model recurrence
app/Models/Concerns/HasRecurrenceRule.php, app/Models/Budget.php, app/Models/TransactionSchedule.php, app/Casts/RecurrenceCountCast.php
Budget and transaction schedule recurrence fields are decomposed from and composed into a hidden rrule attribute.
RRULE service integration
app/Services/RecurrenceRuleService.php, app/Models/Transaction.php, app/Services/BudgetService.php
Recurrence service methods now accept RRULE strings. Transaction and budget occurrence calculations pass effectiveRrule().
Database migration
database/migrations/*rrule*, database/migrations/2026_08_05_000001_create_budgets_table.php, database/schema/mysql-schema.sql
Transaction schedules use separate add, backfill, validation, and legacy-column removal migrations. Budgets use a single rrule column directly.
Legacy budget conversion
app/Console/Commands/MigrateBudgetsRecurrenceToRrule.php
A temporary command converts legacy budget recurrence columns to RRULE strings without dropping those columns.

Month-end recurrence patterns

Layer / File(s) Summary
Validation and request wiring
app/Http/Traits/ValidatesRecurrenceRule.php, app/Http/Requests/BudgetRequest.php, app/Http/Requests/TransactionRequest.php
days_before_month_end accepts values from 0 through 27. last_business_day_of_month accepts a boolean. Both are limited to monthly or yearly schedules and are mutually exclusive with other month-scoped patterns.
Frontend recurrence behavior
resources/js/transactions/components/form/TransactionSchedule.vue, resources/js/shared/lib/helpers/index.js, resources/js/reports/components/BudgetForm.vue
Forms and RRULE builders support days-before-month-end and last-business-day patterns.
Display and translations
resources/js/transactions/components/display/Schedule.vue, lang/*.json
Schedule descriptions and locale strings describe the new patterns and validation messages.

Tests and documentation

Layer / File(s) Summary
Regression coverage
tests/Feature/*, tests/Unit/Models/*, tests/Unit/Services/*, tests/Unit/Console/*
Tests cover migration backfills, RRULE round trips, mass-assignment protection, validation, occurrence dates, and RRULE service behavior.
Documentation and upgrade notes
.ai/docs/**, UPGRADE.md, CLAUDE.md
Documentation describes RRULE storage, month-end patterns, migration behavior, and the distinction between feature documentation and specifications.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature

Merge Risk: 🟡 Moderate · up to fbc51

Valid schedules may be treated as exhausted, malformed requests can fail unexpectedly, and deployment tooling has unsafe rollback and shipping behavior. These issues should be corrected before merge.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes support issue #546 or the required RRULE storage migration. The rollback change in database/migrations/2026_08_29_000002_add_composite_index_to_budgets_table.php changes unrelated index… Remove the unrelated composite-index rollback change and the unrelated CLAUDE.md taxonomy change, or provide issue-linked requirements that require them.
Docstring Coverage ⚠️ Warning Docstring coverage is 36.07% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 122 functions across 27 files. (15 skippe… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: RRULE-based recurrence storage and new month-end recurrence patterns.
Linked Issues check ✅ Passed Issue #546 requests four recurrence patterns. The existing by_day path supports ordinal weekdays, including nth weekdays and last Friday. This PR preserves that path and adds days_before_month_end
Full details: Out of Scope Changes check

Explanation

Most changes support issue #546 or the required RRULE storage migration. The rollback change in database/migrations/2026_08_29_000002_add_composite_index_to_budgets_table.php changes unrelated index handling. The CLAUDE.md documentation taxonomy change also has no connection to recurrence behavior or storage.

Full details: Docstring Coverage

Explanation

Docstring coverage is 36.07% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 122 functions across 27 files. (15 skipped: 15 unsupported.)

✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kantorge

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 19, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]

This comment was marked as resolved.

@kantorge
kantorge merged commit 38b3915 into release/v4 Sep 20, 2026
7 checks passed
@kantorge
kantorge deleted the feat/budget-schedule-month-end-patterns branch September 20, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant