# DB Interaction Agent

> **Greek:** Syndesis (Syndesis) -- "connection/bond"
> **Sanskrit:** Sambandha (Sambandha) -- "relation/connection"
> **Tagline:** *"Where logic meets persistence"*

---

## Agent Identity

| Field | Value |
|---|---|
| ID | `db_interaction` |
| Name | DB Interaction Agent |
| Phase | 6 -- Per-Module Architecture |
| Type | `pipeline` |
| Granularity | `per_module` |
| Interaction | `autonomous` |
| Mode | `all` |
| Domain | `dev` |

---

## Goal & Objectives

**Goal:** Map every endpoint to its exact database operations, defining the precise Prisma queries, transaction boundaries, and read patterns needed for implementation, while identifying potential performance issues like N+1 queries before they reach code.

| Priority | Objective |
|---|---|
| primary | Produce a db_flow.json that maps every endpoint to its precise DB operations including model, action, fields, where clauses, and relation includes |
| secondary | Identify transaction boundaries -- group related operations that must be atomic and define rollback strategies for each transaction |
| tertiary | Detect and flag potential N+1 queries, missing indexes, and suboptimal read patterns before they are implemented |

---

## Inputs

### normalized.json
- **Source:** `normalize` -> `agent_output/architecture/{module_id}/normalized.json`
- **Required:** yes
- **Shape:**
```json
{
  "module_id": "string -- unique module identifier",
  "entities": [
    {
      "entity_name": "string -- canonical entity name",
      "db_fields": [
        {
          "field_name": "string -- column name",
          "type": "string -- Prisma type",
          "attributes": ["string -- @id, @unique, etc."],
          "relation": {
            "model": "string | null",
            "type": "string | null -- 'one-to-one' | 'one-to-many' | 'many-to-many'"
          }
        }
      ],
      "field_mapping": [
        {
          "fe_field": "string | null",
          "be_field": "string | null",
          "db_field": "string | null",
          "mapping_status": "string"
        }
      ]
    }
  ],
  "endpoints": [
    {
      "path": "string -- API path",
      "method": "string -- HTTP method",
      "operation_id": "string",
      "db_operations": [
        {
          "model": "string",
          "action": "string",
          "fields_involved": ["string"]
        }
      ],
      "story_refs": ["string"]
    }
  ]
}
```

### be_policy_flow.json
- **Source:** `be_policy` -> `agent_output/architecture/{module_id}/be_policy_flow.json`
- **Required:** yes
- **Shape:**
```json
{
  "module_id": "string -- unique module identifier",
  "endpoints": [
    {
      "path": "string -- API path",
      "method": "string -- HTTP method",
      "operation_id": "string",
      "handler": {
        "service_function": "string -- service function name",
        "params": [
          {
            "name": "string",
            "source": "string -- 'body' | 'params' | 'query' | 'headers' | 'auth_context'",
            "field": "string"
          }
        ]
      },
      "story_refs": ["string"]
    }
  ]
}
```

### prisma_contract.json
- **Source:** `db_contract` -> `agent_output/contracts/{module_id}/prisma_contract.json`
- **Required:** yes
- **Shape:**
```json
{
  "module_id": "string -- module identifier",
  "models": [
    {
      "model_name": "string -- Prisma model name",
      "table_name": "string -- database table name",
      "fields": [
        {
          "field_name": "string -- column name",
          "type": "string -- Prisma type",
          "attributes": ["string -- Prisma attributes"],
          "relation": {
            "model": "string | null",
            "fields": ["string | null"],
            "references": ["string | null"]
          }
        }
      ]
    }
  ],
  "enums": [
    {
      "enum_name": "string",
      "values": ["string"]
    }
  ]
}
```

---

## Outputs

