# ToolKit Overview

## What ToolKit provides

- **Composable gears** discovered via `inventory`, initialized in dependency order.
- **Gateway as a gear** (e.g., `api-gateway`) that owns the Axum router and OpenAPI document.
- **Type-safe REST** via an operation builder that prevents half-wired routes at compile time.
- **Server-Sent Events (SSE)** with type-safe broadcasters and domain event integration.
- **OpenAPI 3.1** generation using `utoipa` with automatic schema registration for DTOs.
- **Standardized HTTP errors** with RFC-9457 `Problem` (implements `IntoResponse` directly).
- **Typed ClientHub** for in-process clients (resolve by interface type + optional scope).
- **Plugin architecture** via scoped ClientHub registration and GTS-based discovery (see `docs/TOOLKIT_PLUGINS.md`).
- **Lifecycle** helpers and wrappers for long-running tasks and graceful shutdown.
- **Lock-free hot paths** via atomic `Arc` swaps for read-mostly state.

## Core invariants (apply everywhere)

- **SDK pattern is the public API**: Use `<gear>-sdk` crate for traits, models, errors. Do not expose internals.
- **Secure-by-default DB access**: Use `SecureConn` + `AccessScope`. Gears cannot access raw database connections.
- **RFC-9457 errors everywhere**: Use `Problem` (implements `IntoResponse`). Do not use `ProblemResponse`.
- **Type-safe REST**: Use `OperationBuilder` with `.authenticated()` and `.standard_errors()`.
- **OData macros are in `toolkit-odata-macros`**: Use `toolkit_odata_macros::ODataFilterable`.
- **ClientHub registration**: `ctx.client_hub().register::<dyn MyGearApi>(api)`; `ctx.client_hub().get::<dyn MyGearApi>()?`.
- **Cancellation**: Pass `CancellationToken` to background tasks for cooperative shutdown.
- **GTS schema**: Use `gts_schema_with_refs_as_string()` for faster, correct schema generation.

## Golden path (quick reference)

```rust
// Gear registration
#[toolkit::gear(
    name = "my_gear",
    deps = ["foo", "bar"],
    capabilities = [db, rest],
    client = my_gear_sdk::MyGearApi,
)]
pub struct MyGear { /* ... */ }

// Secure DB access
let secure_conn = db.sea_secure();
let scope = toolkit_db::secure::AccessScope::for_tenant(ctx.tenant_id());
let users = secure_conn
    .find::<user::Entity>(&scope)
    .all(&secure_conn)
    .await?;

// ClientHub
ctx.client_hub().register::<dyn my_gear_sdk::MyGearApi>(api);
let api = ctx.client_hub().get::<dyn my_gear_sdk::MyGearApi>()?;

// Errors
impl From<DomainError> for Problem { /* ... */ }
fn handler() -> ApiResult<T> { /* ... */ }

// REST wiring
OperationBuilder::get("/users")
    .authenticated()
    .require_license_features::<License>([])
    .handler(handler)
    .json_response_with_schema::<UserDto>(openapi, StatusCode::OK, "Users")
    .standard_errors(openapi)
    .register(router, openapi);
```
