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

169 lines
8.5 KiB
JSON

{
"format": 1,
"function": "propose_allocation",
"cases": [
{
"name": "owing X (-30000, oldest owing) and Y (-20000), owed in Z (+10000): 40000 gives X 30000, Y 10000",
"input": {
"amount_ore": 40000,
"accounts": [
{ "account_id": "X", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -30000 },
{ "account_id": "Y", "created_at": "2025-02-01T00:00:00.000Z", "archived": false, "payer_net_ore": -20000 },
{ "account_id": "Z", "created_at": "2024-12-01T00:00:00.000Z", "archived": false, "payer_net_ore": 10000 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "X", "amount_ore": 30000 }, { "account_id": "Y", "amount_ore": 10000 } ], "excess_ore": 0, "over_settled_account_ids": [] } }
},
{
"name": "same accounts, 50000 = exactly the total debt: no excess",
"input": {
"amount_ore": 50000,
"accounts": [
{ "account_id": "X", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -30000 },
{ "account_id": "Y", "created_at": "2025-02-01T00:00:00.000Z", "archived": false, "payer_net_ore": -20000 },
{ "account_id": "Z", "created_at": "2024-12-01T00:00:00.000Z", "archived": false, "payer_net_ore": 10000 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "X", "amount_ore": 30000 }, { "account_id": "Y", "amount_ore": 20000 } ], "excess_ore": 0, "over_settled_account_ids": [] } }
},
{
"name": "same accounts, 60000: excess 10000 added to the last owing account Y, over-settled [Y]",
"input": {
"amount_ore": 60000,
"accounts": [
{ "account_id": "X", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -30000 },
{ "account_id": "Y", "created_at": "2025-02-01T00:00:00.000Z", "archived": false, "payer_net_ore": -20000 },
{ "account_id": "Z", "created_at": "2024-12-01T00:00:00.000Z", "archived": false, "payer_net_ore": 10000 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "X", "amount_ore": 30000 }, { "account_id": "Y", "amount_ore": 30000 } ], "excess_ore": 10000, "over_settled_account_ids": ["Y"] } }
},
{
"name": "same accounts, 20000 is less than the first debt: only X",
"input": {
"amount_ore": 20000,
"accounts": [
{ "account_id": "X", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -30000 },
{ "account_id": "Y", "created_at": "2025-02-01T00:00:00.000Z", "archived": false, "payer_net_ore": -20000 },
{ "account_id": "Z", "created_at": "2024-12-01T00:00:00.000Z", "archived": false, "payer_net_ore": 10000 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "X", "amount_ore": 20000 } ], "excess_ore": 0, "over_settled_account_ids": [] } }
},
{
"name": "input order does not matter: accounts listed newest first",
"input": {
"amount_ore": 40000,
"accounts": [
{ "account_id": "Y", "created_at": "2025-02-01T00:00:00.000Z", "archived": false, "payer_net_ore": -20000 },
{ "account_id": "Z", "created_at": "2024-12-01T00:00:00.000Z", "archived": false, "payer_net_ore": 10000 },
{ "account_id": "X", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -30000 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "X", "amount_ore": 30000 }, { "account_id": "Y", "amount_ore": 10000 } ], "excess_ore": 0, "over_settled_account_ids": [] } }
},
{
"name": "no owing accounts: 5000 with only Z (owed) goes to Z, over-settled [Z]",
"input": {
"amount_ore": 5000,
"accounts": [ { "account_id": "Z", "created_at": "2024-12-01T00:00:00.000Z", "archived": false, "payer_net_ore": 10000 } ]
},
"expected": { "ok": { "allocations": [ { "account_id": "Z", "amount_ore": 5000 } ], "excess_ore": 5000, "over_settled_account_ids": ["Z"] } }
},
{
"name": "no owing accounts: a net of exactly 0 is not owing; target is the oldest non-archived account",
"input": {
"amount_ore": 700,
"accounts": [
{ "account_id": "A", "created_at": "2024-01-01T00:00:00.000Z", "archived": true, "payer_net_ore": 0 },
{ "account_id": "B", "created_at": "2024-06-01T00:00:00.000Z", "archived": false, "payer_net_ore": 500 },
{ "account_id": "C", "created_at": "2024-03-01T00:00:00.000Z", "archived": false, "payer_net_ore": 0 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "C", "amount_ore": 700 } ], "excess_ore": 700, "over_settled_account_ids": ["C"] } }
},
{
"name": "all accounts archived and none owing: the oldest account",
"input": {
"amount_ore": 1200,
"accounts": [
{ "account_id": "P", "created_at": "2025-05-01T00:00:00.000Z", "archived": true, "payer_net_ore": 0 },
{ "account_id": "Q", "created_at": "2025-03-01T00:00:00.000Z", "archived": true, "payer_net_ore": 300 },
{ "account_id": "R", "created_at": "2025-04-01T00:00:00.000Z", "archived": true, "payer_net_ore": 0 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "Q", "amount_ore": 1200 } ], "excess_ore": 1200, "over_settled_account_ids": ["Q"] } }
},
{
"name": "archived owing accounts are still settled (archived never affects money)",
"input": {
"amount_ore": 1500,
"accounts": [
{ "account_id": "old", "created_at": "2024-01-01T00:00:00.000Z", "archived": true, "payer_net_ore": -1000 },
{ "account_id": "new", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -1000 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "old", "amount_ore": 1000 }, { "account_id": "new", "amount_ore": 500 } ], "excess_ore": 0, "over_settled_account_ids": [] } }
},
{
"name": "equal created_at among owing accounts: ordered by id ascending",
"input": {
"amount_ore": 1500,
"accounts": [
{ "account_id": "q", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -1000 },
{ "account_id": "p", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -1000 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "p", "amount_ore": 1000 }, { "account_id": "q", "amount_ore": 500 } ], "excess_ore": 0, "over_settled_account_ids": [] } }
},
{
"name": "equal created_at with no owing account: target chosen by id ascending",
"input": {
"amount_ore": 100,
"accounts": [
{ "account_id": "n", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": 0 },
{ "account_id": "m", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": 50 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "m", "amount_ore": 100 } ], "excess_ore": 100, "over_settled_account_ids": ["m"] } }
},
{
"name": "single owing account, amount above its debt: excess to it",
"input": {
"amount_ore": 1000,
"accounts": [
{ "account_id": "Z", "created_at": "2024-12-01T00:00:00.000Z", "archived": false, "payer_net_ore": 10000 },
{ "account_id": "X", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -1 }
]
},
"expected": { "ok": { "allocations": [ { "account_id": "X", "amount_ore": 1000 } ], "excess_ore": 999, "over_settled_account_ids": ["X"] } }
},
{
"name": "no accounts",
"input": { "amount_ore": 1000, "accounts": [] },
"expected": { "error": "no_accounts" }
},
{
"name": "amount 0",
"input": {
"amount_ore": 0,
"accounts": [ { "account_id": "X", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -30000 } ]
},
"expected": { "error": "amount_out_of_range" }
},
{
"name": "amount 1 000 000 001",
"input": {
"amount_ore": 1000000001,
"accounts": [ { "account_id": "X", "created_at": "2025-01-01T00:00:00.000Z", "archived": false, "payer_net_ore": -30000 } ]
},
"expected": { "error": "amount_out_of_range" }
},
{
"name": "error order: amount checked before no accounts",
"input": { "amount_ore": 0, "accounts": [] },
"expected": { "error": "amount_out_of_range" }
}
]
}