Skip to content

Commit bee9959

Browse files
icecrasher321claude
andcommitted
fix(usage): reject an empty custom date instead of reading it as absent
`if (!value) return true` let `?start-date=` through, the route's ternary turned the empty string into `undefined`, and the partial-selection fallback answered about the current period rather than the range named in the request. Absent stays valid — the picker clears the param rather than blanking it, and a missing bound is a real state the resolver handles. Explicitly blank is only reachable from a hand-built request, where a 400 beats a window nobody asked for. Deliberately different from `usageLimitSchema`, which does coerce `''` to its default: that field declares one, so omission has a documented meaning. These bounds declare none, so treating blank as absent substitutes a different answer rather than a default one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 8e38399 commit bee9959

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

apps/sim/lib/api/contracts/organization-usage.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ describe('organization usage window contract', () => {
3737
expect(parseWindow({ startDate: '2026-02-30T00:00:00' }).success).toBe(false)
3838
})
3939

40+
it('refuses an empty date but allows an absent one', () => {
41+
// The picker clears the param rather than blanking it, so `?start-date=` is a
42+
// malformed request — and treating it as absent silently answered about the
43+
// current period instead of the range the caller named.
44+
expect(parseWindow({ startDate: '' }).success).toBe(false)
45+
expect(parseWindow({}).success).toBe(true)
46+
})
47+
4048
it('treats an empty limit as omitted rather than as zero', () => {
4149
// `z.coerce.number()` turns `''` into `0`, which then fails `.min(1)` — so a
4250
// client serializing an unset filter got a 400 instead of the declared default.

apps/sim/lib/api/contracts/organization-usage.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,18 @@ const isoDateSchema = z
6363
.optional()
6464
.refine(
6565
(value) => {
66-
if (!value) return true
66+
/*
67+
Absent is allowed; empty is not. A missing bound is a real state — the picker
68+
clears the param rather than blanking it — and the resolver falls back to the
69+
current period for it. An explicit `?start-date=` is a malformed request, and
70+
treating it as absent silently answered about a different window than the one
71+
asked for.
72+
73+
Deliberately unlike `usageLimitSchema`, which does coerce `''` to its default:
74+
that field declares a default, so omission has a documented meaning. These
75+
bounds have none — omitting one changes which period you get.
76+
*/
77+
if (value === undefined) return true
6778
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return false
6879
return new Date(`${value}T00:00:00.000Z`).toISOString().slice(0, 10) === value
6980
},

0 commit comments

Comments
 (0)