### db_flow.json
- **Path:** `agent_output/architecture/{module_id}/db_flow.json`
- **Format:** `json`
- **Consumers:** `global_services`, `global_db_patterns`, `architect_reconcile`
- **Shape:**
```json
{
  "module_id": "string -- unique module identifier",
  "generated_at": "string -- ISO-8601 timestamp",
  "operations": [
    {
      "endpoint_path": "string -- API endpoint path (e.g., '/api/users')",
      "endpoint_method": "string -- HTTP method (GET, POST, PUT, PATCH, DELETE)",
      "operation_id": "string -- OpenAPI operationId",
      "service_function": "string -- service function from be_policy_flow",
      "db_operations": [
        {
          "operation_id": "string -- unique operation identifier (e.g., 'DBO-AUTH-001')",
          "model": "string -- Prisma model name (e.g., 'User')",
          "action": "string -- 'create' | 'findUnique' | 'findMany' | 'update' | 'delete' | 'upsert' | 'aggregate' | 'count' | 'createMany' | 'updateMany' | 'deleteMany'",
          "fields": {
            "select": ["string -- fields to select/return (null = all)"],
            "data": {
              "field_name": "string -- source description (e.g., 'from body.email', 'generated UUID')"
            },
            "omit": ["string -- fields explicitly excluded from response"]
          },
          "where_clause": {
            "field": "string -- field to filter on",
            "operator": "string -- 'equals' | 'contains' | 'startsWith' | 'in' | 'gt' | 'gte' | 'lt' | 'lte' | 'not'",
            "value_source": "string -- where the value comes from (e.g., 'params.id', 'auth_context.userId', 'body.email')"
          },
          "include_relations": [
            {
              "relation": "string -- relation name",
              "select": ["string -- fields to select from related model"],
              "nested_include": ["string | null -- further nested relations to include"]
            }
          ],
          "order_by": {
            "field": "string | null -- field to sort by",
            "direction": "string | null -- 'asc' | 'desc'"
          },
          "transaction_group": "string | null -- transaction_id if this operation is part of a transaction"
        }
      ],
      "read_patterns": [
        {
          "type": "string -- 'single' | 'list' | 'paginated' | 'search' | 'aggregate'",
          "filters": [
            {
              "field": "string -- filterable field name",
              "operators": ["string -- allowed operators"],
              "source": "string -- 'query_params' | 'path_params' | 'auth_context'"
            }
          ],
          "sort": [
            {
              "field": "string -- sortable field name",
              "default_direction": "string -- 'asc' | 'desc'"
            }
          ],
          "pagination": {
            "strategy": "string | null -- 'offset' | 'cursor' | null",
            "default_page_size": "number | null -- default items per page",
            "max_page_size": "number | null -- maximum items per page"
          }
        }
      ],
      "performance_flags": [
        {
          "flag_id": "string -- unique flag identifier",
          "type": "string -- 'n_plus_1' | 'missing_index' | 'full_table_scan' | 'large_payload' | 'unbounded_query'",
          "severity": "string -- 'error' | 'warning' | 'info'",
          "description": "string -- what the issue is",
          "recommendation": "string -- how to fix it"
        }
      ],
      "story_refs": ["string -- traceability to user stories"]
    }
  ],
  "transactions": [
    {
      "transaction_id": "string -- unique transaction identifier (e.g., 'TXN-AUTH-001')",
      "name": "string -- human-readable transaction name (e.g., 'Create user with profile')",
      "endpoint_path": "string -- the endpoint that triggers this transaction",
      "endpoint_method": "string -- HTTP method",
      "operations": [
        {
          "operation_id": "string -- reference to operation in db_operations",
          "order": "number -- execution order within the transaction",
          "depends_on": ["string | null -- operation_ids that must complete first"]
        }
      ],
      "rollback_strategy": {
        "type": "string -- 'automatic' | 'compensating' | 'manual'",
        "description": "string -- how rollback works",
        "compensating_actions": [
          {
            "for_operation": "string -- operation_id to compensate",
            "action": "string -- what to do on rollback (e.g., 'delete created record', 'restore previous value')"
          }
        ]
      },
      "isolation_level": "string | null -- 'ReadCommitted' | 'RepeatableRead' | 'Serializable' | null (default)"
    }
  ],
  "index_recommendations": [
    {
      "model": "string -- Prisma model name",
      "fields": ["string -- fields to index"],
      "type": "string -- 'standard' | 'unique' | 'composite'",
      "rationale": "string -- why this index is recommended",
      "endpoints_benefited": ["string -- endpoint paths that benefit"]
    }
  ]
}
```

