Files
kvitt/contracts/test-vectors/spend_series.json
T
jacobh2 c6df2ab8f5 M1: contracts and vectors (SPEC v0.1, schema 1)
contracts/openapi.yaml (OpenAPI 3.1, E-1..E-33, error shape and the
exhaustive error code enum, device bearer scheme), contracts/schema/
server-v1.sql (SPEC §14.1 verbatim), seven test-vector files per §14.5.5,
80 examples (every JSON body of §14.3.4, every error code, sync pull/push,
every FCM push type), and tools/contracts-check.py (stdlib-only reference
of §9.1, §9.3, §9.4 and §14.5.4 plus shape checks; the M1 gate).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 20:57:59 +02:00

1173 lines
28 KiB
JSON

{
"format": 1,
"function": "spend_series",
"cases": [
{
"name": "monthly across a year boundary, household, by category; edge buckets clipped, empty January kept, rows outside the range ignored",
"input": {
"expenses": [
{
"date": "2026-11-14",
"account_id": "x",
"category_id": "c1",
"amount_ore": 1000,
"shares": {
"a": 500,
"b": 500
}
},
{
"date": "2026-11-15",
"account_id": "x",
"category_id": "c1",
"amount_ore": 2000,
"shares": {
"a": 1000,
"b": 1000
}
},
{
"date": "2026-11-30",
"account_id": "y",
"category_id": "c2",
"amount_ore": 3000,
"shares": {
"a": 3000,
"b": 0
}
},
{
"date": "2026-12-01",
"account_id": "x",
"category_id": "c2",
"amount_ore": 4000,
"shares": {
"a": 1000,
"b": 3000
}
},
{
"date": "2027-02-10",
"account_id": "y",
"category_id": "c1",
"amount_ore": 500,
"shares": {
"a": 250,
"b": 250
}
},
{
"date": "2027-02-11",
"account_id": "x",
"category_id": "c1",
"amount_ore": 700,
"shares": {
"a": 350,
"b": 350
}
}
],
"range": {
"start": "2026-11-15",
"end_inclusive": "2027-02-10"
},
"granularity": "month",
"measure": "household",
"group_by": "category"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-11",
"start": "2026-11-15",
"end_inclusive": "2026-11-30",
"totals": {
"c1": 2000,
"c2": 3000
},
"total": 5000
},
{
"key": "2026-12",
"start": "2026-12-01",
"end_inclusive": "2026-12-31",
"totals": {
"c2": 4000
},
"total": 4000
},
{
"key": "2027-01",
"start": "2027-01-01",
"end_inclusive": "2027-01-31",
"totals": {},
"total": 0
},
{
"key": "2027-02",
"start": "2027-02-01",
"end_inclusive": "2027-02-10",
"totals": {
"c1": 500
},
"total": 500
}
],
"group_totals": {
"c1": 2500,
"c2": 7000
},
"grand_total": 9500
}
}
},
{
"name": "monthly, share of a, by account",
"input": {
"expenses": [
{
"date": "2026-11-14",
"account_id": "x",
"category_id": "c1",
"amount_ore": 1000,
"shares": {
"a": 500,
"b": 500
}
},
{
"date": "2026-11-15",
"account_id": "x",
"category_id": "c1",
"amount_ore": 2000,
"shares": {
"a": 1000,
"b": 1000
}
},
{
"date": "2026-11-30",
"account_id": "y",
"category_id": "c2",
"amount_ore": 3000,
"shares": {
"a": 3000,
"b": 0
}
},
{
"date": "2026-12-01",
"account_id": "x",
"category_id": "c2",
"amount_ore": 4000,
"shares": {
"a": 1000,
"b": 3000
}
},
{
"date": "2027-02-10",
"account_id": "y",
"category_id": "c1",
"amount_ore": 500,
"shares": {
"a": 250,
"b": 250
}
},
{
"date": "2027-02-11",
"account_id": "x",
"category_id": "c1",
"amount_ore": 700,
"shares": {
"a": 350,
"b": 350
}
}
],
"range": {
"start": "2026-11-15",
"end_inclusive": "2027-02-10"
},
"granularity": "month",
"measure": {
"share": "a"
},
"group_by": "account"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-11",
"start": "2026-11-15",
"end_inclusive": "2026-11-30",
"totals": {
"x": 1000,
"y": 3000
},
"total": 4000
},
{
"key": "2026-12",
"start": "2026-12-01",
"end_inclusive": "2026-12-31",
"totals": {
"x": 1000
},
"total": 1000
},
{
"key": "2027-01",
"start": "2027-01-01",
"end_inclusive": "2027-01-31",
"totals": {},
"total": 0
},
{
"key": "2027-02",
"start": "2027-02-01",
"end_inclusive": "2027-02-10",
"totals": {
"y": 250
},
"total": 250
}
],
"group_totals": {
"x": 2000,
"y": 3250
},
"grand_total": 5250
}
}
},
{
"name": "monthly, share of b, by category: a zero share is omitted from totals",
"input": {
"expenses": [
{
"date": "2026-11-14",
"account_id": "x",
"category_id": "c1",
"amount_ore": 1000,
"shares": {
"a": 500,
"b": 500
}
},
{
"date": "2026-11-15",
"account_id": "x",
"category_id": "c1",
"amount_ore": 2000,
"shares": {
"a": 1000,
"b": 1000
}
},
{
"date": "2026-11-30",
"account_id": "y",
"category_id": "c2",
"amount_ore": 3000,
"shares": {
"a": 3000,
"b": 0
}
},
{
"date": "2026-12-01",
"account_id": "x",
"category_id": "c2",
"amount_ore": 4000,
"shares": {
"a": 1000,
"b": 3000
}
},
{
"date": "2027-02-10",
"account_id": "y",
"category_id": "c1",
"amount_ore": 500,
"shares": {
"a": 250,
"b": 250
}
},
{
"date": "2027-02-11",
"account_id": "x",
"category_id": "c1",
"amount_ore": 700,
"shares": {
"a": 350,
"b": 350
}
}
],
"range": {
"start": "2026-11-15",
"end_inclusive": "2027-02-10"
},
"granularity": "month",
"measure": {
"share": "b"
},
"group_by": "category"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-11",
"start": "2026-11-15",
"end_inclusive": "2026-11-30",
"totals": {
"c1": 1000
},
"total": 1000
},
{
"key": "2026-12",
"start": "2026-12-01",
"end_inclusive": "2026-12-31",
"totals": {
"c2": 3000
},
"total": 3000
},
{
"key": "2027-01",
"start": "2027-01-01",
"end_inclusive": "2027-01-31",
"totals": {},
"total": 0
},
{
"key": "2027-02",
"start": "2027-02-01",
"end_inclusive": "2027-02-10",
"totals": {
"c1": 250
},
"total": 250
}
],
"group_totals": {
"c1": 1250,
"c2": 3000
},
"grand_total": 4250
}
}
},
{
"name": "share of a user absent from every shares map counts 0",
"input": {
"expenses": [
{
"date": "2026-11-14",
"account_id": "x",
"category_id": "c1",
"amount_ore": 1000,
"shares": {
"a": 500,
"b": 500
}
},
{
"date": "2026-11-15",
"account_id": "x",
"category_id": "c1",
"amount_ore": 2000,
"shares": {
"a": 1000,
"b": 1000
}
},
{
"date": "2026-11-30",
"account_id": "y",
"category_id": "c2",
"amount_ore": 3000,
"shares": {
"a": 3000,
"b": 0
}
},
{
"date": "2026-12-01",
"account_id": "x",
"category_id": "c2",
"amount_ore": 4000,
"shares": {
"a": 1000,
"b": 3000
}
},
{
"date": "2027-02-10",
"account_id": "y",
"category_id": "c1",
"amount_ore": 500,
"shares": {
"a": 250,
"b": 250
}
},
{
"date": "2027-02-11",
"account_id": "x",
"category_id": "c1",
"amount_ore": 700,
"shares": {
"a": 350,
"b": 350
}
}
],
"range": {
"start": "2026-11-15",
"end_inclusive": "2026-12-31"
},
"granularity": "month",
"measure": {
"share": "z"
},
"group_by": "category"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-11",
"start": "2026-11-15",
"end_inclusive": "2026-11-30",
"totals": {},
"total": 0
},
{
"key": "2026-12",
"start": "2026-12-01",
"end_inclusive": "2026-12-31",
"totals": {},
"total": 0
}
],
"group_totals": {},
"grand_total": 0
}
}
},
{
"name": "weekly across the 2026/2027 boundary: ISO week 2026-W53 runs 28 Dec 2026 to 3 Jan 2027; first and last weeks clipped, empty W52 kept",
"input": {
"expenses": [
{
"date": "2026-12-19",
"account_id": "x",
"category_id": "c1",
"amount_ore": 50,
"shares": {
"a": 25,
"b": 25
}
},
{
"date": "2026-12-20",
"account_id": "x",
"category_id": "c1",
"amount_ore": 100,
"shares": {
"a": 50,
"b": 50
}
},
{
"date": "2026-12-31",
"account_id": "x",
"category_id": "c1",
"amount_ore": 200,
"shares": {
"a": 100,
"b": 100
}
},
{
"date": "2027-01-01",
"account_id": "y",
"category_id": "c2",
"amount_ore": 300,
"shares": {
"a": 300,
"b": 0
}
},
{
"date": "2027-01-03",
"account_id": "y",
"category_id": "c2",
"amount_ore": 400,
"shares": {
"a": 0,
"b": 400
}
},
{
"date": "2027-01-04",
"account_id": "x",
"category_id": "c1",
"amount_ore": 500,
"shares": {
"a": 250,
"b": 250
}
},
{
"date": "2027-01-12",
"account_id": "y",
"category_id": "c2",
"amount_ore": 600,
"shares": {
"a": 300,
"b": 300
}
},
{
"date": "2027-01-13",
"account_id": "y",
"category_id": "c2",
"amount_ore": 900,
"shares": {
"a": 450,
"b": 450
}
}
],
"range": {
"start": "2026-12-20",
"end_inclusive": "2027-01-12"
},
"granularity": "week",
"measure": "household",
"group_by": "category"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-W51",
"start": "2026-12-20",
"end_inclusive": "2026-12-20",
"totals": {
"c1": 100
},
"total": 100
},
{
"key": "2026-W52",
"start": "2026-12-21",
"end_inclusive": "2026-12-27",
"totals": {},
"total": 0
},
{
"key": "2026-W53",
"start": "2026-12-28",
"end_inclusive": "2027-01-03",
"totals": {
"c1": 200,
"c2": 700
},
"total": 900
},
{
"key": "2027-W01",
"start": "2027-01-04",
"end_inclusive": "2027-01-10",
"totals": {
"c1": 500
},
"total": 500
},
{
"key": "2027-W02",
"start": "2027-01-11",
"end_inclusive": "2027-01-12",
"totals": {
"c2": 600
},
"total": 600
}
],
"group_totals": {
"c1": 800,
"c2": 1300
},
"grand_total": 2100
}
}
},
{
"name": "weekly across the 2026/2027 boundary, share of b, by account",
"input": {
"expenses": [
{
"date": "2026-12-19",
"account_id": "x",
"category_id": "c1",
"amount_ore": 50,
"shares": {
"a": 25,
"b": 25
}
},
{
"date": "2026-12-20",
"account_id": "x",
"category_id": "c1",
"amount_ore": 100,
"shares": {
"a": 50,
"b": 50
}
},
{
"date": "2026-12-31",
"account_id": "x",
"category_id": "c1",
"amount_ore": 200,
"shares": {
"a": 100,
"b": 100
}
},
{
"date": "2027-01-01",
"account_id": "y",
"category_id": "c2",
"amount_ore": 300,
"shares": {
"a": 300,
"b": 0
}
},
{
"date": "2027-01-03",
"account_id": "y",
"category_id": "c2",
"amount_ore": 400,
"shares": {
"a": 0,
"b": 400
}
},
{
"date": "2027-01-04",
"account_id": "x",
"category_id": "c1",
"amount_ore": 500,
"shares": {
"a": 250,
"b": 250
}
},
{
"date": "2027-01-12",
"account_id": "y",
"category_id": "c2",
"amount_ore": 600,
"shares": {
"a": 300,
"b": 300
}
},
{
"date": "2027-01-13",
"account_id": "y",
"category_id": "c2",
"amount_ore": 900,
"shares": {
"a": 450,
"b": 450
}
}
],
"range": {
"start": "2026-12-20",
"end_inclusive": "2027-01-12"
},
"granularity": "week",
"measure": {
"share": "b"
},
"group_by": "account"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-W51",
"start": "2026-12-20",
"end_inclusive": "2026-12-20",
"totals": {
"x": 50
},
"total": 50
},
{
"key": "2026-W52",
"start": "2026-12-21",
"end_inclusive": "2026-12-27",
"totals": {},
"total": 0
},
{
"key": "2026-W53",
"start": "2026-12-28",
"end_inclusive": "2027-01-03",
"totals": {
"x": 100,
"y": 400
},
"total": 500
},
{
"key": "2027-W01",
"start": "2027-01-04",
"end_inclusive": "2027-01-10",
"totals": {
"x": 250
},
"total": 250
},
{
"key": "2027-W02",
"start": "2027-01-11",
"end_inclusive": "2027-01-12",
"totals": {
"y": 300
},
"total": 300
}
],
"group_totals": {
"x": 400,
"y": 700
},
"grand_total": 1100
}
}
},
{
"name": "weekly where the ISO year is ahead of the calendar year: 30 Dec 2024 is in 2025-W01",
"input": {
"expenses": [
{
"date": "2024-12-29",
"account_id": "x",
"category_id": "c1",
"amount_ore": 100,
"shares": {
"a": 50,
"b": 50
}
},
{
"date": "2024-12-30",
"account_id": "y",
"category_id": "c1",
"amount_ore": 200,
"shares": {
"a": 100,
"b": 100
}
},
{
"date": "2025-01-06",
"account_id": "x",
"category_id": "c2",
"amount_ore": 300,
"shares": {
"a": 150,
"b": 150
}
}
],
"range": {
"start": "2024-12-28",
"end_inclusive": "2025-01-06"
},
"granularity": "week",
"measure": "household",
"group_by": "account"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2024-W52",
"start": "2024-12-28",
"end_inclusive": "2024-12-29",
"totals": {
"x": 100
},
"total": 100
},
{
"key": "2025-W01",
"start": "2024-12-30",
"end_inclusive": "2025-01-05",
"totals": {
"y": 200
},
"total": 200
},
{
"key": "2025-W02",
"start": "2025-01-06",
"end_inclusive": "2025-01-06",
"totals": {
"x": 300
},
"total": 300
}
],
"group_totals": {
"x": 400,
"y": 200
},
"grand_total": 600
}
}
},
{
"name": "month boundaries in a leap year: last and first days land in their own months, 29 Feb counted",
"input": {
"expenses": [
{
"date": "2028-01-31",
"account_id": "x",
"category_id": "c1",
"amount_ore": 100,
"shares": {
"a": 50,
"b": 50
}
},
{
"date": "2028-02-01",
"account_id": "x",
"category_id": "c1",
"amount_ore": 200,
"shares": {
"a": 100,
"b": 100
}
},
{
"date": "2028-02-29",
"account_id": "x",
"category_id": "c2",
"amount_ore": 300,
"shares": {
"a": 150,
"b": 150
}
},
{
"date": "2028-03-01",
"account_id": "x",
"category_id": "c1",
"amount_ore": 400,
"shares": {
"a": 200,
"b": 200
}
}
],
"range": {
"start": "2028-01-31",
"end_inclusive": "2028-03-01"
},
"granularity": "month",
"measure": "household",
"group_by": "category"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2028-01",
"start": "2028-01-31",
"end_inclusive": "2028-01-31",
"totals": {
"c1": 100
},
"total": 100
},
{
"key": "2028-02",
"start": "2028-02-01",
"end_inclusive": "2028-02-29",
"totals": {
"c1": 200,
"c2": 300
},
"total": 500
},
{
"key": "2028-03",
"start": "2028-03-01",
"end_inclusive": "2028-03-01",
"totals": {
"c1": 400
},
"total": 400
}
],
"group_totals": {
"c1": 700,
"c2": 300
},
"grand_total": 1000
}
}
},
{
"name": "month boundaries in a common year: February has 28 days",
"input": {
"expenses": [
{
"date": "2027-02-28",
"account_id": "x",
"category_id": "c1",
"amount_ore": 100,
"shares": {
"a": 50,
"b": 50
}
},
{
"date": "2027-03-01",
"account_id": "x",
"category_id": "c1",
"amount_ore": 200,
"shares": {
"a": 100,
"b": 100
}
}
],
"range": {
"start": "2027-02-01",
"end_inclusive": "2027-03-31"
},
"granularity": "month",
"measure": "household",
"group_by": "category"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2027-02",
"start": "2027-02-01",
"end_inclusive": "2027-02-28",
"totals": {
"c1": 100
},
"total": 100
},
{
"key": "2027-03",
"start": "2027-03-01",
"end_inclusive": "2027-03-31",
"totals": {
"c1": 200
},
"total": 200
}
],
"group_totals": {
"c1": 300
},
"grand_total": 300
}
}
},
{
"name": "a single-day range with no expenses: one empty, clipped bucket",
"input": {
"expenses": [],
"range": {
"start": "2026-10-17",
"end_inclusive": "2026-10-17"
},
"granularity": "month",
"measure": "household",
"group_by": "category"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-10",
"start": "2026-10-17",
"end_inclusive": "2026-10-17",
"totals": {},
"total": 0
}
],
"group_totals": {},
"grand_total": 0
}
}
},
{
"name": "weekly with no expenses: whole weeks, all empty",
"input": {
"expenses": [],
"range": {
"start": "2026-10-12",
"end_inclusive": "2026-10-25"
},
"granularity": "week",
"measure": "household",
"group_by": "category"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-W42",
"start": "2026-10-12",
"end_inclusive": "2026-10-18",
"totals": {},
"total": 0
},
{
"key": "2026-W43",
"start": "2026-10-19",
"end_inclusive": "2026-10-25",
"totals": {},
"total": 0
}
],
"group_totals": {},
"grand_total": 0
}
}
},
{
"name": "several expenses in the same group and bucket are summed",
"input": {
"expenses": [
{
"date": "2026-10-01",
"account_id": "x",
"category_id": "c1",
"amount_ore": 100,
"shares": {
"a": 50,
"b": 50
}
},
{
"date": "2026-10-17",
"account_id": "y",
"category_id": "c1",
"amount_ore": 250,
"shares": {
"a": 125,
"b": 125
}
},
{
"date": "2026-10-31",
"account_id": "x",
"category_id": "c1",
"amount_ore": 1,
"shares": {
"a": 1,
"b": 0
}
}
],
"range": {
"start": "2026-10-01",
"end_inclusive": "2026-10-31"
},
"granularity": "month",
"measure": "household",
"group_by": "category"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-10",
"start": "2026-10-01",
"end_inclusive": "2026-10-31",
"totals": {
"c1": 351
},
"total": 351
}
],
"group_totals": {
"c1": 351
},
"grand_total": 351
}
}
},
{
"name": "tombstoned rows excluded: callers pass only non-deleted expenses (AC-14.9); archived accounts and categories are ordinary ids and are counted",
"input": {
"expenses": [
{
"date": "2026-10-05",
"account_id": "archived-account",
"category_id": "archived-category",
"amount_ore": 1200,
"shares": {
"a": 600,
"b": 600
}
}
],
"range": {
"start": "2026-10-01",
"end_inclusive": "2026-10-31"
},
"granularity": "month",
"measure": "household",
"group_by": "account"
},
"expected": {
"ok": {
"buckets": [
{
"key": "2026-10",
"start": "2026-10-01",
"end_inclusive": "2026-10-31",
"totals": {
"archived-account": 1200
},
"total": 1200
}
],
"group_totals": {
"archived-account": 1200
},
"grand_total": 1200
}
}
}
]
}