feat(app): show each batch's story as a composite timeline

The Movement log (history + provenance DAG) was recorded but invisible.
A new history sheet on every lot tile narrates the batch: movements,
germination tests, storage checks and how it entered the collection
(origin attached), most-recent first. Two one-tap chips record 'sown
today' / 'harvested today' — the first UI door to the sown/harvested
movement types. No schema change; one-shot reads only (no live
subscriptions in a transient sheet).
This commit is contained in:
vjrj 2026-07-18 06:25:55 +02:00
parent 11cbdf3022
commit 92fd84590b
10 changed files with 835 additions and 2 deletions

View file

@ -86,6 +86,7 @@ class Translations with BaseTranslations<AppLocale, Translations> {
late final Translations$notifications$en notifications = Translations$notifications$en.internal(_root);
late final Translations$plantare$en plantare = Translations$plantare$en.internal(_root);
late final Translations$handover$en handover = Translations$handover$en.internal(_root);
late final Translations$history$en history = Translations$history$en.internal(_root);
late final Translations$sale$en sale = Translations$sale$en.internal(_root);
late final Translations$legal$en legal = Translations$legal$en.internal(_root);
late final Translations$marketGate$en marketGate = Translations$marketGate$en.internal(_root);
@ -1980,6 +1981,66 @@ class Translations$handover$en {
String get promiseReceived => 'I\'ll return seed';
}
// Path: history
class Translations$history$en {
Translations$history$en.internal(this._root);
final Translations _root; // ignore: unused_field
// Translations
/// en: 'Story of this batch'
String get title => 'Story of this batch';
/// en: 'Story'
String get tooltip => 'Story';
/// en: 'Sown today'
String get sowToday => 'Sown today';
/// en: 'Harvested today'
String get harvestToday => 'Harvested today';
/// en: 'Sowing noted'
String get sownRecorded => 'Sowing noted';
/// en: 'Harvest noted'
String get harvestRecorded => 'Harvest noted';
/// en: 'Received'
String get movementReceived => 'Received';
/// en: 'Given away'
String get movementGiven => 'Given away';
/// en: 'Sown'
String get movementSown => 'Sown';
/// en: 'Harvested'
String get movementHarvested => 'Harvested';
/// en: 'Germination test'
String get movementGerminationTest => 'Germination test';
/// en: 'Split into batches'
String get movementSplit => 'Split into batches';
/// en: 'Discarded'
String get movementDiscarded => 'Discarded';
/// en: 'Added to your collection'
String get created => 'Added to your collection';
/// en: 'From {origin}'
String from({required Object origin}) => 'From ${origin}';
/// en: 'Germination test — {percent}%'
String germinationResult({required Object percent}) => 'Germination test — ${percent}%';
/// en: 'Comes from an earlier batch'
String get linkedEarlier => 'Comes from an earlier batch';
}
// Path: sale
class Translations$sale$en {
Translations$sale$en.internal(this._root);
@ -3199,6 +3260,23 @@ extension on Translations {
'handover.paymentChip' => 'Money changed hands',
'handover.promiseGave' => 'They\'ll return me seed',
'handover.promiseReceived' => 'I\'ll return seed',
'history.title' => 'Story of this batch',
'history.tooltip' => 'Story',
'history.sowToday' => 'Sown today',
'history.harvestToday' => 'Harvested today',
'history.sownRecorded' => 'Sowing noted',
'history.harvestRecorded' => 'Harvest noted',
'history.movementReceived' => 'Received',
'history.movementGiven' => 'Given away',
'history.movementSown' => 'Sown',
'history.movementHarvested' => 'Harvested',
'history.movementGerminationTest' => 'Germination test',
'history.movementSplit' => 'Split into batches',
'history.movementDiscarded' => 'Discarded',
'history.created' => 'Added to your collection',
'history.from' => ({required Object origin}) => 'From ${origin}',
'history.germinationResult' => ({required Object percent}) => 'Germination test — ${percent}%',
'history.linkedEarlier' => 'Comes from an earlier batch',
'sale.title' => 'Sales',
'sale.help' => 'Record seed you sold or bought — money, Ğ1, or any currency. A separate model from a gift or a Plantare. No commission is ever taken on seeds.',
'sale.add' => 'Record a sale',