# API Documentation

## Internal Python APIs

### run_cronjob_every_10mins.py — Public Functions

#### `get_normalized_time() -> datetime`
- **Purpose**: Round down current time to nearest 10-minute boundary
- **Returns**: datetime object with minute floored to 0 or 10

#### `matches_schedule(job: dict, current_time: datetime) -> bool`
- **Purpose**: Check if a job's cron expression matches the current time
- **Parameters**: job dict with `schedule.expr`, current_time datetime
- **Returns**: True if job should run now

#### `parse_cron_field(field: str) -> set | str`
- **Purpose**: Parse cron field (minute/hour/day/dow) into set of matching values
- **Supports**: `*`, `*/n`, `n,m`, `n-m` formats
- **Returns**: set of integers or `"*"` for any

#### `load_config(agent_role: str) -> dict | None`
- **Purpose**: Load cronjob.json config for a given role
- **Searches**: `cronjobs/{role}/cronjob.json`, `cronjobs/{role}/_config/jobs.json`
- **Returns**: config dict or None

#### `get_job_command(agent_role: str, job_name: str, config: dict) -> str | None`
- **Purpose**: Get the shell command for a named job
- **Returns**: command string or None

#### `execute_job(command: str, job_name: str) -> dict`
- **Purpose**: Execute a job command and capture results
- **Behavior**: Sources ~/.bashrc for env vars, sets CRONJOB_*/MINIMAX_*/GITHUB_* vars
- **Returns**: dict with `success`, `returncode`, `stdout`, `stderr`
- **Timeout**: 600 seconds (10 minutes)

#### `log_to_file(agent_role: str, message: str) -> None`
- **Purpose**: Append timestamped message to daily log file
- **Location**: `~/CRONJOB_LOGS/cron_{YYYYMMDD}.log`

#### `send_feishu_notification(failed_jobs: list, agent_role: str) -> None`
- **Purpose**: Send Feishu alert for failed cronjobs
- **Auth**: Role-specific app credentials from env vars
- **Recipient**: Hardcoded Wang Bing (ou_f442e20fd980363ea486b5a6cd8d2a2f)

### run_cronjob_every_10mins.py — CLI Interface

```bash
python3 run_cronjob_every_10mins.py <agent_role> [cronjob_name]

# Examples:
python3 run_cronjob_every_10mins.py team-workflow      # Run scheduled jobs
python3 run_cronjob_every_10mins.py team-workflow ai-news  # Debug: run immediately
```

## External API Integrations

### Feishu Open API

#### POST /open-apis/auth/v3/tenant_access_token/internal
- **Purpose**: Get tenant access token for API calls
- **Request**: `{"app_id": "...", "app_secret": "..."}`
- **Response**: `{"tenant_access_token": "...", "expire": ...}`

#### POST /open-apis/im/v1/messages?receive_id_type=open_id
- **Purpose**: Send Feishu messages
- **Auth**: Bearer token from tenant_access_token
- **Request**: `{"receive_id": "...", "msg_type": "text", "content": "{\"text\":\"...\"}"}`

### GitHub API (App Authentication)

#### POST /app/installations/{installation_id}/access_tokens
- **Purpose**: Generate installation access token from GitHub App
- **Auth**: JWT signed with private key
- **Response**: `{"token": "...", "expires_at": "..."}`

### Jira REST API
- **Base URL**: `https://{domain}.atlassian.net/rest/api/3/`
- **Auth**: Basic auth with email + API token
- **Standard endpoints**: `/issue`, `/search`, `/project`

### Grafana API
- **Base URL**: Configured per deployment
- **Auth**: Bearer token (api_key)
- **Usage**: Clinic API for metrics access

## Data Models

### cronjob.json Schema
```json
{
  "version": 1,
  "jobs": [
    {
      "name": "string",
      "command": "string (shell command)",
      "schedule": "string (cron5-field format)",
      "description": "string"
    }
  ],
  "note": "string (optional)",
  "crontab_entry": "string (optional)"
}
```

### Job Execution Result
```python
{
    "success": bool,
    "returncode": int,
    "stdout": str,
    "stderr": str
}
```

### Feishu Message Payload
```python
{
    "receive_id": str,        # open_id or chat_id
    "msg_type": str,          # "text", "interactive", etc.
    "content": str            # JSON string of message body
}
```
