feat(library-traffic): Library Traffic Averaging Endpoints - #413
Open
estao1 wants to merge 44 commits into
Open
Conversation
…eting old records
…rom 13 to 15 months
… and entry structures
…rn library traffic history queries
…ypes for aggregation
…e date examples for consistency
…le date ranges and improve cursor handling
…pes and queries to 1800 seconds
…Id examples for consistency
… and simplify date handling
…e and endDate optional
…Date optional and refine validation logic
…ror handling and update period to bucketStart
…ing redundant error checks
… descriptions for historical data routes
…artDate, and endDate fields in query schemas
…ive and clarify granularity handling
HwijungK
requested changes
May 30, 2026
Collaborator
There was a problem hiding this comment.
#300 adds WEEK_MS to stdlib which we could use instead of a hardcoded number but its not merged yet... If it gets merged before reminders to add. if not, its whatever really
Contributor
Author
There was a problem hiding this comment.
ill keep this open for now then
laggycomputer
requested changes
May 31, 2026
…one first before comparing to not exclude evening readings on last day of term
…splay strings in LibraryName
…e enum for type safety
…ttern history routes for clarity
…clarity and consistency across query schemas
…prove query performance
…ce granularity descriptions for clarity
…ce week calculation logic
laggycomputer
requested changes
Jun 3, 2026
HwijungK
reviewed
Jun 3, 2026
…ute to clarify granularity and usage patterns
…dize timestamp handling to UTC ISO 8601
…t logic for traffic queries
… formatting in SQL queries
HwijungK
requested changes
Jun 11, 2026
HwijungK
left a comment
Collaborator
There was a problem hiding this comment.
Pattern Endpoint fails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds three new REST + GraphQL endpoints under
/v2/rest/libraryTrafficfor accessing historical occupancy data, alongside small consistency improvements to the existing snapshot endpoint.New endpoints
GET /historyGET /history/aggregatedhour/day/week/month). Scope with(startDate + endDate)or(year + quarter). Range cap per granularity to bound response size.GET /history/patternEquivalent GraphQL queries (
libraryTrafficHistory,libraryTrafficHistoryAggregated,libraryTrafficHistoryPattern) are exposed with matching shapes and@cacheControl(maxAge: 1800).Implementation notes
year + quarter + periodare convenience filters that resolve viacalendarTerm. Raw and aggregated overwrite the date range from the term; pattern joins ontimestamp BETWEEN periodStart AND periodEndso each row gets its term context.floor((ts - periodStart)/604800) + 1), so week numbers are 1–10 (term-relative) rather than ISO weeks of the year. Whengranularity=weekwith an explicit quarter filter, rows are separated per-term and includeyear/quarterin the response; otherwise data is combined across terms.(timestamp > cursor.ts) OR (timestamp = cursor.ts AND id > cursor.id)predicate to keep pagination stable across duplicate timestamps (multiple locations scraped at the same second).productionCache({ maxAge: 1800 }), matching the 30-minute scraper cadence and the GraphQL@cacheControlTTLs.HTTPException(400)instead ofError, so users get proper status codes instead of 500s.200with an empty array/items, matching the codebase convention (courses, instructors, enrollment-history). The pre-existing snapshot endpoint keeps its400-on-emptybehavior.Related Issue
Closes #243
Motivation and Context
The existing snapshot endpoint only exposes current occupancy. Consumers (study-spot recommendations, dashboards, etc.) need historical views — both raw records for export/analysis and aggregated/pattern views for charts.
How Has This Been Tested?
Manually verified each endpoint via
curlagainst a local dev server with backfilled history:GET /libraryTraffic— snapshot regressionGET /libraryTraffic/history— pagination terminates correctly; composite cursor handles duplicate timestampsGET /libraryTraffic/history/aggregatedwith(startDate + endDate),(year + quarter), and missing both (422)GET /libraryTraffic/history/patternwithgranularity=hour|day|week|month, with and withoutyear/quarterfilters, verifying week-of-term buckets are 1–10 and labels are clean ("2pm","Monday","Week 5")pnpm check:typesandpnpm check:biomeclean forapps/apiScreenshots (if appropriate):
Types of changes
Checklist: