squarecloud 0.1.0

Async Rust client for the SquareCloud API
Documentation
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

```bash
# Build
cargo build

# Run tests
cargo test

# Run a single test
cargo test <test_name>

# Format (max_width = 79, enforced by CI)
cargo fmt

# Check formatting without applying
cargo fmt --check

# Lint
cargo clippy

# Security audit
cargo deny check advisories
```

## Environment Variables

The library reads configuration via `dotenvy` at startup through a `LazyLock<Settings>`. A `.env` file (or environment) must provide:

- `API_TOKEN` — SquareCloud API token
- `BASE_URL` — SquareCloud API base URL

## Architecture

This is a Rust client library for the SquareCloud API. There are three layers:

### 1. `src/http/` — Transport layer

- **`http_client.rs` (`ApiClient`)** — the root entry point. Holds a `reqwest::Client` with the `Authorization` header pre-set. Exposes top-level operations (`me`, `upload_app`, `all_apps_status`, `create_database`, etc.) and factory methods that return resource handles (`app(id)`, `workspace(id)`, `database(id)`).
- **`endpoints/`** — one module per API domain (`apps`, `databases`, `workspaces`, `users`, `service`). Each module `impl Endpoint` with static constructors that use `EndpointBuilder` to fill path params and query strings.
- **`endpoints/types.rs` (`Endpoint` / `EndpointBuilder`)** — thin descriptor: HTTP method, resolved path string, optional JSON body. Built via a builder that substitutes `{param}` placeholders and appends query params.
- **`errors.rs`**`ApiErrorCode` (SCREAMING_SNAKE_CASE enum matching API responses), `ApiError` (transport vs. API variant), `CommitError` (wraps `ApiError` or `std::io::Error`).

### 2. `src/resources/` — Resource handles

Each resource struct (`AppResource`, `DatabaseResource`, `WorkspaceResource`, `FileResource`) holds an `Arc<ApiClient>` and an ID string. Methods on these structs call `client.request_endpoint(Endpoint::…)` and convert the `ApiResponse<T>` via `into_result_t()` or `into_bool_result()`.

`AppResource` can produce a `FileResource` via `.file(path)`. All resource constructors are called from `ApiClient` factory methods.

Methods that need multipart bodies (file upload/commit) call `Endpoint::request_builder(&client.http_client)` directly to attach a `Form`, then use `execute_request`.

### 3. `src/types/` — API response types

Plain `serde` structs/enums representing API payloads (`AppInfo`, `AppStatus`, `Deploy`, `Database`, `WorkspaceInfo`, etc.). No logic here.

### Response unwrapping convention

All API responses deserialize into `ApiResponse<T>` (untagged enum with `success: bool` + optional `response` or `code`). Callers chain `.into_result_t()` for typed data or `.into_bool_result()` for boolean outcomes.

## Commit Convention

Commits use `cz-conventional-gitmoji` (enforced by pre-commit hook). Format: `<emoji> <type>(<scope>): <description>`.

## Formatting

Line width is capped at 79 characters (`rustfmt.toml`). CI enforces this via `cargo fmt --check`.