chore(release): bump workspace to v1.1.1 + CHANGELOG
- Workspace package version: 1.1.0 → 1.1.1 (patch under the post-1.0 expansion-phase carve-out in docs/versioning.md) - Rhai SDK version: 1.1 → 1.2 — minor bump, additive only. New surfaces: kv::*, dead_letters::*, ctx.event. - Dashboard package version: 0.6.0 → 0.7.0 for the dead-letters UI. - HTTP API version stays at 1 (additive: trigger CRUD, dead-letter admin endpoints, dispatch_mode field on routes). - Schema version: 6 → 12 (migrations 0007–0012). CHANGELOG.md created at the repo root following the convention from prior bumps (release commits + design-notes references). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
88
CHANGELOG.md
Normal file
88
CHANGELOG.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# PiCloud Changelog
|
||||||
|
|
||||||
|
## v1.1.1 — Storage & Events (unreleased)
|
||||||
|
|
||||||
|
The triggers framework — KV store + universal outbox + dispatcher +
|
||||||
|
NATS-style sync HTTP + per-route async dispatch + dead-letter
|
||||||
|
handling + dashboard surface. Every subsequent v1.1.x service module
|
||||||
|
(docs, files, pubsub, …) hangs off the dispatcher built here.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **KV store** — `kv_entries` table keyed `(app_id, collection, key)`
|
||||||
|
with JSONB values. Rhai SDK exposes the handle pattern:
|
||||||
|
`kv::collection(name).{get,set,has,delete,list}`. Cursor-style
|
||||||
|
pagination with opaque base64 cursors. Cross-app isolation
|
||||||
|
enforced via `cx.app_id` (never script-passed).
|
||||||
|
- **Triggers framework (Layout E)** — parent `triggers` table +
|
||||||
|
per-kind detail tables (`kv_trigger_details`,
|
||||||
|
`dead_letter_trigger_details`). Trigger CRUD admin endpoints
|
||||||
|
(`/api/v1/admin/apps/{id}/triggers/{kv,dead_letter}`) +
|
||||||
|
`Capability::AppManageTriggers(AppId)`.
|
||||||
|
- **Universal outbox + dispatcher** — single tokio task that polls
|
||||||
|
the outbox via `FOR UPDATE SKIP LOCKED`, routes due rows to the
|
||||||
|
executor through the shared `ExecutionGate`. Retry with
|
||||||
|
exponential backoff + ±jitter; on exhaustion, dead-letter.
|
||||||
|
- **NATS-style sync HTTP via outbox** — `InboxRegistry` (in-process
|
||||||
|
oneshot map) lets the orchestrator await dispatcher delivery on
|
||||||
|
every sync HTTP request. Cluster mode (v1.3+) swaps this for
|
||||||
|
`LISTEN/NOTIFY` behind the same `InboxResolver` trait.
|
||||||
|
- **`dispatch_mode: async` on routes** — `POST` to a route with
|
||||||
|
`dispatch_mode = 'async'` returns `202 Accepted` immediately;
|
||||||
|
the script runs via the dispatcher (with retries / dead-letter).
|
||||||
|
- **Dead-letter handling** — separate `dead_letters` table per
|
||||||
|
design notes §4. `dead_letters::{replay,resolve}` Rhai SDK +
|
||||||
|
admin endpoints + `Capability::AppDeadLetterManage(AppId)`.
|
||||||
|
Recursion-stop rule: dead-letter handler failures annotate the
|
||||||
|
original row as `resolution = 'handler_failed'` and never produce
|
||||||
|
a new dead-letter or retry.
|
||||||
|
- **Dashboard surface for dead letters** — unresolved-count red
|
||||||
|
badge on the apps list + per-app page; per-app dead-letters list
|
||||||
|
view at `/admin/apps/{slug}/dead-letters` with Replay + Mark
|
||||||
|
resolved per-row actions and expandable payload detail.
|
||||||
|
- **`abandoned_executions` table** — forensic row written by the
|
||||||
|
dispatcher when it tries to resolve an inbox the orchestrator
|
||||||
|
already abandoned (timed out). Counter metric path reserved.
|
||||||
|
- **Trigger-depth limit** — `cx.trigger_depth > max_trigger_depth`
|
||||||
|
(default 8) skips execution + logs; does NOT dead-letter
|
||||||
|
(depth-exceeded means "you built a loop").
|
||||||
|
- **GC sweepers** — weekly retention sweeps for `dead_letters`
|
||||||
|
(30 days) and `abandoned_executions` (7 days), both with
|
||||||
|
`FOR UPDATE SKIP LOCKED` for cluster-mode safety.
|
||||||
|
- **Env-overridable trigger config** — `TriggerConfig::from_env`
|
||||||
|
reads `PICLOUD_MAX_TRIGGER_DEPTH`, `PICLOUD_TRIGGER_RETRY_*`,
|
||||||
|
`PICLOUD_DEAD_LETTER_RETENTION_DAYS`,
|
||||||
|
`PICLOUD_ABANDONED_EXECUTIONS_RETENTION_DAYS`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Workspace version**: `1.1.0` → `1.1.1`.
|
||||||
|
- **Rhai SDK version**: `1.1` → `1.2` (additive — every v1.1 script
|
||||||
|
still runs unchanged; new surfaces: `kv::*`, `dead_letters::*`,
|
||||||
|
`ctx.event` for triggered handlers).
|
||||||
|
- **Dashboard version**: `0.6.0` → `0.7.0` for the dead-letters UI.
|
||||||
|
- **`Services` bundle** — replaces v1.1.0's no-arg `Services::new()`
|
||||||
|
with explicit `Services::new(kv, dead_letters, events)`. Tests
|
||||||
|
use `Services::default()` for an all-noop bundle.
|
||||||
|
- **`SdkCallCx`** grows `is_dead_letter_handler: bool` and
|
||||||
|
`event: Option<TriggerEvent>` fields.
|
||||||
|
- **`ExecRequest`** mirrors the new `SdkCallCx` fields and grows
|
||||||
|
`event` for serializable trigger payload transport.
|
||||||
|
- **Routes table** grows `dispatch_mode TEXT NOT NULL DEFAULT 'sync'`
|
||||||
|
(CHECK in {sync, async}).
|
||||||
|
- **Schema version**: 6 → 12 (migrations 0007 through 0012).
|
||||||
|
|
||||||
|
### Migrations
|
||||||
|
|
||||||
|
- `0007_kv.sql` — `kv_entries` table + index
|
||||||
|
- `0008_triggers.sql` — `triggers` + `kv_trigger_details` +
|
||||||
|
`dead_letter_trigger_details`
|
||||||
|
- `0009_outbox.sql` — universal `outbox` table + due-row partial index
|
||||||
|
- `0010_dead_letters.sql` — `dead_letters` table + unresolved partial
|
||||||
|
index + GC index
|
||||||
|
- `0011_abandoned_executions.sql` — forensic table + GC index
|
||||||
|
- `0012_routes_dispatch_mode.sql` — `routes.dispatch_mode` column
|
||||||
|
|
||||||
|
## v1.1.0 — Foundation & Standard Library
|
||||||
|
|
||||||
|
See `docs/v1.1.x-design-notes.md` §7 for the full v1.1.x roadmap.
|
||||||
18
Cargo.lock
generated
18
Cargo.lock
generated
@@ -1505,7 +1505,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "picloud"
|
name = "picloud"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -1531,7 +1531,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "picloud-cli"
|
name = "picloud-cli"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
@@ -1552,7 +1552,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "picloud-executor"
|
name = "picloud-executor"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"picloud-executor-core",
|
"picloud-executor-core",
|
||||||
@@ -1564,7 +1564,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "picloud-executor-core"
|
name = "picloud-executor-core"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64",
|
"base64",
|
||||||
@@ -1585,7 +1585,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "picloud-manager"
|
name = "picloud-manager"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"picloud-manager-core",
|
"picloud-manager-core",
|
||||||
@@ -1597,7 +1597,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "picloud-manager-core"
|
name = "picloud-manager-core"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argon2",
|
"argon2",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -1622,7 +1622,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "picloud-orchestrator"
|
name = "picloud-orchestrator"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"picloud-orchestrator-core",
|
"picloud-orchestrator-core",
|
||||||
@@ -1634,7 +1634,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "picloud-orchestrator-core"
|
name = "picloud-orchestrator-core"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
@@ -1653,7 +1653,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "picloud-shared"
|
name = "picloud-shared"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.92"
|
rust-version = "1.92"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ pub const PRODUCT_VERSION: &str = env!("CARGO_PKG_VERSION");
|
|||||||
///
|
///
|
||||||
/// 1.1 additions: `ctx.request.params`, `ctx.request.query`,
|
/// 1.1 additions: `ctx.request.params`, `ctx.request.query`,
|
||||||
/// `ctx.request.rest`.
|
/// `ctx.request.rest`.
|
||||||
pub const SDK_VERSION: &str = "1.1";
|
///
|
||||||
|
/// 1.2 additions (v1.1.1): `kv::collection(name).{get,set,has,delete,list}`,
|
||||||
|
/// `dead_letters::{replay,resolve}`, `ctx.event` for triggered handlers.
|
||||||
|
pub const SDK_VERSION: &str = "1.2";
|
||||||
|
|
||||||
/// HTTP API major version. Appears in URL paths as `/api/v{N}/...`.
|
/// HTTP API major version. Appears in URL paths as `/api/v{N}/...`.
|
||||||
/// Bump (new integer + new URL prefix) when the request/response
|
/// Bump (new integer + new URL prefix) when the request/response
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "picloud-dashboard",
|
"name": "picloud-dashboard",
|
||||||
"version": "0.6.0",
|
"version": "0.7.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user