---
fragment_id: oscar.map.annotation-stub.002
domain: MAP
rule: Annotation storage schema (stub — store only, no auto-interpretation)
source: app/src/data/models/Annotation.ts
bound_to_modules:
  - oscar.map
status: SHIPPED
version: .002
---

# Annotation schema stub (per Item 8 of operator design + rules.md §12)

PDFs that are sent to a client may come back marked-up. The marked-up annotations are stored separately from the Document and the underlying layers. v0.2.0 defines the storage schema and the write path. v0.2.0 does NOT define auto-interpretation or auto-apply behaviour.

## Annotation record shape

```
Annotation {
  id: string
  documentId: string           // references Document.id
  pageNum: number              // 1-indexed
  x: number                    // 0..1, normalised to page width
  y: number                    // 0..1, normalised to page height
  w: number                    // 0..1, normalised to page width
  h: number                    // 0..1, normalised to page height
  author: string               // free-form, e.g. "client" or operator name
  timestamp: ISO8601
  text: string                 // the annotation content (typed or OCR'd)
  status: 'open' | 'applied' | 'dismissed'   // v0.2.0 starts at 'open', operator updates manually
}
```

## v0.2.0 scope

In scope:

- Write an annotation record (operator-driven)
- Read annotation records back (per-document listing)
- Update annotation status: 'open' → 'applied' | 'dismissed' (operator-driven)

Out of scope (deferred to a future doctrine pass):

- Auto-interpretation of annotation text into layer mutations
- "Apply this annotation to layer X" command
- Diff between Document version and current layer state
- Annotation → layer coordinate transformation (e.g. "move tree 5 to the annotated location")

## Persistence

Annotations are stored in the `annotations` IDB store (added in v0.2.0, DB v19). Records are write-once for fields other than `status`. The `status` field can transition `open → applied` or `open → dismissed` but not back. Status transitions write a new `Annotation.status` value to the existing record — no separate audit trail is required in v0.2.0 (a future audit doctrine pass will add it).

## Read path

The Documents view (oscar.map.documents-view.002) shows annotation count per document row. A future UI surface (annotations view) will list annotations grouped by document with status filters. v0.2.0 does not include this UI surface.