# Contract Tool (OpenAPI/JSON Schema) - Documentation

## Overview

Contract Tool validates OpenAPI 3.x specifications and detects breaking changes between API versions. Essential for release gates and API governance.

## Integration

### Tool Definition

Registered in `services/router/tool_manager.py`:

```python
{
    "type": "function",
    "function": {
        "name": "contract_tool",
        "description": "📜 Перевірка OpenAPI контрактів...",
        "parameters": {...}
    }
}
```

### RBAC Configuration

Added to `FULL_STANDARD_STACK` in `services/router/agent_tools_config.py`.

## Request Format

### `POST /v1/tools/contract-check`

```json
{
  "action": "lint_openapi | diff_openapi | generate_client_stub",
  "inputs": {
    "format": "openapi_json | openapi_yaml",
    "base": {
      "source": "text",
      "value": "..."
    },
    "head": {
      "source": "text", 
      "value": "..."
    }
  },
  "options": {
    "fail_on_breaking": true,
    "strict": true,
    "max_chars": 800000,
    "service_name": "my-service"
  }
}
```

## Actions

### 1. lint_openapi

Static quality checks on OpenAPI specification.

**Example:**
```json
{
  "action": "lint_openapi",
  "inputs": {
    "format": "openapi_yaml",
    "base": {
      "source": "text",
      "value": "openapi: 3.0.0\npaths:\n  /users:\n    get:\n      operationId: getUsers..."
    }
  }
}
```

**Lint Rules:**

| Severity | Rule | Description |
|----------|------|-------------|
| Error | Missing operationId | Every endpoint must have operationId |
| Warning | Missing requestBody | POST/PUT should have requestBody |
| Warning | No 2xx response | Success responses required |
| Warning | Unresolved $ref | External references not allowed |
| Info | Missing description | Critical endpoints need descriptions |

### 2. diff_openapi

Compare two OpenAPI specs and classify changes.

**Breaking Changes:**

| Type | Description |
|------|-------------|
| endpoint_removed | Endpoint or method removed |
| param_removed | Parameter removed |
| required_added | Required parameter/field added |
| required_field_added | Required schema field added |
| response_shape_changed | Response schema changed |
| auth_changed | Auth requirements changed |
| enum_narrowed | Enum values removed |
| schema_incompatible | Type changed |

**Non-Breaking Changes:**

| Type | Description |
|------|-------------|
| endpoint_added | New endpoint |
| param_optional_added | Optional parameter added |
| description_updated | Description changed |
| schema_extended | Optional fields added |

**Example:**
```json
{
  "action": "diff_openapi",
  "inputs": {
    "format": "openapi_yaml",
    "base": {"source": "text", "value": "..."},
    "head": {"source": "text", "value": "..."}
  },
  "options": {
    "fail_on_breaking": true
  }
}
```

### 3. generate_client_stub

Generate Python client stub from OpenAPI spec.

**Example:**
```json
{
  "action": "generate_client_stub",
  "inputs": {
    "format": "openapi_yaml",
    "base": {"source": "text", "value": "..."}
  }
}
```

**Response:**
```json
{
  "success": true,
  "data": {
    "language": "python",
    "client_stub": "class UserAPIClient:\n    def getUsers(self): ...",
    "info": {"title": "User API", "version": "1.0.0", "endpoints": 5}
  }
}
```

## Response Format

```json
{
  "status": "succeeded",
  "data": {
    "summary": "🚫 2 breaking change(s) detected",
    "breaking": [
      {
        "id": "OAC-001",
        "type": "endpoint_removed",
        "path": "/v1/users",
        "method": "DELETE",
        "location": "paths./v1/users.delete",
        "why_it_breaks": "Endpoint was removed",
        "suggested_fix": "Deprecate instead of removing"
      }
    ],
    "non_breaking": [...],
    "lint": [...],
    "compat_score": {
      "breaking_count": 2,
      "warnings": 1,
      "coverage": 75
    },
    "release_checklist": [...]
  }
}
```

## Security Features

### Logging Policy
- **NEVER** logs full OpenAPI specs
- Only logs: hash (first 16 chars), spec size, service name

### Limits
- `max_chars`: Default 800KB
- Parse timeout: 30 seconds

## Release Checklist

Generated automatically for diff:

1. Breaking changes detected → requires version bump
2. Communicate changes to API consumers
3. Update API documentation
4. Update client SDKs
5. Test with existing clients

## Example Usage

### Check for Breaking Changes Before Release
```
"Перевір чи є breaking changes в API: base=spec-v1.yaml, head=spec-v2.yaml"
```

### Validate OpenAPI Quality
```
"Зроби lint мого OpenAPI спека"
```

### Generate Client SDK
```
"Згенеруй Python клієнта для мого API"
```

## Testing

```bash
pytest tools/contract_tool/tests/test_contract_tool.py -v
```

Test coverage:
- Endpoint removed → breaking
- Required field added → breaking
- Optional field added → non-breaking
- Enum narrowed → breaking
- fail_on_breaking option
- max_chars limit enforcement
- Python client stub generation
