# Data Module — Codex (per FVW v8 §22)

**Module ID:** `oscar.data`
**Per FVW v8 v0.10.0 §22:** C1-C9 contract items.
**Status:** Constitutional — the IDB schema IS Oscar's unwritten constitution.

---

## C1 — Behaviour Inventory

| File | Purpose |
|---|---|
| `app/src/data/models/Tree.ts` | Typed tree model (species, height, condition, retention_category A/B/C/U) |
| `app/src/data/models/Site.ts` | Site model |
| `app/src/data/models/Survey.ts` | Survey model (draft → archived lifecycle) |
| `app/src/data/models/Note.ts` | Note model |
| `app/src/data/models/Report.ts` | Report model (markdown body + surveyId) |
| `app/src/data/models/BlogPost.ts` | Blog post model (added Phase 10) |
| `app/src/data/persistence/idb.ts` | Schema definition + `getDb()` + Repository pattern |
| `app/src/data/persistence/repo.ts` | `Repository<T>` class wrapping IDB |
| `app/src/data/persistence/local-storage.ts` | localStorage namespace |

---

## C2 — State Machine (per artefact type)

- **Tree:** created → updated → (linked to survey) → archived
- **Survey:** draft → active → archived (per DAT-2.2)
- **Note:** draft → published
- **Report:** draft → review → published
- **BlogPost:** draft → review → published (per Phase 10)

---

## C3 — Side Effect List

- IDB writes (every save)
- localStorage prefix writes (oscar:)
- IDB indexes (by store)
- Schema migrations (v1 → v2 added `posts`)

---

## C4 — Input Validation Contract

- Tree species must be non-empty
- Tree retention category MUST be A/B/C/U
- Note text required
- Report body required
- BlogPost title + slug required

---

## C5 — Failure Modes

- IDB quota exceeded → caught by Repository; reported
- Schema migration failure → blocks all reads
- Concurrent write → IDB transactions handle

---

## C6 — User Simulations (10+)

- Create tree → listed
- Edit survey → draft state preserved
- Save note → appears in list
- Generate report from survey → body populated
- Export PDF/DOCX → file generated

---

## C7 — Reproducibility

Deterministic: same save → same record. IDB is durable.

---

## C8 — Shape Matrix

Per-surface = list view per store.
Per-mode = list / edit / detail.
Per-chip = save / delete / export / link.
Per-state = `draft → published → archived`.

---

## C9 — State Shape Inventory

### C9.1 localStorage
- `oscar:provider`
- `oscar:theme`
- `oscar:brain-downloaded`
- `oscar:tour-completed`

### C9.2 In-memory
- `dbPromise` (lazy-loaded IDB connection)
- Repository instances per store

### C9.3 IDB (THE CONSTITUTIONAL SCHEMA)

```
DB: oscar-platform
DB_VERSION: 2

Stores:
- trees: { id (ULID, key), survey_id, species, height_m, age_class, condition, retention_category (A|B|C|U), notes, created_at, updated_at }
  Indexes: (survey_id, species)

- sites: { id (ULID, key), name, location, ... }
  Indexes: (name)

- surveys: { id (ULID, key), site_id, surveyor, date, weather, methodology, status (draft|active|archived), hazards, notes, created_at }
  Indexes: (site_id, status, date)

- notes: { id (ULID, key), title, body, status, tags[], created_at, updated_at }
  Indexes: (status, created_at)

- reports: { id (ULID, key), survey_id, title, body (markdown), status (draft|review|published), created_at, updated_at }
  Indexes: (survey_id, status)

- posts: { id (ULID, key), title, slug, body (markdown), tone, audience, status (draft|review|published), tags[], created_at, updated_at }
  Indexes: (status, slug)

Per-store database: oscar-trees, oscar-surveys, oscar-notes, etc.
```

### C9.4 UI-affecting state summary

Every view's list rendering depends on the IDB schema. Every artefact save/update affects at least one IDB store.

---

## END OF DATA CODEX

*Note: The IDB schema is Oscar's most important constitutional artefact. Per audit-plan-v2 finding: it was implicit. This codex declares it.*
