Files
calendars/openspec/changes/add-ical-subscription-export/specs/ical-subscription-export/spec.md
Nathan Panchout a96be2c7b7 📝(docs) add OpenSpec workflow
Add OpenSpec workflow for AI-assisted change proposals
including proposal templates, archive commands, and
project configuration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 16:56:21 +01:00

6.8 KiB

ADDED Requirements

Requirement: Calendar Subscription Token Management

The system SHALL allow calendar owners to generate a private subscription token for their calendars using CalDAV paths directly, enabling read-only access via iCal URL from external calendar applications without requiring Django Calendar model synchronization.

Scenario: Owner generates subscription token

  • GIVEN a user owns a calendar with CalDAV path /calendars/<email>/<uuid>/
  • WHEN the user requests a subscription token with that CalDAV path
  • THEN the system verifies the user's email matches the path
  • AND generates a unique UUID token stored with the CalDAV path
  • AND returns the subscription URL in format /ical/<token>.ics

Scenario: Owner retrieves existing subscription token

  • GIVEN a user owns a calendar with an existing subscription token
  • WHEN the user requests the subscription token by CalDAV path
  • THEN the system returns the existing token and URL

Scenario: Owner regenerates subscription token

  • GIVEN a user owns a calendar with an existing subscription token
  • WHEN the user deletes the token and creates a new one
  • THEN the old token is invalidated
  • AND a new unique token is generated
  • AND the old subscription URL no longer works

Scenario: Owner revokes subscription token

  • GIVEN a user owns a calendar with an existing subscription token
  • WHEN the user requests to delete the token by CalDAV path
  • THEN the system removes the token
  • AND the subscription URL returns 404

Scenario: Non-owner cannot manage subscription token

  • GIVEN a user attempts to create a token for a CalDAV path not containing their email
  • WHEN the user sends a request with that CalDAV path
  • THEN the system rejects the request with a 403 permission error

Scenario: One token per calendar path per owner

  • GIVEN a user already has a subscription token for a CalDAV path
  • WHEN the user requests to create another token for the same path
  • THEN the system returns the existing token instead of creating a duplicate

Requirement: Public iCal Export Endpoint

The system SHALL provide a public endpoint that serves calendar data in iCal format when accessed with a valid subscription token, without requiring user authentication, using the CalDAV path stored directly in the token.

Scenario: Valid token returns calendar data

  • GIVEN a valid and active subscription token exists with a CalDAV path
  • WHEN an HTTP GET request is made to /ical/<token>.ics
  • THEN the system proxies to SabreDAV using the token's caldav_path and owner email
  • AND returns the calendar events in iCal format
  • AND the response Content-Type is text/calendar
  • AND the response is RFC 5545 compliant
  • AND no authentication headers are required

Scenario: Invalid token returns 404

  • GIVEN a token that does not exist in the system
  • WHEN an HTTP GET request is made to /ical/<invalid-token>.ics
  • THEN the system returns HTTP 404 Not Found

Scenario: Deleted token returns 404

  • GIVEN a subscription token that has been deleted
  • WHEN an HTTP GET request is made to /ical/<deleted-token>.ics
  • THEN the system returns HTTP 404 Not Found

Scenario: Access tracking

  • GIVEN a valid subscription token
  • WHEN the iCal endpoint is accessed successfully
  • THEN the system updates the token's last accessed timestamp

Scenario: Security headers are set

  • GIVEN a valid subscription URL
  • WHEN the iCal endpoint returns a response
  • THEN the response includes Cache-Control: no-store, private
  • AND the response includes Referrer-Policy: no-referrer

Scenario: Compatible with external calendar apps

  • GIVEN a valid subscription URL
  • WHEN the URL is added to Apple Calendar as a subscription
  • THEN Apple Calendar successfully subscribes and displays events
  • AND events sync automatically on refresh

Requirement: Subscription URL User Interface

The system SHALL provide a user interface for calendar owners to obtain and manage subscription URLs using CalDAV paths extracted from calendar URLs.

Scenario: Access subscription URL from calendar menu

  • GIVEN a user is viewing their calendars
  • WHEN the user opens the context menu for a calendar they own
  • THEN an option to get the subscription URL is available

Scenario: Subscription option hidden for non-owned calendars

  • GIVEN a user has shared access to a calendar but is not the owner
  • WHEN the user opens the context menu for that calendar
  • THEN the subscription URL option is NOT displayed

Scenario: Display subscription URL modal

  • GIVEN a user clicks the subscription URL option for their calendar
  • WHEN the modal opens
  • THEN the frontend extracts the CalDAV path from the calendar URL
  • AND creates or retrieves the token using the CalDAV path
  • AND the full subscription URL is displayed
  • AND a "Copy to clipboard" button is available
  • AND a warning about keeping the URL private is shown
  • AND an option to regenerate the URL is available

Scenario: Copy URL to clipboard

  • GIVEN the subscription URL modal is open
  • WHEN the user clicks "Copy to clipboard"
  • THEN the URL is copied to the system clipboard
  • AND visual feedback confirms the copy was successful

Scenario: Regenerate token from modal

  • GIVEN the subscription URL modal is open
  • WHEN the user clicks to regenerate the URL
  • THEN a confirmation dialog is shown
  • AND upon confirmation, the old token is deleted
  • AND a new token is generated
  • AND the modal updates to show the new URL

Scenario: Error handling in modal

  • GIVEN the subscription URL modal is open
  • WHEN the initial token fetch returns 404 (no existing token)
  • THEN the system automatically creates a new token
  • AND no error message is displayed to the user
  • BUT if token creation fails, an error message is displayed

Requirement: Standalone Token Storage

The system SHALL store subscription tokens independently of the Django Calendar model, using CalDAV paths directly to enable token management without requiring CalDAV-to-Django synchronization.

Scenario: Token stores CalDAV path directly

  • GIVEN a subscription token is created
  • THEN the token record includes the full CalDAV path
  • AND the token record includes the owner (user) reference
  • AND the token record includes an optional calendar display name
  • AND no foreign key to Django Calendar model is required

Scenario: Permission verification via path

  • GIVEN a user requests a subscription token
  • WHEN the system verifies permissions
  • THEN it checks that the user's email appears in the CalDAV path
  • AND does not require querying the CalDAV server