Skip to content

Pivot to a data-only calendar-feed library#9

Merged
m1ngsama merged 17 commits into
mainfrom
feat/calendar-feed-library
Jun 17, 2026
Merged

Pivot to a data-only calendar-feed library#9
m1ngsama merged 17 commits into
mainfrom
feat/calendar-feed-library

Conversation

@m1ngsama

Copy link
Copy Markdown
Member

Closes #8.

Summary

Rebuilds @nbtca/nbtcal from a campus course-schedule scraper into a data-only, isomorphic calendar-feed library for ical.nbtca.space (the maintainers' Google Calendar, exported as ICS). It owns all date/recurrence logic and hands typed events + heatmap data to consumers like @nbtca/prompt; rendering stays out of this package.

Google Calendar -> ical.nbtca.space -> @nbtca/nbtcal (data) -> @nbtca/prompt (presentation)

What changed

  • Removed the old scraper/email/serverless code (src/auth|scraper|converter|mailer|i18n|cli, api/, the CLI bin) and the related doc sprawl.
  • Added a focused library:
    • fetchFeed() — isomorphic fetch (global fetch) with timeout + typed errors.
    • parseCalendar() — ICS → events via ical.js.
    • occurrencesInRange / upcoming / next — recurrence-aware queries (the old prompt code silently dropped RRULE events).
    • heatmap() — dense day/week buckets, timezone-stable (default Asia/Shanghai, overridable) so output is identical on Node, browser, and any host TZ.
    • loadCalendar() — convenience wrapper; FeedFetchError / FeedParseError typed errors.
  • Tests: 26 vitest tests, verified host-TZ-independent (pass under TZ=UTC and TZ=America/New_York).
  • Packaging: 0.2.0, data-only exports, no bin; added MIT LICENSE.
  • CI/CD: ci.yml (test + build on push/PR) and release.yml (npm publish with provenance on v* tags).
  • Governance: calendar-source maintenance doc + issue/discussion templates; refreshed TODO.

Test plan

  • npm test — 26/26 pass
  • npm test under TZ=America/New_York — 26/26 pass (timezone stability)
  • npm run build — clean, dist/ has no test files
  • npx tsc --noEmit — clean

Notes

A whole-implementation code review was completed; findings (timezone-stable heatmap, rolling upcoming window, next clamp, removed dead DateRange export) are addressed in fix: address code review.

The @nbtca/prompt-side change to consume this library is intentionally out of scope and tracked separately.

m1ngsama and others added 17 commits June 17, 2026 09:39
Pivot @nbtca/nbtcal from campus course scraper to a data-only calendar
feed library that fetches/parses ical.nbtca.space, owns date/recurrence
logic, and exposes typed events plus heatmap data for @nbtca/prompt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- heatmap buckets by a fixed IANA time zone (default Asia/Shanghai) with an
  optional timeZone override, instead of host-local time; output is now
  deterministic across Node/browser/any host TZ (verified under TZ=America/New_York)
- upcoming() uses a clean rolling now+days*24h window (was ~1 day too long)
- next() clamps non-positive counts; horizon cap documented
- remove unused DateRange export (YAGNI)
- drop TZ=UTC test crutch now that bucketing is timezone-explicit

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces the stale scraper test.yml.example. Release publishes @nbtca/nbtcal
to npm on pushing a v* tag, using the NPM_TOKEN secret. No provenance because
the source repo is private.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@m1ngsama m1ngsama merged commit 793c488 into main Jun 17, 2026
1 check passed
@m1ngsama m1ngsama deleted the feat/calendar-feed-library branch June 17, 2026 03:19
m1ngsama added a commit that referenced this pull request Jun 17, 2026
Pivot to a data-only calendar-feed library
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.

Pivot @nbtca/nbtcal into a data-only calendar-feed library

1 participant