feat(plantare): schema v12 — bilateral signed columns + repo

Adds the deferred bilateral columns to Plantares (plantare-bilateral.md
§"Schema delta"), all nullable/defaulted so v1 local rows coexist
untouched:

- pledgeId (the shared id both parties key their row by), debtorKey /
  creditorKey, debtorSignature / creditorSignature, movementId (the
  shared hand-over Movement for the provenance DAG), remoteState
  (proposed/accepted/declined — the handshake, distinct from status),
  returnKind (similar/workHours/other, default similar) + workHours.

Repo: createPlantare grows optional bilateral params; plantareByPledgeId
looks a row up by the shared id; applyPlantareSignatures counter-stamps
an incoming accept; setPlantareRemoteState records a decline. The
JSON codec carries every new field so they ride backups.

Versioned migration is guarded/idempotent like the others; schema v12
dumped, test helper regenerated, migration test covers v1..v11 → v12.
db + data + services 295/295 green.
This commit is contained in:
vjrj 2026-07-14 10:59:35 +02:00
parent 3f622f7bf7
commit 01fba40ec2
11 changed files with 5322 additions and 17 deletions

View file

@ -102,6 +102,19 @@ enum PlantareDirection {
/// `forgiven` (not "defaulted") when it's let go.
enum PlantareStatus { open, returned, forgiven }
/// State of the bilateral SIGNED handshake, distinct from [PlantareStatus]
/// (which tracks the *promise*, not the *agreement*). A v1 local-only row leaves
/// this null. `proposed` = I sent/received a proposal awaiting the other stub;
/// `accepted` = both signed (a provably closed deal); `declined` = the other
/// party turned my proposal down. Mirrors commons_core `PlantareMessageKind`.
enum PlantareRemoteState { proposed, accepted, declined }
/// How a Plantare is promised back, mirroring the paper form's checkboxes and
/// commons_core `ReturnKind`. `similar` (the default) means open-pollinated ·
/// non-GMO · organically grown; `workHours` is time-as-currency; `other` is
/// free text in `owedDescription`.
enum PlantareReturnKind { similar, workHours, other }
/// Direction of a recorded seed Sale, seen from this app's owner. A sale is a
/// SEPARATE model from a gift or a Plantare seed for money (any currency:
/// , Ğ1, a local/time currency). No commission is ever taken on seeds.