tane/docs/design/block1-status.md
vjrj 48e9d15772 feat(ui): align inventory + detail with mockups (seed icons, green theme)
Visual pass toward docs/mockups (06 inventory, 07 item):
- Bundle the seedks icon font (chars a–k → seed pictograms: jar, packet, spoon…)
  and a SeedGlyph/QuantityKindIcon helper.
- Green app bar + pale-green canvas theme (buildTaneTheme).
- Inventory list: rounded-square photo thumbnail or green initial avatar, bold
  title, scientific-name subtitle, trailing edit pencil, styled category
  headers, rounded search field, seed-glyph empty state.
- Quantity selectors (quick-add + add-lot) show the seed pictogram + word;
  detail lot lines use the kind's glyph.
- Detail header restyled to mockup 07: category link + scientific name on the
  left, photo on the right.

watchInventory now also returns the linked species' scientific name (subtitle).
37 app tests green; seedks font verified in the Linux asset bundle.
2026-07-08 00:14:43 +02:00

118 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Block 1 — estado actual (marcador)
*Dónde estamos en el Bloque 1 (inventario offline, cifrado, multilingüe). Este
fichero es el marcador de progreso; actualízalo al avanzar. Convenciones en
[`../../CLAUDE.md`](../../CLAUDE.md) y guía del sprint en [`first-sprint.md`](first-sprint.md).*
## Hecho ✅
Arquitectura y estado (como G1nkgo pero adaptado): **`flutter_bloc` (Cubit)** con
la **BD Drift cifrada (SQLCipher) como fuente de verdad** (sin hydrated_bloc/Hive,
que dejaría texto en claro); **`get_it`**, **`go_router`**, **`slang`** (ES/EN,
JSON por locale, compatible Weblate). Ver [`../../apps/app_seeds`](../../apps/app_seeds).
- **Workspace + CI**: pub workspace (`commons_core` puro Dart + `app_seeds`),
AGPL LICENSE, `.gitlab-ci.yml` (format + analyze + test + cobertura,
instala libsqlcipher).
- **commons_core**: UUIDv7 (`IdGen`), Hybrid Logical Clock (`Hlc`), `Quantity`
(+ `QuantityKind` plant-aware), stub de semilla raíz (`IdentityService`).
- **BD**: Drift `schemaVersion=1`, 10 tablas + columnas CRDT (HLC `updated_at`,
`last_author`, tombstones); `Movement` append-only. Export
`drift_schemas/drift_schema_v1.json` + test de migración.
- **Cifrado**: SQLCipher vía executor inyectable que **se niega a abrir en claro**;
clave de BD + semilla raíz en el keystore (secretos separados). Test
"no plaintext at rest" **verificado** (corre con libsqlcipher; en CI se instala).
- **Inventario (UI)**: alta rápida (etiqueta + foto + cantidad ~20 s), lista por
categorías con búsqueda y **miniatura de foto**/inicial, ficha con nombre
científico, categoría, nombres vernáculos (solo lectura), notas, lotes
(año + unidad) y **% de germinación** por lote, edición de campos + enlazar
**especie del catálogo** (rellena familia), borrado suave.
- **Catálogo de especies**: 14 hortícolas ibéricas (familia + nombres ES/EN),
sembrado idempotente al arrancar, búsqueda + autocompletado.
- **Germinación**: pruebas por lote (germinadas/muestra → tasa derivada), badge
reactivo.
- **Tests**: 37 verdes, 0 saltados. `analyze` + `format` limpios.
## Pendiente en el Bloque 1 (pulido) ⏳
- **Editar nombres vernáculos** ("también conocida como": hoy solo lectura;
falta añadir/quitar — colección OR-Set).
- **Editar/borrar lotes** (se pueden añadir pero no modificar/eliminar). Falta
`updateLot`/`softDeleteLot` en el repo (hoy solo `addLot` en
[`variety_repository.dart`](../../apps/app_seeds/lib/data/variety_repository.dart))
y la afordancia en las tiles de lote de
[`variety_detail_screen.dart`](../../apps/app_seeds/lib/ui/variety_detail_screen.dart).
El soft-delete ya tiene infraestructura (`isDeleted`/tombstone vía `SyncColumns`).
- **Editar cantidad del lote**: la UI de alta solo ofrece 6 `QuantityKind` como
chips; falta campo para cantidad numérica (`precise`) y etiqueta libre (`label`),
que el modelo (`Quantity`) ya soporta.
- (Opcional) QR de recuperación de la semilla raíz; almacenamiento cifrado de
fotos fuera de la BD (hoy van como BLOB cifrado dentro de la BD, que cumple la
regla).
### Feedback de prueba (vjrj, 2026-07-07)
Tras probar la app: no se pueden editar unidades/cantidad ni editar/borrar lotes
(solo añadir) — **esperado**, cubierto por los pendientes de arriba. Echa en falta
la iconografía de los mockups (ver nota siguiente).
## Iconografía de los mockups (diseño futuro) 🎨
La app usa hoy **Material Icons genéricos**. Los iconos de los mockups **existen** ya
como font custom: **[`seedks.ttf`](../../seedks.ttf)** (raíz del repo, trackeado en
git), familia interna **"Seedks"**, **11 glifos** en `a``k` (U+0061U+006B), de la
misma época que [`../icons.svg`](../icons.svg) (2018). Preview renderizado:
[`../mockups/seedks-glyphs.png`](../mockups/seedks-glyphs.png).
Mapeo de glifos:
| Glifo | Icono | Glifo | Icono | Glifo | Icono |
|---|---|---|---|---|---|
| `a` | tarro | `e` | saco/bolsa | `i` | sobre |
| `b` | tarros (varios) | `f` | cucharilla | `j` | sobre vertiendo |
| `c` | búsqueda (lupa) | `g` | cuchara | `k` | semillas sueltas |
| `d` | mano compartiendo | `h` | taza | | |
**No** está cableado: falta declarar `fonts:` en
[`../../apps/app_seeds/pubspec.yaml`](../../apps/app_seeds/pubspec.yaml) y crear un
mapa codepoint→`IconData` (`fontFamily: 'Seedks'`). Recuperar la iconografía **no**
requiere SVGs nuevos. Iconos por familia/categoría y por unidad de cantidad =
trabajo de diseño para después del pulido del Bloque 1.
## Fuera de alcance (Bloque 2, no empezar) 🚫
Ofertas, mensajería, relays, Nostr, red de confianza, Ğ1, sincronización entre
dispositivos, backup completo. Ver [`../../CLAUDE.md`](../../CLAUDE.md).
## Cómo correr la app
**Requisitos previos** (una vez): los ficheros generados (Drift, slang) ya están
commiteados; si algo falla, regenera con:
```bash
cd apps/app_seeds
dart run build_runner build --delete-conflicting-outputs # Drift
dart run slang # i18n
```
**IntelliJ IDEA** (con plugins *Flutter* y *Dart* instalados):
1. Abre la carpeta raíz del repo (`tane`) como proyecto.
2. En *Settings → Languages & Frameworks → Flutter*, apunta al SDK de Flutter.
3. Hay una configuración de ejecución lista: **`app_seeds (tane)`** (en `.run/`),
cuyo *Dart entrypoint* es `apps/app_seeds/lib/main.dart`. Selecciónala en la
barra superior. Si no aparece, créala: *Run → Edit Configurations → + →
Flutter*, y pon *Dart entrypoint* = `apps/app_seeds/lib/main.dart`.
4. Elige un dispositivo (emulador Android, o *Linux desktop* / Chrome) en el
selector de dispositivos y pulsa ▶.
**Línea de comandos** (equivalente):
```bash
cd apps/app_seeds
flutter devices # ver dispositivos
flutter run -d linux # escritorio Linux (o -d chrome, o un emulador)
```
Nota: `flutter run` debe lanzarse desde `apps/app_seeds` (no desde la raíz del
workspace).