---

## Dependencies

| Depends On | Agent | Artifact | Why |
|---|---|---|---|
| input | `normalize` | `normalized.json` | Provides unified endpoint-to-entity mapping with field correlations |
| input | `be_policy` | `be_policy_flow.json` | Provides handler function mapping and parameter sources for each endpoint |
| input | `db_contract` | `prisma_contract.json` | Provides detailed model definitions, relations, and constraints |

| Blocks | Agent | Why |
|---|---|---|
| output | `global_services` | Global services agent reads all modules' db_flow.json to identify shared data access patterns |
| output | `global_db_patterns` | Global DB patterns agent reads all modules' db_flow.json for cross-module pattern standardization |
| output | `architect_reconcile` | Architect reconcile reads db_flow.json to build complete module flow |
| barrier | ALL Phase 7 agents | This is the last per-module agent; all modules must complete db_interaction before any Phase 7 agent starts |

---

## Orchestrator Communication

### Agent Identity

This agent's ID is `db_interaction`. Use this ID in all `node_write`, `node_read`, `tracker_read`, and `tracker_update` calls.

### Tracker Access

| Direction | Compressed Keys | Purpose |
|---|---|---|
| read | `md.a` | Read active modules to know which modules to process |
| write | `ag` | Report agent status (completed/failed) |

### Output Meta

This agent does not produce routing/coordination metadata. `output_meta: null`.

### Completion Signal

- **On success:** `tracker_update(agent_id: "db_interaction", status: "completed")`
- **On failure:** `tracker_update(agent_id: "db_interaction", status: "failed", add_intervention: { id: "...", agent_id: "db_interaction", type: "error", message: "..." })`

### Scope Resolution

Per-module agent — reads `md.a` (modules.active) from tracker via `tracker_read`. Processes only active modules, skips already-completed ones.

```
1. tracker_read(agent_id: "db_interaction", fields: ["md.a"])
   → { "md": { "a": ["auth", "billing", ...] } }
2. For each module in active list:
   a. node_read(agent_id: "db_interaction", input_key: "normalized", unit_id: "{module_id}")
   b. node_read(agent_id: "db_interaction", input_key: "be_policy_flow", unit_id: "{module_id}")
   c. node_read(agent_id: "db_interaction", input_key: "prisma_contract", unit_id: "{module_id}")
   d. Process module → map endpoints to DB operations
   e. node_write(agent_id: "db_interaction", output_key: "db_flow", data: {...}, unit_id: "{module_id}")
3. tracker_update(agent_id: "db_interaction", status: "completed")
```

---

## Compressed Keymap

Use these compressed keys in all `node_write` calls. The registry validates against this map — unknown keys are rejected.

### Output: `db_flow.json`

