# API

## Endpoints

| Method | Path | Description |
| --- | --- | --- |
| GET | `/` | Service status |
| GET | `/healthz` | Liveness probe |
| GET | `/readyz` | Readiness probe (Redis PING, MongoDB ping, readable git workspace) |
| GET | `/version` | Service version |
| GET | `/parse-jobs/{job_id}` | Parse job status |
| GET | `/artifacts/{artifact_id}` | Graph artifact metadata |
| GET | `/diagnostics/{job_id}` | Parser diagnostics for a job |

## Response shapes

### `GET /parse-jobs/{job_id}`

**200**

```json
{
  "job_id": "job_snap_01_a1b2c3d4",
  "repo_id": "ad/example",
  "snapshot_id": "snap_01",
  "commit_sha": "abc123",
  "file_path": "internal/config/config.go",
  "language": "go",
  "status": "completed",
  "artifact_id": "art_snap_01_deadbeef"
}
```

`status` is one of: `pending`, `running`, `completed`, `failed`, `skipped`.  
`artifact_id` is present when the job completed and an artifact was saved.

**404**

```json
{
  "error": "not_found",
  "message": "parse job not found"
}
```

### `GET /artifacts/{artifact_id}`

Returns metadata only (not the full graph nodes/edges payload).

**200**

```json
{
  "artifact_id": "art_snap_01_deadbeef",
  "schema_version": "v1",
  "repo_id": "ad/example",
  "snapshot_id": "snap_01",
  "commit_sha": "abc123",
  "file_path": "internal/config/config.go",
  "node_count": 12,
  "edge_count": 18,
  "artifact_uri": "file:///data/artifacts/art_snap_01_deadbeef.json"
}
```

**400** — invalid artifact ID format

```json
{
  "error": "invalid_request",
  "message": "invalid artifact id"
}
```

**404**

```json
{
  "error": "not_found",
  "message": "artifact not found"
}
```

### `GET /diagnostics/{job_id}`

**200** — known job (empty array when the job succeeded without diagnostics)

```json
{
  "job_id": "job_snap_01_a1b2c3d4",
  "diagnostics": [
    {
      "code": "syntax_error",
      "message": "main.go:3:1: expected declaration, found 'func'",
      "severity": "error",
      "file_path": "main.go",
      "line": 3
    }
  ]
}
```

**404**

```json
{
  "error": "not_found",
  "message": "parse job not found"
}
```

## Environment Variables

| Variable | Default (`ENVIRONMENT=local`) | Description |
| --- | --- | --- |
| `HOST` | `0.0.0.0` | Bind host |
| `PORT` | `6002` | Bind port |
| `LOG_LEVEL` | `info` | Log level |
| `ENVIRONMENT` | `local` | Runtime environment |
| `REDIS_URL` | `redis://localhost:6379` | Redis connection for stream consumers/publishers |
| `REDIS_STREAM_PREFIX` | (empty) | Optional prefix for stream names (e.g. `staging` → `staging.files.changed`) |
| `GIT_WORKSPACE_PATH` | `./data/repos` | Repo Sync clone directory; created on startup if missing; `/readyz` checks readable |
| `ARTIFACT_STORE_PATH` | `./data/artifacts` | Local graph artifact JSON storage |
| `PARSER_WORKERS` | `runtime.NumCPU()` | Bounded parse worker pool size (must be `>= 1` if set) |
| `PARSER_VERSION` | `v0.1.0` | Version emitted on `graph.artifact.ready` events |

When `ENVIRONMENT` is not `local`, `REDIS_URL`, `ARTIFACT_STORE_PATH`, and `GIT_WORKSPACE_PATH` are required.

See [`env.example`](../env.example) for a local template.
