syntax = "proto3"; package chatto.admin.v1; import "google/protobuf/timestamp.proto"; // Request to read owner-only server diagnostics. message GetSystemInfoRequest {} // Owner-only operational diagnostics for the Chatto server. message GetSystemInfoResponse { // Broker connection, account, and JetStream state. AdminSystemInfo system_info = 1; // Event-sourced projection health and memory estimates. repeated AdminProjectionState projections = 2; // Recoverable physical deletion worker health. AdminAssetCleanupStatus asset_cleanup = 3; // Known durable worker queues and their current broker-derived health. repeated AdminDurableWorkerStatus durable_workers = 4; // Whether projection diagnostics were collected successfully. optional bool projections_available = 5; // LiveKit voice and video call setup diagnostics. AdminLiveKitStatus livekit = 6; } // LiveKit voice and video call setup as seen by the Chatto server that // handled the request. The response never includes the API secret or the // webhook signing secret. // // Chatto calls the LiveKit server API once for each request to check // reachability and credentials. Webhook times come from the memory of the // Chatto server that handled the request. They reset when that server // restarts, and other servers in a cluster keep their own times. message AdminLiveKitStatus { // Whether `livekit.enabled` is set. bool enabled = 1; // Whether LiveKit is enabled and the URL, API key, and API secret are all set. bool configured = 2; // Configured LiveKit server URL that clients connect to. string url = 3; // Configured LiveKit API key. This is an identifier, not a secret. string api_key = 4; // Whether webhooks use a signing key that differs from `api_key`. bool separate_webhook_key = 5; // URL that LiveKit must send webhooks to. Empty when the public server URL is not set. string webhook_url = 6; // Result of the LiveKit server API check. AdminLiveKitConnectionState connection_state = 7; // Error detail when the check fails. Never contains secrets. string connection_error = 8; // True when `url` uses unencrypted `ws://` or `http://` and the public server URL host is not a loopback address or a `.localhost` name. bool insecure_url = 9; // Time of the last webhook with a valid signature that this server received. google.protobuf.Timestamp last_webhook_at = 10; // Time of the last webhook that this server rejected because of an invalid signature. google.protobuf.Timestamp last_rejected_webhook_at = 11; } // Result of the LiveKit server API check. enum AdminLiveKitConnectionState { // Unknown state. ADMIN_LIVE_KIT_CONNECTION_STATE_UNSPECIFIED = 0; // LiveKit is not configured, so Chatto did not do the check. ADMIN_LIVE_KIT_CONNECTION_STATE_NOT_CONFIGURED = 1; // LiveKit accepted the API call with the configured key and secret. ADMIN_LIVE_KIT_CONNECTION_STATE_OK = 2; // Chatto could not connect to the LiveKit server URL. ADMIN_LIVE_KIT_CONNECTION_STATE_UNREACHABLE = 3; // LiveKit rejected the configured API key or secret. ADMIN_LIVE_KIT_CONNECTION_STATE_UNAUTHORIZED = 4; // The server at the URL replied with an unexpected error. ADMIN_LIVE_KIT_CONNECTION_STATE_ERROR = 5; } // Broker-derived health for one known durable worker queue. message AdminDurableWorkerStatus { // Stable machine-readable worker key. string key = 1; // Current availability and work state. AdminDurableWorkerHealth health = 2; // Deliveries not yet handed to a handler. string pending_count = 3; // Deliveries awaiting acknowledgement; this does not prove handler liveness. string ack_pending_count = 4; // Pull requests currently waiting for work. string waiting_count = 5; // Redelivered messages that remain unacknowledged. string redelivered_count = 6; // Latest EVT stream sequence delivered to this queue. string last_delivered_sequence = 7; // Highest contiguous EVT stream sequence acknowledged by this queue. string ack_floor_sequence = 8; } // Operator-facing state derived from a durable consumer. enum AdminDurableWorkerHealth { ADMIN_DURABLE_WORKER_HEALTH_UNSPECIFIED = 0; // This optional worker is not required by current server configuration. ADMIN_DURABLE_WORKER_HEALTH_INACTIVE = 1; // A worker is waiting and all known work is acknowledged. ADMIN_DURABLE_WORKER_HEALTH_HEALTHY = 2; // A worker is available and unacknowledged work remains. ADMIN_DURABLE_WORKER_HEALTH_WORKING = 3; // An acknowledgement is pending, but broker state cannot prove whether a // handler is active or the delivery is awaiting recovery after a crash. ADMIN_DURABLE_WORKER_HEALTH_UNCONFIRMED = 4; // The consumer exists but has neither a waiting pull nor an ack-pending delivery. ADMIN_DURABLE_WORKER_HEALTH_STALLED = 5; // The required consumer is unavailable. ADMIN_DURABLE_WORKER_HEALTH_UNAVAILABLE = 6; } // Current health of recoverable message-owned asset deletion. message AdminAssetCleanupStatus { // Operator-facing state derived from the shared durable consumer. AdminAssetCleanupHealth health = 1; // Deletion effects currently waiting for a successful retry. int64 pending_count = 2; // Deprecated. Shared durable consumers do not expose this value. google.protobuf.Timestamp oldest_pending_at = 3 [deprecated = true]; // Deprecated. Shared durable consumers run continuously rather than in passes. bool pass_in_progress = 4 [deprecated = true]; // Deprecated. Shared durable consumers run continuously rather than in passes. google.protobuf.Timestamp last_pass_at = 5 [deprecated = true]; // Deprecated. Shared durable consumers run continuously rather than in passes. google.protobuf.Timestamp last_successful_pass_at = 6 [deprecated = true]; // Deprecated. Shared durable consumers do not publish a liveness heartbeat. google.protobuf.Timestamp updated_at = 7 [deprecated = true]; // Deprecated. Use health and pending_count instead. bool last_pass_failed = 8 [deprecated = true]; // Global EVT sequence of the most recently delivered deletion fact. string last_inspected_sequence = 9; // Current latest global EVT sequence matching asset deletion facts. string latest_deletion_sequence = 10; } // Operator-facing state for the shared durable asset cleanup queue. enum AdminAssetCleanupHealth { ADMIN_ASSET_CLEANUP_HEALTH_UNSPECIFIED = 0; ADMIN_ASSET_CLEANUP_HEALTH_INACTIVE = 1; ADMIN_ASSET_CLEANUP_HEALTH_INITIALIZING = 2; ADMIN_ASSET_CLEANUP_HEALTH_HEALTHY = 3; ADMIN_ASSET_CLEANUP_HEALTH_RETRYING = 4; ADMIN_ASSET_CLEANUP_HEALTH_STALLED = 5; // Cleanup diagnostics could not be read; other system diagnostics remain valid. ADMIN_ASSET_CLEANUP_HEALTH_UNAVAILABLE = 6; } // Broker and application diagnostics shown on the server admin system page. message AdminSystemInfo { // Current NATS server connection metadata. AdminConnectionInfo connection = 1; // JetStream account limits and usage. AdminAccountInfo account = 2; // JetStream stream and consumer diagnostics. AdminNatsStats nats = 3; // Aggregate Chatto object counts. AdminServerStats stats = 4; } // Current NATS server connection metadata. message AdminConnectionInfo { // Whether Chatto is currently connected to NATS. bool connected = 1; // Connected NATS server ID. string server_id = 2; // Connected NATS server name. string server_name = 3; // Connected NATS server version. string version = 4; // Maximum payload accepted by the connected NATS server. int64 max_payload = 5; // Round-trip latency to the connected NATS server. string rtt = 6; } // JetStream account limits and usage. message AdminAccountInfo { // Maximum memory storage in bytes. Values less than or equal to zero mean unlimited. int64 memory = 1; // Used memory storage in bytes. int64 memory_used = 2; // Maximum file storage in bytes. Values less than or equal to zero mean unlimited. int64 storage = 3; // Used file storage in bytes. int64 storage_used = 4; // Maximum number of streams. Values less than or equal to zero mean unlimited. int32 streams = 5; // Current number of streams. int32 streams_used = 6; // Maximum number of consumers. Values less than or equal to zero mean unlimited. int32 consumers = 7; // Current number of consumers. int32 consumers_used = 8; } // Aggregate Chatto object counts. message AdminServerStats { // Registered user count. int32 user_count = 1; // Channel room count. int32 channel_room_count = 2; // Direct-message room count. int32 dm_room_count = 3; } // JetStream stream and consumer diagnostics. message AdminNatsStats { // Total messages stored across all streams. int64 total_messages = 1; // Total bytes stored across all streams. int64 total_bytes = 2; // Total pending messages across all consumers. int64 total_consumer_pending = 3; // Total messages currently waiting for acknowledgement. int32 total_ack_pending = 4; // Streams sorted by name. repeated AdminNatsStreamInfo streams = 5; // Consumers sorted by stream and name. repeated AdminNatsConsumerInfo consumers = 6; } // JetStream stream state. message AdminNatsStreamInfo { // Stream name. string name = 1; // Stream description. string description = 2; // Subjects stored in the stream. repeated string subjects = 3; // Storage backend name. string storage = 4; // Number of messages in the stream. int64 messages = 5; // Number of bytes in the stream. int64 bytes = 6; // First stream sequence. string first_sequence = 7; // Last stream sequence. string last_sequence = 8; // Number of stream consumers. int32 consumer_count = 9; // Configured stream replica count. int32 replicas = 10; // Current cluster leader, when reported by NATS. string cluster_leader = 11; } // JetStream consumer state. message AdminNatsConsumerInfo { // Stream that owns the consumer. string stream = 1; // Consumer name. string name = 2; // Durable name, when the consumer is durable. string durable = 3; // Single filter subject, when configured. string filter_subject = 4; // Multiple filter subjects, when configured. repeated string filter_subjects = 5; // NATS acknowledgement policy. string ack_policy = 6; // Whether this is a pull consumer. bool pull_based = 7; // Whether this push consumer has an active subscription. bool push_bound = 8; // Pending messages for this consumer. int64 pending = 9; // Messages waiting for acknowledgement. int32 ack_pending = 10; // Redelivered message count. int32 redelivered = 11; // Pull requests waiting for messages. int32 waiting = 12; // Delivered consumer sequence. string delivered_consumer_sequence = 13; // Delivered stream sequence. string delivered_stream_sequence = 14; // Acknowledgement floor consumer sequence. string ack_floor_consumer_sequence = 15; // Acknowledgement floor stream sequence. string ack_floor_stream_sequence = 16; } // Event-sourced projection health and memory estimates. message AdminProjectionState { // Stable projection key. string key = 1; // Display name. string name = 2; // EVT subjects consumed by this projection. repeated string subjects = 3; // Whether the projection projector is running. bool started = 4; // Startup duration in seconds, set after startup completes. optional double startup_duration_seconds = 5; // Last event sequence applied by the projection. string last_applied_sequence = 6; // Target sequence among the projection's matching subjects. string matching_stream_sequence = 7; // Current last sequence of the EVT stream. string stream_last_sequence = 8; // Matching-subject lag between target and applied sequence. int64 lag = 9; // Whether the projection failed. bool failed = 10; // Sequence that failed, when failed is true. string failed_sequence = 11; // Failure message, when failed is true. string failure = 12; // Estimated number of entries held by the projection. int64 entry_count = 13; // Estimated memory used by the projection in bytes. int64 estimated_bytes = 14; // Estimated average memory per entry in bytes. int64 average_entry_bytes = 15; // Projection-specific diagnostic metrics. repeated AdminProjectionMetric metrics = 16; } // Projection-specific diagnostic metric. message AdminProjectionMetric { // Metric name. string name = 1; // Metric value. int64 value = 2; // Estimated memory represented by this metric in bytes. int64 bytes = 3; } // Provides server diagnostics for the admin system page. service AdminDiagnosticsService { // Returns broker, JetStream, projection, and LiveKit diagnostics. Requires // the server owner role. The call checks the LiveKit server API, so it can // take up to five seconds when LiveKit does not reply. rpc GetSystemInfo(GetSystemInfoRequest) returns (GetSystemInfoResponse); }