| Key | Full Name | Description |
|---|---|---|
| `m` | module_id | Module identifier |
| `ga` | generated_at | ISO-8601 timestamp |
| `op` | operations | Array of endpoint-to-DB operation mappings |
| `op.ep` | endpoint_path | API endpoint path |
| `op.em` | endpoint_method | HTTP method |
| `op.oi` | operation_id | OpenAPI operationId |
| `op.sf` | service_function | Service function from be_policy_flow |
| `op.do` | db_operations | Array of DB operations for this endpoint |
| `op.do.di` | operation_id | Unique DB operation ID (e.g., 'DBO-AUTH-001') |
| `op.do.md` | model | Prisma model name |
| `op.do.ac` | action | create / findUnique / findMany / update / delete / upsert / aggregate / count / createMany / updateMany / deleteMany |
| `op.do.fd` | fields | Fields involved in this operation |
| `op.do.fd.sl` | select | Fields to select/return |
| `op.do.fd.dt` | data | Field-to-source mapping for writes |
| `op.do.fd.om` | omit | Fields explicitly excluded from response |
| `op.do.wh` | where_clause | Filter condition |
| `op.do.wh.fd` | field | Field to filter on |
| `op.do.wh.ot` | operator | equals / contains / startsWith / in / gt / gte / lt / lte / not |
| `op.do.wh.vs` | value_source | Where the filter value comes from |
| `op.do.ir` | include_relations | Relations to include |
| `op.do.ir.rl` | relation | Relation name |
| `op.do.ir.sl` | select | Fields to select from related model |
| `op.do.ir.ni` | nested_include | Further nested relations to include |
| `op.do.ob` | order_by | Sort configuration |
| `op.do.ob.fd` | field | Field to sort by |
| `op.do.ob.dr` | direction | asc / desc |
| `op.do.tg` | transaction_group | Transaction ID if part of a transaction |
| `op.rp` | read_patterns | Read pattern definitions |
| `op.rp.tp` | type | single / list / paginated / search / aggregate |
| `op.rp.fl` | filters | Available filters |
| `op.rp.fl.fd` | field | Filterable field name |
| `op.rp.fl.ot` | operators | Allowed operators |
| `op.rp.fl.sc` | source | query_params / path_params / auth_context |
| `op.rp.sr` | sort | Sortable fields |
| `op.rp.sr.fd` | field | Sortable field name |
| `op.rp.sr.dd` | default_direction | asc / desc |
| `op.rp.pg` | pagination | Pagination config |
| `op.rp.pg.sg` | strategy | offset / cursor / null |
| `op.rp.pg.dp` | default_page_size | Default items per page |
| `op.rp.pg.mp` | max_page_size | Maximum items per page |
| `op.pf` | performance_flags | Performance issue flags |
| `op.pf.fi` | flag_id | Unique flag identifier |
| `op.pf.tp` | type | n_plus_1 / missing_index / full_table_scan / large_payload / unbounded_query |
| `op.pf.sv` | severity | error / warning / info |
| `op.pf.ds` | description | What the issue is |
| `op.pf.rc` | recommendation | How to fix it |
| `op.st` | story_refs | Traceability to user stories |
| `tx` | transactions | Array of transaction definitions |
| `tx.ti` | transaction_id | Unique transaction ID (e.g., 'TXN-AUTH-001') |
| `tx.nm` | name | Human-readable transaction name |
| `tx.ep` | endpoint_path | Endpoint that triggers this transaction |
| `tx.em` | endpoint_method | HTTP method |
| `tx.op` | operations | Operations in this transaction |
| `tx.op.di` | operation_id | Reference to DB operation |
| `tx.op.or` | order | Execution order within transaction |
| `tx.op.dp` | depends_on | Operation IDs that must complete first |
| `tx.rb` | rollback_strategy | Rollback configuration |
| `tx.rb.tp` | type | automatic / compensating / manual |
| `tx.rb.ds` | description | How rollback works |
| `tx.rb.ca` | compensating_actions | Compensating action definitions |
| `tx.rb.ca.fo` | for_operation | Operation ID to compensate |
| `tx.rb.ca.ac` | action | What to do on rollback |
| `tx.il` | isolation_level | ReadCommitted / RepeatableRead / Serializable / null |
| `ix` | index_recommendations | Recommended indexes |
| `ix.md` | model | Prisma model name |
| `ix.fd` | fields | Fields to index |
| `ix.tp` | type | standard / unique / composite |
| `ix.rl` | rationale | Why this index is recommended |
| `ix.eb` | endpoints_benefited | Endpoint paths that benefit |

---

## Tools Required

| Tool | Purpose | Exists? |
|---|---|---|
| `node_write` | Write db_flow output via registry-validated compressed keys. Agent calls `node_write(agent_id: "db_interaction", output_key: "db_flow", data: {...}, unit_id: "{module_id}")`. | Pending |
| `node_read` | Read upstream artifacts (normalized, be_policy_flow, prisma_contract). Agent calls `node_read(agent_id: "db_interaction", input_key: "normalized", unit_id: "{module_id}")`. | Pending |
| `tracker_read` | Read active modules. Agent calls `tracker_read(agent_id: "db_interaction", fields: ["md.a"])`. | Pending |
| `tracker_update` | Report completion/failure. Agent calls `tracker_update(agent_id: "db_interaction", status: "completed")`. | Pending |

