# Contrat Workflow Steps v1

Contrat de reference pour les etapes du workflow d'intervention en mode mobile offline-first.

## Perimetre

Ce document definit:
- Le modele de donnees des steps (backend + mobile)
- Le schema SQLite local pour les steps
- Le cycle de vie des statuts et les regles de validation
- Le comportement de synchronisation (queue offline + resolution de conflits)

Ce contrat s'applique a CoolCare et MissioFlow SaaS.

## Modele canonique d'un step

Objet step (serveur et runtime mobile):

```json
{
  "id": "check-pressure-1",
  "intervention_id": 1234,
  "order_index": 10,
  "type": "measurement",
  "label": "Pression HP",
  "required": true,
  "status": "todo",
  "value": null,
  "unit": "bar",
  "constraints": {
    "min": 0,
    "max": 50,
    "precision": 1
  },
  "options": [],
  "metadata": {},
  "updated_at": "2026-04-14T21:00:00.000Z",
  "version": 1
}
```

Champs obligatoires:
- id: string, unique dans une intervention
- intervention_id: number
- order_index: number
- type: enum
- label: string
- required: boolean
- status: enum
- updated_at: string ISO
- version: entier (version optimiste)

Champs optionnels:
- value: mixte (depend du type)
- unit: string
- constraints: object
- options: tableau (pour les types a choix)
- metadata: object

## Types de step

Valeurs autorisees pour type:
- checklist: booleen ou tableau de cles cochees
- measurement: number
- text: string
- photo: tableau d'elements photo
- signature: objet avec role signataire + reference fichier/chemin

Contrats de valeur selon le type:
- checklist:
  - simple: true/false
  - multi-option: ["opt_a", "opt_b"]
- measurement:
  - nombre uniquement, valide avec constraints.min/max/precision
- text:
  - texte libre, max_length optionnel dans constraints
- photo:
  - [{"id":"local-1","uri":"file:///...","uploaded":false}]
- signature:
  - {"signed":true,"signed_by":"technicien|client","uri":"file:///..."}

## Cycle de vie des statuts

Valeurs autorisees pour status:
- todo
- in_progress
- done
- blocked

Regles de transition:
- todo -> in_progress
- in_progress -> done
- in_progress -> blocked
- blocked -> in_progress
- done -> in_progress (autorise seulement si l'intervention n'est pas terminee)

Regle de completion:
- Un step required=true doit etre status=done avec une valeur valide selon son type.

## Regles de validation

Validation globale:
- required=true et status=done exigent une valeur valide non vide
- updated_at doit etre renseigne a chaque ecriture locale
- version est incrementee a chaque mutation locale ajoutee a la sync

Validation measurement:
- value doit etre un nombre
- si constraints.min existe, value >= min
- si constraints.max existe, value <= max

Validation text:
- si constraints.max_length existe, la longueur de la chaine <= max_length

Validation photo:
- si required=true, au moins 1 element photo

Validation signature:
- signed=true et uri present quand required=true

## Schema SQLite local (mobile)

Table: steps

```sql
CREATE TABLE IF NOT EXISTS steps (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  intervention_id INTEGER NOT NULL,
  step_id TEXT NOT NULL,
  order_index INTEGER NOT NULL,
  type TEXT NOT NULL,
  label TEXT NOT NULL,
  required INTEGER NOT NULL DEFAULT 0,
  status TEXT NOT NULL,
  value_json TEXT,
  unit TEXT,
  constraints_json TEXT,
  options_json TEXT,
  metadata_json TEXT,
  version INTEGER NOT NULL DEFAULT 1,
  updated_at TEXT NOT NULL,
  dirty INTEGER NOT NULL DEFAULT 0,
  UNIQUE(intervention_id, step_id)
);

CREATE INDEX IF NOT EXISTS idx_steps_intervention
ON steps(intervention_id, order_index);

CREATE INDEX IF NOT EXISTS idx_steps_dirty
ON steps(dirty, intervention_id);
```

Notes:
- value_json, constraints_json, options_json, metadata_json sont des chaines JSON.
- dirty=1 signifie que les changements locaux ne sont pas encore confirmes par le backend.

## Contrat de sync_queue pour les steps

Payload d'action en file (mobile -> backend):

```json
{
  "entity_type": "step",
  "entity_id": "1234:check-pressure-1",
  "endpoint": "/missions/1234/steps/check-pressure-1/complete",
  "method": "POST",
  "payload": {
    "status": "done",
    "value": 18.5,
    "version": 3,
    "updated_at": "2026-04-14T21:10:00.000Z"
  }
}
```

Comportement push:
- traitement strictement sequentiel (pas de push parallele) pour preserver l'ordre et reduire les conflits
- arret uniquement sur erreurs auth/contrat non rejouables
- reessai des erreurs reseau transitoires a la prochaine reconnexion

## Comportement pull delta

Format delta attendu cote backend (exemple):

```json
{
  "success": true,
  "data": {
    "interventions": [],
    "steps": [
      {
        "intervention_id": 1234,
        "id": "check-pressure-1",
        "status": "done",
        "value": 19.0,
        "version": 4,
        "updated_at": "2026-04-14T21:12:00.000Z"
      }
    ],
    "server_time": "2026-04-14T21:12:10.000Z"
  }
}
```

Regle d'application locale:
- appliquer la ligne serveur si server.version > local.version
- si versions egales, conserver le updated_at le plus recent
- si local est dirty et serveur plus recent, le serveur gagne et un conflit local est journalise

## Strategie de conflit (v1)

Politique:
- le serveur gagne pour l'etat canonique
- les lignes locales ecrasees doivent etre journalisees pour diagnostic

Table locale recommandee pour les conflits:

```sql
CREATE TABLE IF NOT EXISTS step_conflicts (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  intervention_id INTEGER NOT NULL,
  step_id TEXT NOT NULL,
  local_value_json TEXT,
  server_value_json TEXT,
  local_version INTEGER,
  server_version INTEGER,
  created_at TEXT NOT NULL
);
```

## Checklist d'alignement API

Avant d'implementer l'UI finale du workflow:
- confirmer que le backend accepte version et updated_at a la completion d'un step
- confirmer que le backend renvoie la version du step dans le detail mission et le sync pull
- confirmer l'endpoint backend de mise a jour de step (chemin et payload exacts)
- confirmer que le backend inclut la liste des steps dans le detail mission pour le bootstrap offline

## Ordre d'implementation

1. Ajouter la migration de table steps dans le service DB local
2. Ajouter les fonctions repository step (get/set/list par intervention)
3. Etendre le typage de la sync_queue et les handlers pour les actions step
4. Etendre la logique d'application du pull delta pour les steps
5. Construire les ecrans workflow sur ce contrat
