From bc8e67fbdfdafe3f6e592ad13303c67d65428e5f Mon Sep 17 00:00:00 2001 From: sstent Date: Sat, 21 Feb 2026 07:37:34 -0800 Subject: [PATCH] chore(conductor): Add new track 'Generic RRULE Formatter' --- conductor/tracks.md | 5 ++++ .../rrule_generic_formatter_20260219/index.md | 5 ++++ .../metadata.json | 8 ++++++ .../rrule_generic_formatter_20260219/plan.md | 22 ++++++++++++++++ .../rrule_generic_formatter_20260219/spec.md | 25 +++++++++++++++++++ 5 files changed, 65 insertions(+) create mode 100644 conductor/tracks/rrule_generic_formatter_20260219/index.md create mode 100644 conductor/tracks/rrule_generic_formatter_20260219/metadata.json create mode 100644 conductor/tracks/rrule_generic_formatter_20260219/plan.md create mode 100644 conductor/tracks/rrule_generic_formatter_20260219/spec.md diff --git a/conductor/tracks.md b/conductor/tracks.md index d493df3..95307d1 100644 --- a/conductor/tracks.md +++ b/conductor/tracks.md @@ -21,3 +21,8 @@ This file tracks all major tracks for the project. Each track has its own detail - [x] **Track: Fix RRULE UNTIL object conversion error: Invalid UNTIL value: [object Object]** *Link: [./tracks/fix_rrule_until_conversion_20260219/](./tracks/fix_rrule_until_conversion_20260219/)* + +--- + +- [ ] **Track: Fix SyntaxError: Invalid weekday string: [object Object] by implementing a generic recursive RRULE formatter.** + *Link: [./tracks/rrule_generic_formatter_20260219/](./tracks/rrule_generic_formatter_20260219/)* diff --git a/conductor/tracks/rrule_generic_formatter_20260219/index.md b/conductor/tracks/rrule_generic_formatter_20260219/index.md new file mode 100644 index 0000000..580fc74 --- /dev/null +++ b/conductor/tracks/rrule_generic_formatter_20260219/index.md @@ -0,0 +1,5 @@ +# Track rrule_generic_formatter_20260219 Context + +- [Specification](./spec.md) +- [Implementation Plan](./plan.md) +- [Metadata](./metadata.json) diff --git a/conductor/tracks/rrule_generic_formatter_20260219/metadata.json b/conductor/tracks/rrule_generic_formatter_20260219/metadata.json new file mode 100644 index 0000000..d04715c --- /dev/null +++ b/conductor/tracks/rrule_generic_formatter_20260219/metadata.json @@ -0,0 +1,8 @@ +{ + "track_id": "rrule_generic_formatter_20260219", + "type": "bug", + "status": "new", + "created_at": "2026-02-19T00:00:00Z", + "updated_at": "2026-02-19T00:00:00Z", + "description": "Fix SyntaxError: Invalid weekday string: [object Object] by implementing a generic recursive RRULE formatter." +} diff --git a/conductor/tracks/rrule_generic_formatter_20260219/plan.md b/conductor/tracks/rrule_generic_formatter_20260219/plan.md new file mode 100644 index 0000000..4e57169 --- /dev/null +++ b/conductor/tracks/rrule_generic_formatter_20260219/plan.md @@ -0,0 +1,22 @@ +# Implementation Plan - Generic RRULE Formatter + +## Phase 1: Reproduction & Test Setup +- [ ] Task: Create reproduction test case for `BYDAY` object + - [ ] Add a test in `icalendar_test.ts` mocking a `BYDAY` property as an array of objects (e.g. `[{ day: 'MO' }]`). + - [ ] Run the test and confirm it fails with `SyntaxError: Invalid weekday string: [object Object]`. +- [ ] Task: Conductor - User Manual Verification 'Reproduction & Test Setup' (Protocol in workflow.md) + +## Phase 2: Implementation +- [ ] Task: Implement Recursive Formatter + - [ ] Update `formatRRuleValue` in `icalendar.ts` to be a recursive function. + - [ ] Handle Arrays by joining elements with commas. + - [ ] Handle `Date` objects using the existing iCal format. + - [ ] Handle property objects (extract `date`, `day`, or `value` properties). + - [ ] Run the reproduction test to confirm it passes. +- [ ] Task: Conductor - User Manual Verification 'Implementation' (Protocol in workflow.md) + +## Phase 3: Verification & Cleanup +- [ ] Task: Composite and Regression Testing + - [ ] Add a complex test case containing both nested `UNTIL` dates and `BYDAY` arrays. + - [ ] Run the full regression test suite in `icalendar_test.ts`. +- [ ] Task: Conductor - User Manual Verification 'Verification & Cleanup' (Protocol in workflow.md) diff --git a/conductor/tracks/rrule_generic_formatter_20260219/spec.md b/conductor/tracks/rrule_generic_formatter_20260219/spec.md new file mode 100644 index 0000000..1c04d31 --- /dev/null +++ b/conductor/tracks/rrule_generic_formatter_20260219/spec.md @@ -0,0 +1,25 @@ +# Specification: Generic RRULE Object Formatter + +## Overview +The current implementation for converting RRULE objects (from `ts-ics`) back to strings is brittle and fails when encountering nested objects or arrays for properties like `BYDAY`. This results in `[object Object]` being injected into the RRULE string, causing syntax errors in the `rrule` library. This track replaces the specific property handling with a robust, recursive generic formatter. + +## Functional Requirements +- **Recursive Value Formatting:** The `formatRRuleValue` function must handle nested structures: + - **Arrays:** Join elements with commas (e.g., `['MO', 'TU']` -> `MO,TU`). + - **Date Objects:** Format as `YYYYMMDDTHHMMSSZ`. + - **Nested Property Objects:** If an object has a `date`, `day`, or `value` property, extract and format that value (e.g., `{ day: 'MO' }` -> `MO`). + - **Recursion:** If an array contains objects, or an object contains an array, the logic must recurse until primitives are reached. +- iCalendar Compliance: Ensure the resulting string for every property matches the iCalendar spec format expected by `rrule.js`. + +## Implementation Steps +1. Reproduce: Create a test case in `icalendar_test.ts` where `BYDAY` is an object or an array of objects. Verify it fails with `Invalid weekday string: [object Object]`. +2. Fix: Re-implement `formatRRuleValue` in `icalendar.ts` as a recursive function that handles Arrays, Dates, and standard `ts-ics` nested value objects. +3. Verify: + - Confirm the `BYDAY` reproduction test passes. + - Add a composite test with `UNTIL` (Date) and `BYDAY` (Array) together. + - Run regression tests to ensure standard string RRULEs still work. + +## Acceptance Criteria +- [ ] `expandRecurrences` correctly handles `BYDAY` when provided as an array of objects. +- [ ] `expandRecurrences` correctly handles `UNTIL` when provided as a nested date object. +- [ ] All 12+ existing tests pass, including regression checks for string-based RRULEs.