feat(block1): bundled species catalog + autocomplete link

Add a small curated catalog of Iberian horticultural species and let a variety
be linked to it from the edit sheet.

- assets/catalog/species.json: 14 species with botanical family and ES/EN
  common names (wikidata_qid/gbif_key deferred to the varilla enrichment).
- SpeciesRepository: idempotent seedBundled (is_bundled rows, keyed by
  scientific name) + search by scientific/common name with a locale-best label.
  Seeded on startup from DI.
- VarietyRepository.linkSpecies: sets species_id and prefills category from the
  species' family when empty (never overwrites an existing category).
  VarietyDetail now carries the scientific name.
- Edit sheet gains a live species-search field; the detail view shows the
  scientific name (italic). i18n strings added (ES/EN).

Tests: catalog parse, idempotent seeding, search by scientific/common name,
linkSpecies prefill semantics, and a widget test for the autocomplete → link →
scientific-name-shown flow. Full suite: 32 passing, 0 skipped.
This commit is contained in:
vjrj 2026-07-07 21:21:59 +02:00
parent 7ff4e38a15
commit 4e8b8293e0
22 changed files with 700 additions and 47 deletions

View file

@ -39,7 +39,9 @@
"title": "Edit seed",
"name": "Name",
"category": "Category",
"notes": "Notes"
"notes": "Notes",
"species": "Species (from catalog)",
"speciesHint": "Search a species…"
},
"addLot": {
"title": "Add lot",

View file

@ -39,7 +39,9 @@
"title": "Editar semilla",
"name": "Nombre",
"category": "Categoría",
"notes": "Notas"
"notes": "Notas",
"species": "Especie (del catálogo)",
"speciesHint": "Buscar una especie…"
},
"addLot": {
"title": "Añadir lote",

View file

@ -4,9 +4,9 @@
/// To regenerate, run: `dart run slang`
///
/// Locales: 2
/// Strings: 102 (51 per locale)
/// Strings: 106 (53 per locale)
///
/// Built on 2026-07-07 at 13:25 UTC
/// Built on 2026-07-07 at 19:21 UTC
// coverage:ignore-file
// ignore_for_file: type=lint, unused_import

View file

@ -192,6 +192,12 @@ class Translations$editVariety$en {
/// en: 'Notes'
String get notes => 'Notes';
/// en: 'Species (from catalog)'
String get species => 'Species (from catalog)';
/// en: 'Search a species…'
String get speciesHint => 'Search a species…';
}
// Path: addLot
@ -313,6 +319,8 @@ extension on Translations {
'editVariety.name' => 'Name',
'editVariety.category' => 'Category',
'editVariety.notes' => 'Notes',
'editVariety.species' => 'Species (from catalog)',
'editVariety.speciesHint' => 'Search a species…',
'addLot.title' => 'Add lot',
'addLot.year' => 'Harvest year',
'addLot.quantity' => 'Quantity',

View file

@ -131,6 +131,8 @@ class _Translations$editVariety$es extends Translations$editVariety$en {
@override String get name => 'Nombre';
@override String get category => 'Categoría';
@override String get notes => 'Notas';
@override String get species => 'Especie (del catálogo)';
@override String get speciesHint => 'Buscar una especie…';
}
// Path: addLot
@ -210,6 +212,8 @@ extension on TranslationsEs {
'editVariety.name' => 'Nombre',
'editVariety.category' => 'Categoría',
'editVariety.notes' => 'Notas',
'editVariety.species' => 'Especie (del catálogo)',
'editVariety.speciesHint' => 'Buscar una especie…',
'addLot.title' => 'Añadir lote',
'addLot.year' => 'Año de cosecha',
'addLot.quantity' => 'Cantidad',