feat: [breaking] cmueats gets a real database that can store more than 7 days worth of times, and also stores overwrites#195
Conversation
…to feat/time-overwrites
|
don't mind the commits... I made this branch off of at least the diff is fine. |
|
I pushed a temp commit to main for now |
laasyaaki
left a comment
There was a problem hiding this comment.
Thanks for the PR Eric! Looks good to me for now. We can convert this to SQL once the admin dashboard is further along
| const timeInfo: ITimeRowAttributes = {}; | ||
|
|
||
| for (const token of tokens) { | ||
| for (const token of timeSlotStrings) { |
There was a problem hiding this comment.
Maybe rename token to a more intuitive name.
There was a problem hiding this comment.
Change tokens to be clearer.
| } catch (err: any) { | ||
| notifySlack( | ||
| `<!channel> Failed to parse token \`${token}\` from list of tokens \`${tokens}\`\n${err.stack}` | ||
| `<!channel> Failed to parse token \`${token}\` from time slot \`${timeSlotStrings.join( |
| }); | ||
|
|
||
| return response.data; | ||
| const attemptedParsedDate = DateTime.fromRFC2822( |
There was a problem hiding this comment.
Is there a particular reason for this over ISO 8601 or RFC 3339?
JackHurew
left a comment
There was a problem hiding this comment.
I'd wait for Jaisal's approval.
| const timeInfo: ITimeRowAttributes = {}; | ||
|
|
||
| for (const token of tokens) { | ||
| for (const token of timeSlotStrings) { |
There was a problem hiding this comment.
Change tokens to be clearer.
| "8/30/2025": ["CLOSED"], | ||
| "8/31/2025": ["CLOSED"], | ||
| "9/1/2025": ["CLOSED"], | ||
| "9/2/2025": ["CLOSED"], |
There was a problem hiding this comment.
There has got to be a more concise way to do this.
There was a problem hiding this comment.
lol usually you would override a single day, I think
| if (env.IN_TEST_MODE) { | ||
| console.log("would've notified slack with message", message); | ||
| return; | ||
| } |
There was a problem hiding this comment.
Do you clarify anywhere that this exists (test mode/this effect)? Maybe in readme?
There was a problem hiding this comment.
IN_TEST_MODE is set when tests are run (see package.json)
There was a problem hiding this comment.
Oh I figured it could also be used to allow us to stop spamming slack bot playground channel too.
There was a problem hiding this comment.
Pull Request Overview
This PR implements a major refactoring to change the time handling system from a day-of-week based approach to a date-based approach, adds database integration for storing and retrieving location data, and introduces support for time overwrites. The changes enable the system to handle specific dates rather than generic weekdays and support custom time overrides for individual locations.
Key Changes:
- Refactored time representation from day-of-week enums to full date-based structures with year/month/day
- Added database schema and operations for storing location data, times, and overwrites
- Implemented time overwrite functionality to allow custom scheduling for specific dates
- Deprecated old API endpoints and introduced new
/api/v2/locationsendpoint
Reviewed Changes
Copilot reviewed 25 out of 28 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Enabled noUncheckedIndexedAccess compiler option for stricter type checking |
| tests/mockTimings.ts | Updated test helpers to accept parser parameter and support serverDate |
| tests/mockAxios.ts | Added serverDate parameter to mock functions for date-aware testing |
| tests/locationMerger.test.ts | Updated class reference from LocationMerger to ScrapeResultMerger |
| tests/integration.test.ts | Added extensive test coverage for time overwrites and coordinate overwrites |
| src/utils/timeUtils.ts | Simplified time range merging to work with numeric timestamps |
| src/utils/slack.ts | Added console logging for test mode |
| src/utils/requestUtils.ts | Modified to parse and return server date from response headers |
| src/utils/parseTimeToken.ts | Removed unused day/date parsing functionality |
| src/utils/locationMerger.ts | Renamed class from LocationMerger to ScrapeResultMerger |
| src/utils/diff.ts | Added non-null assertion for indexed access after type narrowing |
| src/types.ts | Changed time representation from ITimeRange to IFullTimeRange with date info |
| src/server.ts | Added early return in reload function and deprecated old endpoints |
| src/parser/diningParser.ts | Removed empty constructor and updated to use new response structure |
| src/containers/timeBuilder.ts | Complete rewrite to parse dates and create date-based time ranges |
| src/containers/time/parsedTimeForDay.ts | Changed return type from enum to number (0-6) |
| src/containers/time/parsedTimeForDate.ts | Added documentation and non-null assertions |
| src/containers/time/parsedTime.ts | Added non-null assertions for array element access |
| src/containers/locationBuilder.ts | Updated to use serverDate and store earliestDayFound |
| src/deprecationNotice.ts | Added deprecation notice with old interface types |
| src/overwrites/timeOverwrites.ts | New file defining time overwrite types and data |
| src/db/schema.ts | Added new database tables for locations, times, and overwrites |
| src/db/updateLocation.ts | New file for adding/updating location data in database |
| src/db/overrides.ts | Refactored to support general and time-specific overwrites |
| src/db/getLocations.ts | New file for retrieving and merging location data from database |
| src/db/emails.ts | Extracted email retrieval logic into separate file |
| package.json | Added luxon and @types/luxon dependencies |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (3)
src/db/overrides.ts:2
- Unused import IFullTimeRange.
src/db/overrides.ts:9 - Unused import augmentAndEditTimeRangesWithDateInfo.
src/db/overrides.ts:10 - Unused import DateTime.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@cirex-web I've opened a new pull request, #212, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
oh lmao what |
|
@copilot rework the timestamps in |
|
@cirex-web I've opened a new pull request, #213, to work on those changes. Once the pull request is ready, I'll request review from you. |
…nction Co-authored-by: cirex-web <57322506+cirex-web@users.noreply.github.com>
|
@copilot how would you refactor |
|
@cirex-web I've opened a new pull request, #214, to work on those changes. Once the pull request is ready, I'll request review from you. |
There was a problem hiding this comment.
why is this file named like this lol
There was a problem hiding this comment.
drizzle auto-names the migration files lol
| const todayAsSQLString = `${location.today.year}-${pad( | ||
| location.today.month | ||
| )}-${pad(location.today.day)})`; | ||
| // add specials |
There was a problem hiding this comment.
is the end paren supposed to be there?
Refactor database.test.ts timestamps to use timeToUnixTimestamp helper

Implements everything described in https://www.notion.so/wiki-scottylabs/RFC-Introduction-of-dining-api-db-schema-w-location-data-and-time-overwrites-2a596192554c80309a8fc63efa73a434
For those willing to review this massive PR, the most important files are
schema.ts,getLocations.ts, andupdateLocation.ts, located in thedbfolder. All other changes were just made to accomodate these changes.location table
location times table
overwrites table
time overwrites table
you may have also noticed that the ids are not the concept ids. we have a separate mapping table so if dining services switches out all the ids, we can still maintain internal consistency (eg. reviews will still be tied to the correct location)

[outdated notes]
Dateresponse header when scraping the Dining website. We do so to get the current year, since that's not included in the HTML itself. And yes, we can find the year locally, but using the response header date means that we know for sure the HTML corresponds to the date. May be a bit overkill now that I'm thinking about it, but it doesn't hurt)Example of how we can overwrite times: