{
  "schema_version": "1.0",
  "baseline": "A-document-note-service-v1",
  "phase": "Batch 11 · local/dev notes backend",
  "updated_at": "2026-04-20",
  "owner": "session_a",
  "purpose_en": "Contract for the Document Note Service — file-backed CRUD + aggregate endpoints replacing the Batch-6 browser-localStorage notes loop. Uses the same 14-field schema from docs/assets/notes/document_note_schema.json.",
  "purpose_th": "สัญญาของ Document Note Service · CRUD + aggregate · แทน localStorage ของ Batch 6 · ใช้ schema 14 ฟิลด์เดิม",
  "honest_note": "Local/dev file-backed service. Single-writer (no lock beyond the Python GIL for a single uvicorn worker). Fine for development; NOT concurrency-hardened. No auth on notes (anyone who reaches the service may write). Intended for behind-the-scenes use with the access service.",
  "persistence": {
    "mode": "file-backed JSON",
    "path": "docs/runtime/document-note-service/notes_store.json",
    "write_strategy": "whole-file rewrite on every mutation · atomic via temp-file+rename · acceptable for small backlog (<few thousand notes)",
    "fsync": false,
    "concurrency": "single-writer assumption · multiple uvicorn workers NOT safe in this batch"
  },
  "endpoints": [
    {
      "method": "GET",
      "path": "/api/notes/health",
      "returns": {
        "ok": "bool",
        "service_version": "string",
        "notes_total": "int",
        "docs_touched": "int",
        "store_path": "string",
        "started_at": "ISO-8601",
        "honest_banner": "bilingual"
      }
    },
    {
      "method": "POST",
      "path": "/api/notes/create",
      "body": {
        "doc_id": "string (required)",
        "title": "string (required)",
        "body": "string (optional)",
        "note_type": "enum (default requirement)",
        "priority": "P0|P1|P2|P3 (default P2)",
        "section_ref": "string|null",
        "created_by_type": "human|AI|system|imported (default human)"
      },
      "returns": "full note row with note_id, created_at, last_action_at"
    },
    {
      "method": "GET",
      "path": "/api/notes/list",
      "query": { "doc_id": "optional · filter to one doc" },
      "returns": { "notes": "array<note>", "count": "int" }
    },
    {
      "method": "PATCH",
      "path": "/api/notes/{note_id}",
      "body": {
        "status": "optional · must be valid transition",
        "linked_change_ref": "optional",
        "title": "optional",
        "body": "optional",
        "priority": "optional"
      },
      "returns": "updated note row",
      "validation": "status transitions validated against document_note_status_matrix.json"
    },
    {
      "method": "DELETE",
      "path": "/api/notes/{note_id}",
      "returns": { "ok": true, "deleted": "note_id" },
      "honest_note": "Hard delete. No soft-delete/audit trail in this batch."
    },
    {
      "method": "GET",
      "path": "/api/notes/aggregate",
      "returns": {
        "counters": {
          "total": "int", "open": "int", "done": "int", "deferred": "int",
          "rejected": "int", "p0_open": "int", "docs_touched": "int"
        },
        "top_docs_by_open": "array<{doc_id, open}>",
        "recent_activity": "array<note>",
        "honest_banner": "bilingual"
      }
    },
    {
      "method": "GET",
      "path": "/api/notes/by-doc",
      "returns": "map<doc_id, {total, open, done, deferred, last_action_at}>"
    }
  ],
  "cors_policy": {
    "allow_origin": "* (dev only)",
    "allow_credentials": true,
    "allow_methods": ["GET", "POST", "PATCH", "DELETE", "OPTIONS"]
  },
  "non_goals_this_batch": [
    "Per-note auth · notes inherit the authority of whoever can reach the service port",
    "Audit trail / transition history",
    "Multi-writer safety (locks / transactions)",
    "Server-sent events / websockets for live updates",
    "Notifications",
    "Theme clustering"
  ],
  "cross_references": {
    "note_schema":        "docs/assets/notes/document_note_schema.json",
    "status_matrix":      "docs/assets/notes/document_note_status_matrix.json",
    "backlog_model":      "docs/assets/notes/document_note_backlog_model.json",
    "service_app":        "docs/runtime/document-note-service/app.py",
    "service_readme":     "docs/runtime/document-note-service/README.md",
    "planning":           "docs/planning/document-note-backend.html"
  }
}
