@@ -118,16 +118,25 @@ describe("POST /api/cron/liquidation", () => {
118118 } ) ;
119119} ) ;
120120
121- // ── Acceptance criterion: the worker monitors prices every minute ──────────────
122- // vercel.json must schedule the liquidation cron on a 1-minute cadence.
121+ // ── Scheduling ─────────────────────────────────────────────────────────────────
122+ // Vercel Hobby rejects any cron that runs more than once a day, so vercel.json
123+ // keeps a daily safety-net schedule and the 5-minute cadence lives in
124+ // .github/workflows/keepers.yml. Both must keep pointing at this route.
123125
124- describe ( "vercel.json liquidation schedule " , ( ) => {
125- it ( "schedules /api/cron/liquidation every minute (* * * * * )" , ( ) => {
126+ describe ( "liquidation cron scheduling " , ( ) => {
127+ it ( "vercel.json schedules /api/cron/liquidation once a day (Hobby-compatible )" , ( ) => {
126128 const raw = fs . readFileSync ( path . resolve ( process . cwd ( ) , "vercel.json" ) , "utf8" ) ;
127129 const crons = ( JSON . parse ( raw ) as { crons : Array < { path : string ; schedule : string } > } ) . crons ;
128130
129131 const liquidationCron = crons . find ( ( c ) => c . path === "/api/cron/liquidation" ) ;
130132 expect ( liquidationCron ) . toBeDefined ( ) ;
131- expect ( liquidationCron ?. schedule ) . toBe ( "* * * * *" ) ;
133+ // "m h * * *" — exactly one run per day
134+ expect ( liquidationCron ?. schedule ) . toMatch ( / ^ \d { 1 , 2 } \d { 1 , 2 } \* \* \* $ / ) ;
135+ } ) ;
136+
137+ it ( "the GitHub Actions keeper workflow triggers the route every 5 minutes" , ( ) => {
138+ const raw = fs . readFileSync ( path . resolve ( process . cwd ( ) , ".github/workflows/keepers.yml" ) , "utf8" ) ;
139+ expect ( raw ) . toContain ( `cron: "*/5 * * * *"` ) ;
140+ expect ( raw ) . toContain ( "/api/cron/liquidation" ) ;
132141 } ) ;
133142} ) ;
0 commit comments