# boarddata SDK — AI Consumer Guide

## What This Package Is

`boarddata` is a Python SDK for the BoardData V2 REST API. It provides typed methods
for managing corporate governance data: companies, persons, board/comex/auditor mandates,
compensations, assemblies, resolutions, ESG data, and sentinel analyses.

## Architecture

- **Mixin-based**: Each domain is a mixin class in `_companies.py`, `_persons.py`, etc.
- **Single facade**: `BoardDataClient` in `client.py` composes all mixins via multiple inheritance.
- **Base class**: `_base.py` provides OAuth2 Client Credentials authentication and HTTP transport (`_get`, `_post`, `_patch`, `_delete`).
- **Types**: `types/` contains TypedDict definitions for all API request/response shapes.

## Key Patterns

### Authentication
```python
from boarddata import BoardDataClient
client = BoardDataClient.from_env()  # reads BOARDDATA_* env vars
```

### CRUD Operations
Every domain follows the same pattern:
```python
client.list_companies(country="FR", page=1)     # GET with filters
client.get_company("uuid")                       # GET by ID
client.create_company("Name", "ISIN")            # POST
client.update_company("uuid", name="New Name")   # PATCH
client.delete_company("uuid")                    # DELETE
```

### Upsert Methods
Return `UpsertResult` (TypedDict with `action`, `id`, `data`):
```python
result = client.upsert_company("FR0000120271", "TotalEnergies")
result["action"]  # "created" or "updated"
result["id"]      # UUID
result["data"]    # full entity dict
```

### Pagination
```python
all_results = client.paginate(client.list_companies, country="FR")
```

## Domain Gotchas

### Board vs Comex Compensation
- **Board** (directors): uses `token_personal`, `stock_personal`, `attendance` fields
- **Comex** (executives): uses `fixed`, `variable`, `stock_options`, `performance_shares` fields
- These are completely different schemas. Do NOT mix them.

### Auditor Create is Server-Side Upsert
`create_auditor()` returns `AuditorCreateResponse` with `action` field — the server
may return "updated" if the mandate already exists.

### Assembly Resolutions Use Batch Endpoints
`create_assembly_resolution()` accepts a list and batch-upserts.

## File Layout
```
boarddata/
  __init__.py          # Public API exports
  _base.py             # Auth + HTTP transport
  _companies.py        # CompanyMixin
  _persons.py          # PersonMixin
  _directors.py        # DirectorMixin
  _comex.py            # ComexMixin
  _auditors.py         # AuditorMixin
  _documents.py        # DocumentMixin
  _assemblies.py       # AssemblyMixin
  _esg.py              # ESGMixin
  _sentinel.py         # SentinelMixin
  _utilities.py        # UtilitiesMixin
  client.py            # BoardDataClient facade
  cache.py             # FileTokenCache
  errors.py            # BoardDataError
  types/               # TypedDict definitions
    core.py            # Shared types (PaginatedResponse, UpsertResult, etc.)
    companies.py       # Company types
    persons.py         # Person types
    directors.py       # Director types
    comex.py           # Comex types
    auditors.py        # Auditor types
    documents.py       # Document types
    assemblies.py      # Assembly types
    esg.py             # ESG types
    sentinel.py        # Sentinel types
  tests/               # Unit tests
```