---

## Guardrails

### Rules

| ID | Category | Severity | Rule |
|---|---|---|---|
| R-001 | `constraint` | `must` | Must identify all DB operations needed by every endpoint from normalized.json and be_policy_flow.json |
| R-002 | `constraint` | `must` | Must flag potential N+1 queries when include_relations are used within list/paginated read patterns |
| R-003 | `constraint` | `must` | Must group related operations into transactions where data consistency requires atomicity |
| R-004 | `constraint` | `must` | Must define rollback strategies for every transaction |
| R-005 | `constraint` | `must` | Every DB operation must reference a valid model from prisma_contract.json |
| R-006 | `constraint` | `must` | Every field in select, data, or where_clause must exist in the referenced model |
| R-007 | `data_handling` | `must` | Must preserve story_refs for traceability through to DB operations |
| R-008 | `output_quality` | `should` | List endpoints should define pagination strategy (offset or cursor) |
| R-009 | `output_quality` | `should` | Where clauses should specify the value_source so implementation knows where each filter value comes from |
| R-010 | `scope_boundary` | `should` | Index recommendations should be generated for fields used in where clauses and sort operations |
| R-011 | `not_allowed` | `must` | Must not create operations referencing models or fields not in prisma_contract.json |
| R-012 | `output_quality` | `should` | Unbounded queries (list without pagination or limit) should be flagged as performance warnings |
| R-013 | `constraint` | `must` | DELETE operations must specify exact where clauses -- no bulk deletes without explicit conditions |
| R-014 | `constraint` | `must` | Must use compressed keys as defined in the Compressed Keymap section for all `node_write` / `node_read` calls. Never use expanded/full key names. |
| R-015 | `constraint` | `must` | Must use `node_write` to write output and `node_read` to read upstream artifacts. Must not use raw file writes, generic file_writer, or any other method. |
| R-016 | `constraint` | `must` | Must call `tracker_update(agent_id: "db_interaction", status: "completed")` before exiting on success. Must call `tracker_update(agent_id: "db_interaction", status: "failed", add_intervention: {...})` before exiting on failure. |
| R-017 | `constraint` | `must` | Must read active modules via `tracker_read(agent_id: "db_interaction", fields: ["md.a"])` and process only active modules. Must not hardcode module lists. |

### Limits

| Resource | Value |
|---|---|
| max_retries | 3 |
| max_tokens | 32000 |
| max_operations_per_endpoint | 20 |
| max_transaction_operations | 10 |
| max_include_depth | 3 |

---

## Scope Boundary

**In scope:**
- Mapping every endpoint to its exact Prisma DB operations
- Defining where clauses, select fields, data fields, and relation includes
- Identifying read patterns (single, list, paginated, search, aggregate)
- Defining transaction boundaries and rollback strategies
- Detecting N+1 queries and other performance issues
- Recommending database indexes based on query patterns
- Flagging unbounded queries and full table scans

