Skip to main content

fraiseql_cli/config/toml_schema/
subscriptions.rs

1//! WebSocket subscription configuration for TOML schema.
2
3use serde::{Deserialize, Serialize};
4
5/// WebSocket subscription configuration.
6///
7/// ```toml
8/// [subscriptions]
9/// max_subscriptions_per_connection = 50
10///
11/// [subscriptions.hooks]
12/// on_connect = "http://localhost:8001/hooks/ws-connect"
13/// on_disconnect = "http://localhost:8001/hooks/ws-disconnect"
14/// on_subscribe = "http://localhost:8001/hooks/ws-subscribe"
15/// timeout_ms = 500
16/// ```
17#[derive(Debug, Clone, Default, Deserialize, Serialize)]
18#[serde(default, deny_unknown_fields)]
19pub struct SubscriptionsConfig {
20    /// Maximum subscriptions per WebSocket connection.
21    /// `None` (or omitted) means unlimited.
22    #[serde(default, skip_serializing_if = "Option::is_none")]
23    pub max_subscriptions_per_connection: Option<u32>,
24
25    /// Webhook lifecycle hooks.
26    #[serde(default, skip_serializing_if = "Option::is_none")]
27    pub hooks: Option<SubscriptionHooksConfig>,
28}
29
30/// Webhook URLs invoked during subscription lifecycle events.
31#[derive(Debug, Clone, Default, Deserialize, Serialize)]
32#[serde(default, deny_unknown_fields)]
33pub struct SubscriptionHooksConfig {
34    /// URL to POST on WebSocket `connection_init` (fail-closed).
35    #[serde(default, skip_serializing_if = "Option::is_none")]
36    pub on_connect: Option<String>,
37
38    /// URL to POST on WebSocket disconnect (fire-and-forget).
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub on_disconnect: Option<String>,
41
42    /// URL to POST before a subscription is registered (fail-closed).
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub on_subscribe: Option<String>,
45
46    /// Timeout in milliseconds for fail-closed hooks (default: 500).
47    #[serde(default = "default_hook_timeout_ms")]
48    pub timeout_ms: u64,
49}
50
51fn default_hook_timeout_ms() -> u64 {
52    500
53}