Files
kvitt/contracts/test-vectors/compute_balances.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

142 lines
7.0 KiB
JSON

{
"format": 1,
"function": "compute_balances",
"cases": [
{
"name": "empty: no accounts, no rows",
"input": { "user_ids": ["a", "b"], "account_ids": [], "expenses": [], "settlements": [] },
"expected": { "ok": { "per_account": {}, "global": { "a": 0, "b": 0 } } }
},
{
"name": "one account, (1001, payer a, 50/50) and (100, payer b, a 6000 bp): a +440, b -440",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x"],
"expenses": [
{ "account_id": "x", "amount_ore": 1001, "payer_user_id": "a", "shares": { "a": 501, "b": 500 } },
{ "account_id": "x", "amount_ore": 100, "payer_user_id": "b", "shares": { "a": 60, "b": 40 } }
],
"settlements": []
},
"expected": { "ok": { "per_account": { "x": { "a": 440, "b": -440 } }, "global": { "a": 440, "b": -440 } } }
},
{
"name": "same account plus settlement b -> a 440: all zero",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x"],
"expenses": [
{ "account_id": "x", "amount_ore": 1001, "payer_user_id": "a", "shares": { "a": 501, "b": 500 } },
{ "account_id": "x", "amount_ore": 100, "payer_user_id": "b", "shares": { "a": 60, "b": 40 } }
],
"settlements": [ { "from_user_id": "b", "to_user_id": "a", "allocations": { "x": 440 } } ]
},
"expected": { "ok": { "per_account": { "x": { "a": 0, "b": 0 } }, "global": { "a": 0, "b": 0 } } }
},
{
"name": "two accounts with opposite signs: global is the sum",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x", "y"],
"expenses": [
{ "account_id": "x", "amount_ore": 2000, "payer_user_id": "a", "shares": { "a": 1000, "b": 1000 } },
{ "account_id": "y", "amount_ore": 600, "payer_user_id": "b", "shares": { "a": 300, "b": 300 } }
],
"settlements": []
},
"expected": { "ok": { "per_account": { "x": { "a": 1000, "b": -1000 }, "y": { "a": -300, "b": 300 } }, "global": { "a": 700, "b": -700 } } }
},
{
"name": "an account in account_ids with no rows has zeros",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x", "y"],
"expenses": [ { "account_id": "x", "amount_ore": 1001, "payer_user_id": "a", "shares": { "a": 501, "b": 500 } } ],
"settlements": []
},
"expected": { "ok": { "per_account": { "x": { "a": 500, "b": -500 }, "y": { "a": 0, "b": 0 } }, "global": { "a": 500, "b": -500 } } }
},
{
"name": "archived accounts are included: the archived account is in account_ids and counts toward global",
"input": {
"user_ids": ["a", "b"], "account_ids": ["live", "arch"],
"expenses": [
{ "account_id": "live", "amount_ore": 1000, "payer_user_id": "a", "shares": { "a": 500, "b": 500 } },
{ "account_id": "arch", "amount_ore": 5000, "payer_user_id": "b", "shares": { "a": 2500, "b": 2500 } }
],
"settlements": []
},
"expected": { "ok": { "per_account": { "live": { "a": 500, "b": -500 }, "arch": { "a": -2500, "b": 2500 } }, "global": { "a": -2000, "b": 2000 } } }
},
{
"name": "account ids referenced by rows but not in account_ids still count",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x"],
"expenses": [ { "account_id": "z", "amount_ore": 100, "payer_user_id": "b", "shares": { "a": 100, "b": 0 } } ],
"settlements": [ { "from_user_id": "a", "to_user_id": "b", "allocations": { "w": 30 } } ]
},
"expected": { "ok": { "per_account": { "x": { "a": 0, "b": 0 }, "z": { "a": -100, "b": 100 }, "w": { "a": 30, "b": -30 } }, "global": { "a": -70, "b": 70 } } }
},
{
"name": "settlement with allocations to two accounts",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x", "y"],
"expenses": [
{ "account_id": "x", "amount_ore": 10000, "payer_user_id": "a", "shares": { "a": 5000, "b": 5000 } },
{ "account_id": "y", "amount_ore": 3000, "payer_user_id": "a", "shares": { "a": 0, "b": 3000 } }
],
"settlements": [ { "from_user_id": "b", "to_user_id": "a", "allocations": { "x": 5000, "y": 1000 } } ]
},
"expected": { "ok": { "per_account": { "x": { "a": 0, "b": 0 }, "y": { "a": 2000, "b": -2000 } }, "global": { "a": 2000, "b": -2000 } } }
},
{
"name": "over-settling flips the account's sign",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x"],
"expenses": [ { "account_id": "x", "amount_ore": 1000, "payer_user_id": "a", "shares": { "a": 500, "b": 500 } } ],
"settlements": [ { "from_user_id": "b", "to_user_id": "a", "allocations": { "x": 800 } } ]
},
"expected": { "ok": { "per_account": { "x": { "a": -300, "b": 300 } }, "global": { "a": -300, "b": 300 } } }
},
{
"name": "partial settlement in the other direction",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x"],
"expenses": [ { "account_id": "x", "amount_ore": 1000, "payer_user_id": "b", "shares": { "a": 500, "b": 500 } } ],
"settlements": [ { "from_user_id": "a", "to_user_id": "b", "allocations": { "x": 200 } } ]
},
"expected": { "ok": { "per_account": { "x": { "a": -300, "b": 300 } }, "global": { "a": -300, "b": 300 } } }
},
{
"name": "expense fully borne by the payer leaves the balance unchanged",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x"],
"expenses": [
{ "account_id": "x", "amount_ore": 1001, "payer_user_id": "a", "shares": { "a": 501, "b": 500 } },
{ "account_id": "x", "amount_ore": 7000, "payer_user_id": "a", "shares": { "a": 7000, "b": 0 } }
],
"settlements": []
},
"expected": { "ok": { "per_account": { "x": { "a": 500, "b": -500 } }, "global": { "a": 500, "b": -500 } } }
},
{
"name": "tombstoned rows excluded: callers pass only non-deleted rows (§14.5.2); the account's deleted expense and deleted settlement are absent from the input",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x"],
"expenses": [ { "account_id": "x", "amount_ore": 2000, "payer_user_id": "b", "shares": { "a": 1000, "b": 1000 } } ],
"settlements": []
},
"expected": { "ok": { "per_account": { "x": { "a": -1000, "b": 1000 } }, "global": { "a": -1000, "b": 1000 } } }
},
{
"name": "maximum amounts stay exact in 64-bit integers",
"input": {
"user_ids": ["a", "b"], "account_ids": ["x"],
"expenses": [
{ "account_id": "x", "amount_ore": 1000000000, "payer_user_id": "a", "shares": { "a": 0, "b": 1000000000 } },
{ "account_id": "x", "amount_ore": 1000000000, "payer_user_id": "a", "shares": { "a": 0, "b": 1000000000 } },
{ "account_id": "x", "amount_ore": 1000000000, "payer_user_id": "a", "shares": { "a": 0, "b": 1000000000 } }
],
"settlements": []
},
"expected": { "ok": { "per_account": { "x": { "a": 3000000000, "b": -3000000000 } }, "global": { "a": 3000000000, "b": -3000000000 } } }
}
]
}