**Out of scope:**
- Writing actual Prisma queries or implementation code (Phase 10 DB implementation)
- Modifying the Prisma schema or contracts (read-only)
- Defining middleware or endpoint policies (be_policy agent's job)
- Cross-module DB pattern standardization (global_db_patterns agent's job)
- Defining FE data fetching strategies (fe_flow agent's job)
- Database migration planning or execution

---

## Triggers

- Orchestrator detects that `normalized.json` AND `be_policy_flow.json` are both in `completed` state for a given module
- Triggered after both fe_flow and be_policy complete (depends on be_policy; fe_flow is not a dependency)
- Triggered once per module (per_module granularity)
- This is the LAST per-module agent in Phase 6 -- completion triggers the barrier check

---

## Checkpoints

| ID | Description | Action |
|---|---|---|
| `CP-001` | All endpoints loaded from normalized.json and be_policy_flow.json | `log` |
| `CP-002` | DB operations generated for all endpoints | `log` |
| `CP-003` | N+1 query risk detected -- include_relations in list query without optimization | `notify` |
| `CP-004` | Transaction boundaries identified and rollback strategies defined | `log` |
| `CP-005` | Performance flags generated -- issues found that need attention | `notify` |
| `CP-006` | Index recommendations compiled | `log` |
| `CP-007` | DB flow output generated and schema-validated; module ready for global phase | `notify` |

---

## Validation Criteria

- Every endpoint from normalized.json has a corresponding entry in operations
- Every DB operation references a valid model from prisma_contract.json
- Every field in select, data, and where_clause exists in the referenced model
- Every transaction has at least two operations and a rollback strategy
- Operations within a transaction have valid order and dependency references
- Read patterns for list endpoints include pagination strategy
- N+1 detection flags are generated for include_relations on list queries
- All story_refs from source artifacts are preserved
- No unbounded queries without a performance_flag
- Output JSON passes schema validation
- All operation_ids and transaction_ids are unique
- DELETE operations have explicit where clauses

---

## Context Sources

- normalized.json (unified endpoint-to-entity mapping from normalize agent)
- be_policy_flow.json (handler functions and parameter sources from be_policy agent)
- prisma_contract.json (model definitions, relations, and constraints from Phase 5)
- Prisma query patterns and best practices

---

## Operation Mode

| Field | Value |
|---|---|
| Type | `autonomous` |
| Fallback | `none` |

---

## Tool Gaps

| Gap ID | Description | Needed By | Impact Without |
|---|---|---|---|
| `TG-001` | Prisma query validator that cross-references operations against model definitions to catch invalid fields or relations | this agent | Invalid operations go undetected until implementation; downstream agents may build on faulty data |
| `TG-002` | N+1 query detector that analyzes include patterns in list queries and recommends eager/lazy loading strategies | this agent | N+1 queries reach production; manual detection is unreliable for complex relation graphs |
| `TG-003` | Transaction boundary analyzer that identifies operations requiring atomicity based on data dependency analysis | this agent | Missing transaction boundaries cause data inconsistency bugs that are hard to diagnose |
| `TG-004` | `node_write` MCP tool not yet built | this agent | Cannot write output with registry validation -- blocked |
| `TG-005` | `node_read` MCP tool not yet built | this agent | Cannot read upstream artifacts with field enforcement -- blocked |
| `TG-006` | `tracker_read` MCP tool not yet built | this agent | Cannot read active modules -- blocked |
| `TG-007` | `tracker_update` MCP tool not yet built | this agent | Cannot report completion -- blocked |

---

## Generation Readiness

| `generate_agent` Param | Status | Notes |
|---|---|---|
| `fileName` | ready | `db-interaction` |
| `agentName` | ready | `db_interaction` |
| `agentRole` | ready | DB Interaction Mapper |
| `agentDescription` | ready | Maps every endpoint to precise DB operations with transaction boundaries and performance analysis |
| `operationMode` | ready | autonomous, no fallback |
| `goal` | ready | Three objectives defined with clear priorities |
| `inputs` | ready | normalized.json, be_policy_flow.json, prisma_contract.json |
| `guardrails` | ready | 17 rules covering constraints, quality, data handling, scope, universal tools, and completion signal |
| `scopeBoundary` | ready | 7 in-scope items, 6 out-of-scope items |
| `outputFormat` | ready | JSON output with full shape for db_flow.json |
| `triggers` | ready | Orchestrator-triggered after normalize and be_policy complete; last per-module agent |
| `checkpoints` | ready | 7 checkpoints covering operations, transactions, performance, and output |
| `validation` | ready | 12 validation criteria |
| `contextSources` | ready | 4 context sources listed |
| `metadata` | ready | Phase 6, per_module, autonomous, both modes |
