Before code
This commit is contained in:
parent
23c12ac60c
commit
57c0eeadaf
3 changed files with 45 additions and 1 deletions
|
|
@ -14,6 +14,7 @@ Context for AI agents (Claude Code) working in this repo. Read this first, then
|
|||
- **Local-first**: everything works offline, no account, no central server. Online only enriches (degrades gracefully).
|
||||
- **Progressive disclosure**: only `Variety.label` is mandatory; every other field optional. Audience is everyone 10–80; simple by default, depth on demand. Never build "two modes".
|
||||
- **License: AGPL-3.0.** Keep new deps compatible.
|
||||
- **Tests, near-TDD.** Every behavior is covered by automated tests (unit / widget / integration); **do NOT rely on manual testing.** Write tests first for domain logic (`commons_core` is pure Dart — ideal for TDD). Nothing merges without tests covering the new behavior; CI gates it. See [`docs/design/testing.md`](docs/design/testing.md).
|
||||
- Discussion/design docs may be in Spanish; code and specs in English.
|
||||
|
||||
## Stack & structure
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
Una persona puede: abrir la app, **añadir una semilla en 20 s** (etiqueta + foto + cantidad), verla en una lista por categorías, abrir su ficha, editarla con campos avanzados plegados, y que **todo persista cifrado** entre reinicios. Multilingüe (al menos ES/EN). Corre en un dispositivo/emulador real.
|
||||
|
||||
**Cada historia se entrega con sus tests** (unit/widget/integration) — casi-TDD, sin pruebas manuales como red de seguridad. Ver [`testing.md`](testing.md). Sin tests, la historia no está hecha.
|
||||
|
||||
## Pasos
|
||||
|
||||
0. **Prerequisitos (máquina):** Flutter SDK actualizado, un emulador o dispositivo. Quitar los locks del bare si hiciera falta (`rm -f ~/repos/tane.git/*.lock`).
|
||||
|
|
@ -37,7 +39,8 @@ Una persona puede: abrir la app, **añadir una semilla en 20 s** (etiqueta + fot
|
|||
|
||||
6. **Catálogo de especies (semilla del bundle):** empezar con un CSV/JSON pequeño curado (unas pocas hortícolas ibéricas) con `scientific_name` + `wikidata_qid` + `gbif_key` + nombres comunes ES/EN, para probar el autocompletado. La "varilla" y Kew SID vienen después.
|
||||
|
||||
7. **Verificación:** `flutter analyze` limpio, `flutter test` (incl. test de migración), y arrancar en dispositivo. Añadir el texto canónico de la licencia: `curl -o LICENSE https://www.gnu.org/licenses/agpl-3.0.txt`.
|
||||
7. **Tests y CI (transversal, no al final):** ver [`testing.md`](testing.md). Como mínimo en este sprint: unit de `commons_core` (Quantity, columnas comunes, UUIDv7/HLC), **test de migración** Drift, **test de "no hay texto en claro"** en el fichero de BD, widget tests de la lista y del alta rápida, y **un integration test** del flujo "alta → persiste cifrada → reabrir → sigue ahí". Montar CI (analyze + test + cobertura) desde el primer commit de código.
|
||||
8. **Verificación final:** `flutter analyze` limpio, toda la suite en verde en emulador, cobertura publicada. Añadir el texto canónico de la licencia: `curl -o LICENSE https://www.gnu.org/licenses/agpl-3.0.txt`.
|
||||
|
||||
## Fuera de alcance de este sprint (no hacer)
|
||||
|
||||
|
|
|
|||
40
docs/design/testing.md
Normal file
40
docs/design/testing.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Tanemaki — Estrategia de pruebas (casi-TDD, sin depender de pruebas manuales)
|
||||
|
||||
*Convención del proyecto. Objetivo: **cada comportamiento cubierto por una prueba automática**; las pruebas manuales son la excepción, no la red de seguridad.*
|
||||
|
||||
## Principio
|
||||
|
||||
**Casi-TDD.** Para lógica nueva: test primero (red → green → refactor). Como mínimo innegociable: **ninguna rama se mergea sin tests que cubran lo nuevo.** La "definición de hecho" de cada historia **incluye sus tests**; sin tests, no está hecha. CI en cada push bloquea si algo falla o baja la cobertura.
|
||||
|
||||
`commons_core` es **Dart puro (sin Flutter)** → la lógica difícil (CRDT, identidad/derivación, cifrado, backup, pledge/WoT) se hace con TDD cómodo y rápido.
|
||||
|
||||
## La pirámide (Flutter/Dart)
|
||||
|
||||
- **Unit** (`dart test` / `flutter test`): lógica pura — CRDT, `Quantity`, derivación de claves, serialización, repositorios. Rápidos; el grueso vive en `commons_core`.
|
||||
- **Widget** (`flutter_test`, `pumpWidget`): pantallas y componentes — interacción, *progressive disclosure*, i18n, accesibilidad (targets grandes).
|
||||
- **Integration** (`integration_test` + `flutter test`): app entera en emulador/dispositivo, con **BD real cifrada (SQLCipher)**. Flujos e2e — **esto es lo que sustituye a las pruebas manuales.**
|
||||
- **Golden** (regresión visual): pantallas clave; vigila que la accesibilidad no se rompa.
|
||||
- **Migration** (Drift): `drift_dev schema generate` + `validateDatabaseSchema` por cada `schemaVersion`.
|
||||
|
||||
## Tests que este proyecto necesita sí o sí
|
||||
|
||||
- **Cifrado en reposo:** abrir el fichero de BD **en crudo** y afirmar que **NO hay texto en claro** (buscar una etiqueta conocida en los bytes y exigir ausencia). Regresión de seguridad clave para el "peor caso legal".
|
||||
- **CRDT — convergencia:** *property-based* — fusionar operaciones en **cualquier orden** converge al mismo estado (LWW, OR-Set, log append-only, tombstones).
|
||||
- **Migraciones:** cada versión migra desde la anterior y valida contra el esquema fresco.
|
||||
- **Backup round-trip:** exportar → borrar → importar → **estado idéntico** (y cifrado).
|
||||
- **Identidad:** derivación secp256k1 **determinista** desde la semilla (mismo input → misma clave) y unidireccional.
|
||||
- **i18n:** ninguna cadena hardcodeada (lint), y todas las locales con las mismas claves.
|
||||
|
||||
## Lo difícil de automatizar (y cómo)
|
||||
|
||||
Cámara, keystore/biométrico, relays reales: **abstraer tras interfaces** y probar con *fakes/mocks*; dejar una capa fina de adaptadores de plataforma con un *smoke test* mínimo. Los *integration tests* en dispositivo cubren la integración real de la BD cifrada. Objetivo: **manual ≈ 0**.
|
||||
|
||||
## CI y cobertura
|
||||
|
||||
- CI en cada push/PR (Forgejo/Codeberg Actions o GitHub Actions): `flutter analyze` + unit + widget + **integration en emulador** + cobertura (lcov). **Merge bloqueado** si falla o baja la cobertura.
|
||||
- Objetivo de cobertura **alto en `commons_core`** (p.ej. ≥ 85%); la UI, con widget + golden.
|
||||
- Tests deterministas y rápidos: sin red real, reloj/UUID/HLC inyectables (para reproducibilidad).
|
||||
|
||||
## Flujo de trabajo
|
||||
|
||||
Dominio (`commons_core`): test primero. UI: al menos un widget test por pantalla/flujo antes de darla por terminada, y un *integration test* por flujo crítico (alta de semilla → persiste cifrada → reabrir → sigue ahí). Regla dura repetida: **sin tests, no se mergea.**
|
||||
Loading…
Add table
Add a link
Reference in a new issue