Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
94 lines
3.5 KiB
Markdown
94 lines
3.5 KiB
Markdown
# Extension Storage API Contract
|
|
|
|
> **Status:** Archived. The extension-scoped contract has been superseded by the tenant storage service.
|
|
|
|
The authoritative API contract, resource model, and request/response semantics are maintained in the [Alga Storage Service documentation](../../../docs/storage-system.md). That specification applies uniformly to extensions, workflows, and any other integration consuming the storage platform.
|
|
|
|
If you are migrating existing extension code:
|
|
|
|
- Remove any dependency on `extension_install_id` scoping—the service now keys data by tenant and namespace only.
|
|
- Adopt the optimistic concurrency and TTL guidance documented in the official spec.
|
|
|
|
Legacy details from the Phase 1 extension rollout are intentionally omitted here to avoid divergence from the shared platform documentation.
|
|
|
|
- Request body:
|
|
```jsonc
|
|
{
|
|
"namespace": "settings",
|
|
"key": "invoice-defaults",
|
|
"ifRevision": 13
|
|
}
|
|
```
|
|
- Response: HTTP 204 with no body on success.
|
|
- Errors mirror `REVISION_MISMATCH` and `NOT_FOUND`.
|
|
|
|
### `storage.bulkPut`
|
|
|
|
- Request body:
|
|
```jsonc
|
|
{
|
|
"namespace": "settings",
|
|
"items": [
|
|
{
|
|
"key": "invoice-defaults",
|
|
"value": { /* JSON payload */ },
|
|
"metadata": {},
|
|
"ttlSeconds": 86400,
|
|
"ifRevision": null
|
|
}
|
|
]
|
|
}
|
|
```
|
|
- Constraints:
|
|
- Max 20 items per call, cumulative payload ≤ 512 KiB.
|
|
- Fails fast with `BULK_PARTIAL_FAILURE` if any record violates validation/quota.
|
|
- Response mirrors `storage.put` for each item:
|
|
```jsonc
|
|
{
|
|
"items": [
|
|
{
|
|
"key": "invoice-defaults",
|
|
"revision": 13,
|
|
"ttlExpiresAt": "2025-10-08T19:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Concurrency & Consistency
|
|
|
|
- Each record maintains a `revision` counter starting at 1. Writes increment revision atomically.
|
|
- `ifRevision` guards enforce optimistic concurrency; Runner returns `409 REVISION_MISMATCH` if mismatch.
|
|
- Reads are strongly consistent; `storage.get` returns the latest committed record.
|
|
- `storage.list` guarantees results consistent with the snapshot at query start (transactional).
|
|
|
|
## TTL and Expiration Semantics
|
|
|
|
- Extensions may set `ttlSeconds` (min 60, max 30 days). Absent TTL implies indefinite retention subject to quota.
|
|
- Expired records are soft-deleted on access (reads/writes) by the opportunistic cleanup hook.
|
|
- `ttlExpiresAt` is returned so clients can monitor refresh cycles.
|
|
|
|
## Error Codes (Shared)
|
|
|
|
| Code | HTTP Status | Description |
|
|
|------|-------------|-------------|
|
|
| `REVISION_MISMATCH` | 409 | Optimistic concurrency failure |
|
|
| `QUOTA_EXCEEDED` | 429 | Namespace or tenant quota exceeded |
|
|
| `VALIDATION_FAILED` | 400 | JSON Schema validation error details |
|
|
| `NOT_FOUND` | 404 | Record not found or expired |
|
|
| `UNAUTHORIZED` | 403 | Missing `alga.storage` capability |
|
|
| `RATE_LIMITED` | 429 | Global rate limiting triggered |
|
|
| `INTERNAL_ERROR` | 500 | Unexpected server failure |
|
|
|
|
## Runner Integration Surface
|
|
|
|
- Internal endpoint: `POST /api/internal/ext-storage/install/{installId}` guarded by `RUNNER_STORAGE_API_TOKEN`.
|
|
- Body schema matches the contracts above with an added `operation` field (e.g., `{ "operation": "put", ... }`).
|
|
- Responses mirror the public REST endpoints so the runner can forward them directly to guest code.
|
|
|
|
## Open Items
|
|
|
|
- Define JSON Schema registration flow (see Phase 1 validation strategy).
|
|
- Confirm pagination cursor encoding (opaque Base64 vs. encrypted token).
|
|
- Decide SDK default behavior for `includeValues` on list (likely false).
|