feat(v1.1.5): pubsub::publish_durable SDK + pubsub:* triggers
Durable pub/sub through the universal outbox — the sixth trigger kind. - `pubsub::publish_durable(topic, message)` Rhai SDK (no handle; topics ARE the grouping unit). Message JSON-encoded; Blobs base64 at any depth. - `PubsubService` trait in picloud-shared with the topic matcher + validator (exact / `<prefix>.*` / `*`; mid-pattern wildcards rejected). `PostgresPubsubRepo` + `PubsubServiceImpl` in manager-core. - Publish-time fan-out: one outbox row per matching enabled pubsub trigger, all in ONE transaction (no half-fan-out on crash). No matching trigger → publish succeeds silently, zero rows. - `pubsub:*` trigger kind via Layout-E (0020: widen both CHECKs + pubsub_trigger_details + partial index), TriggerEvent::Pubsub + ctx.event.pubsub, dispatcher arm, admin endpoint POST /triggers/pubsub (validates topic pattern + reuses validate_trigger_target). - AppPubsubPublish capability → script:write (seven-scope held). - Dashboard Pub/Sub trigger form on the Triggers tab + list rendering. publish_ephemeral stays deferred to v1.2. ~18 new tests (service in-memory incl. transactional-rollback, shared matcher, bridge encoding). No DB required for the suite. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -261,6 +261,15 @@ export interface CreateCronTriggerInput {
|
||||
retry_base_ms?: number;
|
||||
}
|
||||
|
||||
export interface CreatePubsubTriggerInput {
|
||||
script_id: string;
|
||||
topic_pattern: string;
|
||||
dispatch_mode?: TriggerDispatchMode;
|
||||
retry_max_attempts?: number;
|
||||
retry_backoff?: 'exponential' | 'linear' | 'constant';
|
||||
retry_base_ms?: number;
|
||||
}
|
||||
|
||||
export interface ExecutionResult {
|
||||
status: number;
|
||||
headers: Record<string, string>;
|
||||
@@ -632,6 +641,11 @@ export const api = {
|
||||
`/api/v1/admin/apps/${encodeURIComponent(idOrSlug)}/triggers/cron`,
|
||||
{ method: 'POST', body: JSON.stringify(input) }
|
||||
),
|
||||
createPubsub: (idOrSlug: string, input: CreatePubsubTriggerInput) =>
|
||||
adminRequest<Trigger>(
|
||||
`/api/v1/admin/apps/${encodeURIComponent(idOrSlug)}/triggers/pubsub`,
|
||||
{ method: 'POST', body: JSON.stringify(input) }
|
||||
),
|
||||
remove: (idOrSlug: string, triggerId: string) =>
|
||||
adminRequest<null>(
|
||||
`/api/v1/admin/apps/${encodeURIComponent(idOrSlug)}/triggers/${triggerId}`,
|
||||
|
||||
Reference in New Issue
Block a user