Add a browsable mdBook developer guide under docs/dev-guide/ covering the full PiCloud v1.1.9 surface for developers building on the platform: - Guide: introduction, 10-minute quickstart, core concepts, writing scripts - Tutorials: 5 end-to-end example apps (URL shortener, webhook receiver, TODO API with auth, scheduled report, file-upload service) + feature matrix - SDK reference: kv/docs/files, pubsub/queue, http, email, users, secrets, invoke/retry/dead_letters, stdlib, ctx & events - HTTP API reference: every /api/v1 endpoint, auth, and capability - CLI reference: the `pic` client + the server admin recovery command - Config: every PICLOUD_* env var, capabilities & roles - Deployment: Docker Compose, bare binary, Caddy/TLS, production checklist - Operations: security, best practices, troubleshooting Every example was built and run against a live instance; SDK signatures, endpoint paths, and env vars were verified against source. Build the site with `mdbook serve docs/dev-guide`. A pointer is added to README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
63 lines
2.6 KiB
Markdown
63 lines
2.6 KiB
Markdown
# Apps & domains
|
|
|
|
Apps are tenants; domains route hosts to apps. See [Core concepts](../../guide/concepts.md#apps).
|
|
|
|
## Apps
|
|
|
|
| Method & path | Capability | Notes |
|
|
|---|---|---|
|
|
| `GET /api/v1/admin/apps` | authenticated | lists apps the caller can see (members: only theirs) |
|
|
| `POST /api/v1/admin/apps` | `InstanceCreateApp` (owner/admin) | create |
|
|
| `GET /api/v1/admin/apps/{id_or_slug}` | `AppRead` | one app |
|
|
| `PATCH /api/v1/admin/apps/{id_or_slug}` | `AppAdmin` | update name/description/slug |
|
|
| `DELETE /api/v1/admin/apps/{id_or_slug}` | `AppAdmin` | delete (cascades scripts, routes, data) |
|
|
| `POST /api/v1/admin/apps/{id_or_slug}/slug:check` | `AppAdmin` | `{"new_slug":"…"}` → `{ok, conflict_kind?, current_app?, reason?}` |
|
|
|
|
Create:
|
|
|
|
```sh
|
|
curl -X POST $PICLOUD/api/v1/admin/apps -H "Authorization: Bearer $TOKEN" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"slug":"demo","name":"Demo App","description":"…"}'
|
|
```
|
|
```json
|
|
{"id":"41f42060-…","slug":"demo","name":"Demo App","description":null,
|
|
"created_at":"2026-…Z","updated_at":"2026-…Z"}
|
|
```
|
|
|
|
**Slug rules:** `^[a-z0-9][a-z0-9-]{0,62}$`, and not one of the reserved words (`new`, `api`, `admin`,
|
|
`apps`, `login`, `healthz`, `version`, …). Renaming a slug records the old one for redirects; reclaim a
|
|
released slug with `"force_takeover": true` in the create/patch body.
|
|
|
|
## Domains
|
|
|
|
A non-`default` app's routes only match once the app **claims** the request `Host`.
|
|
|
|
| Method & path | Capability |
|
|
|---|---|
|
|
| `GET /api/v1/admin/apps/{id_or_slug}/domains` | `AppRead` |
|
|
| `POST /api/v1/admin/apps/{id_or_slug}/domains` | `AppManageDomains` |
|
|
| `DELETE /api/v1/admin/apps/{id_or_slug}/domains/{domain_id}` | `AppManageDomains` |
|
|
|
|
```sh
|
|
curl -X POST $PICLOUD/api/v1/admin/apps/demo/domains -H "Authorization: Bearer $TOKEN" \
|
|
-H 'Content-Type: application/json' -d '{"pattern":"demo.localhost"}'
|
|
```
|
|
```json
|
|
{"id":"6ff04d56-…","app_id":"41f42060-…","pattern":"demo.localhost",
|
|
"shape":"exact","shape_key":"exact:demo.localhost","created_at":"2026-…Z"}
|
|
```
|
|
|
|
**Pattern shapes** (use `{name}`, never `:name`, in domains):
|
|
|
|
- exact — `app.example.com`
|
|
- wildcard — `*.example.com`
|
|
- parameterized — `{tenant}.example.com` (the segment is captured into a route param)
|
|
|
|
The most specific claim wins. Claiming a host another app already holds (in the same shape) returns
|
|
`409`. The `default` app ships claiming `localhost`. Locally, claim `something.localhost` and test with
|
|
`curl -H 'Host: something.localhost' $PICLOUD/...`.
|
|
|
|
**CLI:** `pic apps create demo --name "Demo App"`, `pic apps domains add demo demo.localhost`,
|
|
`pic apps ls`, `pic apps show demo`.
|