Setup Ralph.
This commit is contained in:
114
specs/calendar.md
Normal file
114
specs/calendar.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Calendar Specification
|
||||
|
||||
## Job to Be Done
|
||||
|
||||
When I want to plan ahead, I want to view my cycle phases on a calendar, so that I can schedule training and rest days appropriately.
|
||||
|
||||
## ICS Feed
|
||||
|
||||
### Endpoint: GET `/api/calendar/[userId]/[token].ics`
|
||||
|
||||
Returns ICS calendar feed for subscription in external apps.
|
||||
|
||||
**URL Format:**
|
||||
```
|
||||
https://phaseflow.app/api/calendar/user123/abc123token.ics
|
||||
```
|
||||
|
||||
**Security:**
|
||||
- `token` is a random 32-character secret per user
|
||||
- Token stored in `user.calendarToken`
|
||||
- No authentication required (token IS authentication)
|
||||
|
||||
### ICS Events
|
||||
|
||||
Generate events for the next 90 days:
|
||||
|
||||
**Phase Events (all-day):**
|
||||
```ics
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:🩸 Menstrual (Days 1-3)
|
||||
DTSTART;VALUE=DATE:20240110
|
||||
DTEND;VALUE=DATE:20240113
|
||||
DESCRIPTION:Gentle rebounding only. Weekly limit: 30 min.
|
||||
END:VEVENT
|
||||
```
|
||||
|
||||
**Color Coding (via categories):**
|
||||
- MENSTRUAL: Red
|
||||
- FOLLICULAR: Green
|
||||
- OVULATION: Pink
|
||||
- EARLY_LUTEAL: Yellow
|
||||
- LATE_LUTEAL: Orange
|
||||
|
||||
### Token Regeneration
|
||||
|
||||
POST `/api/calendar/regenerate-token`
|
||||
|
||||
Generates new `calendarToken`, invalidating previous subscriptions.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"token": "newRandomToken123...",
|
||||
"url": "https://phaseflow.app/api/calendar/user123/newRandomToken123.ics"
|
||||
}
|
||||
```
|
||||
|
||||
## In-App Calendar
|
||||
|
||||
### Month View (`/calendar`)
|
||||
|
||||
Full-page calendar showing current month with phase visualization.
|
||||
|
||||
**Components:**
|
||||
- `month-view.tsx` - Main calendar grid
|
||||
- `day-cell.tsx` - Individual day cell
|
||||
|
||||
**Day Cell Contents:**
|
||||
- Date number
|
||||
- Phase color background
|
||||
- Period indicator (if day 1-3)
|
||||
- Today highlight
|
||||
- Training decision icon (for today only)
|
||||
|
||||
### Navigation
|
||||
|
||||
- Previous/Next month buttons
|
||||
- "Today" button to jump to current date
|
||||
- Month/Year header
|
||||
|
||||
### Phase Legend
|
||||
|
||||
Below calendar:
|
||||
```
|
||||
🩸 Menstrual | 🌱 Follicular | 🌸 Ovulation | 🌙 Early Luteal | 🌑 Late Luteal
|
||||
```
|
||||
|
||||
## ICS Utilities (`src/lib/ics.ts`)
|
||||
|
||||
**Functions:**
|
||||
- `generateCalendarFeed(user, startDate, endDate)` - Create ICS string
|
||||
- `generatePhaseEvents(lastPeriodDate, cycleLength, range)` - Create phase events
|
||||
|
||||
**Dependencies:**
|
||||
- `ics` npm package for ICS generation
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. ICS feed subscribable in Google Calendar, Apple Calendar, Outlook
|
||||
2. Phase colors render correctly in calendar apps
|
||||
3. In-app calendar responsive on mobile
|
||||
4. Token regeneration immediately invalidates old URLs
|
||||
|
||||
## Acceptance Tests
|
||||
|
||||
- [ ] ICS endpoint returns valid ICS format
|
||||
- [ ] ICS contains events for next 90 days
|
||||
- [ ] Invalid token returns 401
|
||||
- [ ] Regenerate token creates new unique token
|
||||
- [ ] Month view renders all days in month
|
||||
- [ ] Day cells show correct phase colors
|
||||
- [ ] Today is visually highlighted
|
||||
- [ ] Navigation between months works
|
||||
- [ ] Phase legend displays correctly
|
||||
Reference in New Issue
Block a user