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:
parent
3f622f7bf7
commit
01fba40ec2
11 changed files with 5322 additions and 17 deletions
|
|
@ -230,6 +230,16 @@ class InventoryJsonCodec {
|
|||
'status': p.status.name,
|
||||
'settledOn': p.settledOn,
|
||||
'note': p.note,
|
||||
// Bilateral signed form (plantare-bilateral.md).
|
||||
'pledgeId': p.pledgeId,
|
||||
'debtorKey': p.debtorKey,
|
||||
'creditorKey': p.creditorKey,
|
||||
'debtorSignature': p.debtorSignature,
|
||||
'creditorSignature': p.creditorSignature,
|
||||
'movementId': p.movementId,
|
||||
'remoteState': p.remoteState?.name,
|
||||
'returnKind': p.returnKind.name,
|
||||
'workHours': p.workHours,
|
||||
},
|
||||
],
|
||||
'sales': [
|
||||
|
|
@ -484,6 +494,17 @@ class InventoryJsonCodec {
|
|||
_enumOr(PlantareStatus.values, m['status'], PlantareStatus.open),
|
||||
settledOn: m['settledOn'] as int?,
|
||||
note: m['note'] as String?,
|
||||
pledgeId: m['pledgeId'] as String?,
|
||||
debtorKey: m['debtorKey'] as String?,
|
||||
creditorKey: m['creditorKey'] as String?,
|
||||
debtorSignature: m['debtorSignature'] as String?,
|
||||
creditorSignature: m['creditorSignature'] as String?,
|
||||
movementId: m['movementId'] as String?,
|
||||
remoteState:
|
||||
_enumOrNull(PlantareRemoteState.values, m['remoteState']),
|
||||
returnKind: _enumOr(PlantareReturnKind.values, m['returnKind'],
|
||||
PlantareReturnKind.similar),
|
||||
workHours: (m['workHours'] as num?)?.toDouble(),
|
||||
);
|
||||
}),
|
||||
sales: _rows(root, 'sales', (m) {
|
||||
|
|
|
|||
|
|
@ -1867,14 +1867,27 @@ class VarietyRepository {
|
|||
String? owedDescription,
|
||||
int? dueBy,
|
||||
String? note,
|
||||
// Bilateral signed form (plantare-bilateral.md) — all optional so a plain
|
||||
// local note stays a v1 row with these null.
|
||||
String? id,
|
||||
int? madeOn,
|
||||
String? pledgeId,
|
||||
String? debtorKey,
|
||||
String? creditorKey,
|
||||
String? debtorSignature,
|
||||
String? creditorSignature,
|
||||
String? movementId,
|
||||
PlantareRemoteState? remoteState,
|
||||
PlantareReturnKind returnKind = PlantareReturnKind.similar,
|
||||
double? workHours,
|
||||
}) async {
|
||||
final (created, updated) = await _stamp();
|
||||
final id = idGen.newId();
|
||||
final rowId = id ?? idGen.newId();
|
||||
await _db
|
||||
.into(_db.plantares)
|
||||
.insert(
|
||||
PlantaresCompanion.insert(
|
||||
id: id,
|
||||
id: rowId,
|
||||
createdAt: created,
|
||||
updatedAt: updated,
|
||||
lastAuthor: nodeId,
|
||||
|
|
@ -1882,12 +1895,75 @@ class VarietyRepository {
|
|||
varietyId: Value(varietyId),
|
||||
counterparty: Value(counterparty),
|
||||
owedDescription: Value(owedDescription),
|
||||
madeOn: created,
|
||||
madeOn: madeOn ?? created,
|
||||
dueBy: Value(dueBy),
|
||||
note: Value(note),
|
||||
pledgeId: Value(pledgeId),
|
||||
debtorKey: Value(debtorKey),
|
||||
creditorKey: Value(creditorKey),
|
||||
debtorSignature: Value(debtorSignature),
|
||||
creditorSignature: Value(creditorSignature),
|
||||
movementId: Value(movementId),
|
||||
remoteState: Value(remoteState),
|
||||
returnKind: Value(returnKind),
|
||||
workHours: Value(workHours),
|
||||
),
|
||||
);
|
||||
return id;
|
||||
return rowId;
|
||||
}
|
||||
|
||||
/// The local row holding the bilateral pledge [pledgeId], or null. Both parties
|
||||
/// key their own row by the shared pledge id so accepts/declines reconcile.
|
||||
Future<Plantare?> plantareByPledgeId(String pledgeId) =>
|
||||
(_db.select(_db.plantares)
|
||||
..where((p) => p.pledgeId.equals(pledgeId))
|
||||
..limit(1))
|
||||
.getSingleOrNull();
|
||||
|
||||
/// Applies a counterparty's stub(s) and the new handshake [remoteState] to the
|
||||
/// row for [pledgeId] (e.g. on receiving an `accept`). No-op if unknown.
|
||||
Future<void> applyPlantareSignatures({
|
||||
required String pledgeId,
|
||||
String? debtorSignature,
|
||||
String? creditorSignature,
|
||||
PlantareRemoteState? remoteState,
|
||||
String? movementId,
|
||||
}) async {
|
||||
final (_, updated) = await _stamp();
|
||||
await (_db.update(_db.plantares)
|
||||
..where((p) => p.pledgeId.equals(pledgeId)))
|
||||
.write(
|
||||
PlantaresCompanion(
|
||||
debtorSignature:
|
||||
debtorSignature == null ? const Value.absent() : Value(debtorSignature),
|
||||
creditorSignature: creditorSignature == null
|
||||
? const Value.absent()
|
||||
: Value(creditorSignature),
|
||||
movementId:
|
||||
movementId == null ? const Value.absent() : Value(movementId),
|
||||
remoteState:
|
||||
remoteState == null ? const Value.absent() : Value(remoteState),
|
||||
updatedAt: Value(updated),
|
||||
lastAuthor: Value(nodeId),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Moves the row for [pledgeId] to a new handshake [state] (e.g. `declined`).
|
||||
Future<void> setPlantareRemoteState(
|
||||
String pledgeId,
|
||||
PlantareRemoteState state,
|
||||
) async {
|
||||
final (_, updated) = await _stamp();
|
||||
await (_db.update(_db.plantares)
|
||||
..where((p) => p.pledgeId.equals(pledgeId)))
|
||||
.write(
|
||||
PlantaresCompanion(
|
||||
remoteState: Value(state),
|
||||
updatedAt: Value(updated),
|
||||
lastAuthor: Value(nodeId),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// All live commitments, newest first (for the Plantares screen).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue