port-sdk 0.1.0

Rust SDK for Port APIs.
Documentation
# Architecture Overview

This document explains the planned structure of the Port SDK crate. Read through it before picking up items from `TODO.md`.

## High-Level Design

```
┌────────────────────┐
│ PortClient         │  <-- public entry point
├────────────────────┤
│ - reqwest::Client  │
│ - base Url         │
│ - auth token       │
└────────────────────┘
┌────────────────────┐
│ API modules        │  <-- grouped by resource (Blueprints, Entities, etc.)
└────────────────────┘
┌────────────────────┐
│ Data models        │  <-- serde structs generated from Swagger schema
└────────────────────┘
```

### `PortClient`

- Wraps a configured `reqwest::Client`.
- Applies bearer authentication to every outgoing request.
- Exposes async helpers (`get`, `post`, `patch`, `delete`, etc.).
- Performs response status validation and converts failures into `PortError`.
- Supports configuration via `PortConfig`/`PortClientBuilder`, including region selection, explicit base URLs, proxy settings, and retry policies.
- Delegates credential handling to pluggable token providers (`AuthStrategy`) so OAuth client credentials, static tokens, or custom providers can be used interchangeably.
- Emits resource bookkeeping events through an optional `ResourceTracker` so integration tests can clean up leaked data.

### API Modules (`src/apis/`)

- Each module maps to a logical group of Port endpoints (e.g., `blueprints`, `entities`, `integrations`).
- Functions accept typed request payloads and return typed responses.
- API modules depend only on `PortClient` and types from `src/types/`.

### Data Models (`src/types/`)

- Generated (or hand-crafted) structs/enums that mirror the Swagger schema.
- Derive `serde::Serialize`/`Deserialize` so they work seamlessly with `reqwest`.
- Apply `#[serde(rename_all = "...")]` to match API casing conventions.
- Keep strong typing for IDs, timestamps, and enums to prevent misuse.
- Newtypes such as `BlueprintId` and `EntityId` prevent mixing identifiers across resources.
- `build.rs` validates the schema checksum at compile time; regenerate types after updating `schemas/port.swagger.json`.

### Error Handling

- `PortError::Http` captures transport-level issues (`reqwest::Error`).
- `PortError::Api` stores the HTTP status code and response body for debugging.
- `PortError::Serde` surfaces JSON decoding/encoding errors.
- Consider adding `PortError::RateLimited` once retry logic lands to expose retry-after hints.

## Security Considerations

- Never log authentication tokens; provide helper methods that redact them if needed.
- Default to TLS via `reqwest`'s `rustls-tls` feature (already enabled).
- When adding retries, cap the maximum backoff and respect server-provided retry headers.
- Use `cargo audit` before releases to catch vulnerable dependencies.

## Extensibility

- Leave room for supporting both async and blocking clients (feature-gated via `blocking`).
- Consider optional middleware hooks (e.g., request/response interceptors) for advanced users.
- Support pagination and filtering by returning iterator-like wrappers or builder patterns.

## File Map (Target State)

- `src/lib.rs` – orchestrates module exports and feature gating.
- `src/client.rs` – HTTP client implementation.
- `src/error.rs` – error definitions.
- `src/types/` – nested modules for each resource type.
- `src/apis/` – resource-specific API functions; may use submodules.
- `examples/` – runnable demos showcasing common tasks (to be added).
- `tests/` – integration tests hitting mocked servers or the real API (behind opt-in flag).

## Next Steps

Consult `TODO.md` for the concrete tasks needed to reach this target architecture.