diff --git a/docker/nginx-https.conf b/docker/nginx-https.conf index 81f77ff68..1e7344e33 100644 --- a/docker/nginx-https.conf +++ b/docker/nginx-https.conf @@ -242,15 +242,6 @@ http { proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; } - location ~ ^/alert-rules(/.*)?$ { - proxy_pass http://127.0.0.1:30001; - proxy_http_version 1.1; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; - } - location ~ ^/notification-channels(/.*)?$ { proxy_pass http://127.0.0.1:30001; proxy_http_version 1.1; @@ -260,15 +251,6 @@ http { proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; } - location ~ ^/alert-firings(/.*)?$ { - proxy_pass http://127.0.0.1:30001; - proxy_http_version 1.1; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; - } - location ~ ^/rbac(/.*)?$ { proxy_pass http://127.0.0.1:30001; proxy_http_version 1.1; diff --git a/docker/nginx.conf b/docker/nginx.conf index 57d8a598a..ba75bdcc9 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -222,15 +222,6 @@ http { proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; } - location ~ ^/alert-rules(/.*)?$ { - proxy_pass http://127.0.0.1:30001; - proxy_http_version 1.1; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; - } - location ~ ^/notification-channels(/.*)?$ { proxy_pass http://127.0.0.1:30001; proxy_http_version 1.1; @@ -240,15 +231,6 @@ http { proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; } - location ~ ^/alert-firings(/.*)?$ { - proxy_pass http://127.0.0.1:30001; - proxy_http_version 1.1; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; - } - location ~ ^/rbac(/.*)?$ { proxy_pass http://127.0.0.1:30001; proxy_http_version 1.1; diff --git a/drizzle/mysql/0025_wet_master_mold.sql b/drizzle/mysql/0025_wet_master_mold.sql new file mode 100644 index 000000000..cb1b5e74b --- /dev/null +++ b/drizzle/mysql/0025_wet_master_mold.sql @@ -0,0 +1,3 @@ +DROP TABLE `alert_firings`;--> statement-breakpoint +DROP TABLE `alert_rule_channels`;--> statement-breakpoint +DROP TABLE `alert_rules`; \ No newline at end of file diff --git a/drizzle/mysql/meta/0025_snapshot.json b/drizzle/mysql/meta/0025_snapshot.json new file mode 100644 index 000000000..b892108cd --- /dev/null +++ b/drizzle/mysql/meta/0025_snapshot.json @@ -0,0 +1,9754 @@ +{ + "version": "5", + "dialect": "mysql", + "id": "1dbcc312-4743-49a9-bb91-f468b21a520c", + "prevId": "a6be168e-216b-4f64-8999-bde81c4457a5", + "tables": { + "ai_conversations": { + "name": "ai_conversations", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "provider_id": { + "name": "provider_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_ai_conversations_user": { + "name": "idx_ai_conversations_user", + "columns": [ + "user_id", + "updated_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ai_conversations_user_id_users_id_fk": { + "name": "ai_conversations_user_id_users_id_fk", + "tableFrom": "ai_conversations", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "ai_conversations_id": { + "name": "ai_conversations_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "ai_messages": { + "name": "ai_messages", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('')" + }, + "tool_calls": { + "name": "tool_calls", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_ai_messages_conversation": { + "name": "idx_ai_messages_conversation", + "columns": [ + "conversation_id", + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ai_messages_conversation_id_ai_conversations_id_fk": { + "name": "ai_messages_conversation_id_ai_conversations_id_fk", + "tableFrom": "ai_messages", + "tableTo": "ai_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "ai_messages_id": { + "name": "ai_messages_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "ai_proposals": { + "name": "ai_proposals", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('{}')" + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pending'" + }, + "applied_at": { + "name": "applied_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "result_summary": { + "name": "result_summary", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_ai_proposals_user": { + "name": "idx_ai_proposals_user", + "columns": [ + "user_id", + "status" + ], + "isUnique": false + }, + "idx_ai_proposals_conversation": { + "name": "idx_ai_proposals_conversation", + "columns": [ + "conversation_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ai_proposals_conversation_id_ai_conversations_id_fk": { + "name": "ai_proposals_conversation_id_ai_conversations_id_fk", + "tableFrom": "ai_proposals", + "tableTo": "ai_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ai_proposals_user_id_users_id_fk": { + "name": "ai_proposals_user_id_users_id_fk", + "tableFrom": "ai_proposals", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "ai_proposals_id": { + "name": "ai_proposals_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "ai_providers": { + "name": "ai_providers", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_type": { + "name": "provider_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "label": { + "name": "label", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "base_url": { + "name": "base_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "api_key": { + "name": "api_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "api_key_prefix": { + "name": "api_key_prefix", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_model": { + "name": "default_model", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_ai_providers_user_label": { + "name": "idx_ai_providers_user_label", + "columns": [ + "user_id", + "label" + ], + "isUnique": true + } + }, + "foreignKeys": { + "ai_providers_user_id_users_id_fk": { + "name": "ai_providers_user_id_users_id_fk", + "tableFrom": "ai_providers", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "ai_providers_id": { + "name": "ai_providers_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "api_keys": { + "name": "api_keys", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token_prefix": { + "name": "token_prefix", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + } + }, + "indexes": { + "idx_api_keys_user_id": { + "name": "idx_api_keys_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "api_keys_user_id_users_id_fk": { + "name": "api_keys_user_id_users_id_fk", + "tableFrom": "api_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "api_keys_id": { + "name": "api_keys_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "audit_logs": { + "name": "audit_logs", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "action": { + "name": "action", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "resource_id": { + "name": "resource_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "resource_name": { + "name": "resource_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "details": { + "name": "details", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "success": { + "name": "success", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "timestamp": { + "name": "timestamp", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_audit_logs_timestamp": { + "name": "idx_audit_logs_timestamp", + "columns": [ + "timestamp" + ], + "isUnique": false + }, + "idx_audit_logs_user_ts": { + "name": "idx_audit_logs_user_ts", + "columns": [ + "user_id", + "timestamp" + ], + "isUnique": false + }, + "idx_audit_logs_action_ts": { + "name": "idx_audit_logs_action_ts", + "columns": [ + "action", + "timestamp" + ], + "isUnique": false + }, + "idx_audit_logs_resource_ts": { + "name": "idx_audit_logs_resource_ts", + "columns": [ + "resource_type", + "timestamp" + ], + "isUnique": false + } + }, + "foreignKeys": { + "audit_logs_user_id_users_id_fk": { + "name": "audit_logs_user_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "audit_logs_id": { + "name": "audit_logs_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "automation_channels": { + "name": "automation_channels", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "automation_id": { + "name": "automation_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "channel_id": { + "name": "channel_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_automation_channels_pair": { + "name": "idx_automation_channels_pair", + "columns": [ + "automation_id", + "channel_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "automation_channels_automation_id_automations_id_fk": { + "name": "automation_channels_automation_id_automations_id_fk", + "tableFrom": "automation_channels", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "automation_channels_channel_id_notification_channels_id_fk": { + "name": "automation_channels_channel_id_notification_channels_id_fk", + "tableFrom": "automation_channels", + "tableTo": "notification_channels", + "columnsFrom": [ + "channel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "automation_channels_id": { + "name": "automation_channels_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "automation_run_steps": { + "name": "automation_run_steps", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "run_id": { + "name": "run_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "step_index": { + "name": "step_index", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "step_id": { + "name": "step_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "step_type": { + "name": "step_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "finished_at": { + "name": "finished_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "output": { + "name": "output", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "truncated": { + "name": "truncated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": { + "idx_automation_run_steps_run": { + "name": "idx_automation_run_steps_run", + "columns": [ + "run_id", + "step_index" + ], + "isUnique": false + } + }, + "foreignKeys": { + "automation_run_steps_run_id_automation_runs_id_fk": { + "name": "automation_run_steps_run_id_automation_runs_id_fk", + "tableFrom": "automation_run_steps", + "tableTo": "automation_runs", + "columnsFrom": [ + "run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "automation_run_steps_id": { + "name": "automation_run_steps_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "automation_runs": { + "name": "automation_runs", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "automation_id": { + "name": "automation_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "trigger_type": { + "name": "trigger_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "trigger_context": { + "name": "trigger_context", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "finished_at": { + "name": "finished_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "dry_run": { + "name": "dry_run", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "parent_run_id": { + "name": "parent_run_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_automation_runs_automation": { + "name": "idx_automation_runs_automation", + "columns": [ + "automation_id", + "started_at" + ], + "isUnique": false + }, + "idx_automation_runs_user": { + "name": "idx_automation_runs_user", + "columns": [ + "user_id", + "started_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "automation_runs_automation_id_automations_id_fk": { + "name": "automation_runs_automation_id_automations_id_fk", + "tableFrom": "automation_runs", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "automation_runs_user_id_users_id_fk": { + "name": "automation_runs_user_id_users_id_fk", + "tableFrom": "automation_runs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "automation_runs_id": { + "name": "automation_runs_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "automation_schedules": { + "name": "automation_schedules", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "automation_id": { + "name": "automation_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cron": { + "name": "cron", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "interval_seconds": { + "name": "interval_seconds", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "next_due_at": { + "name": "next_due_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_tick_at": { + "name": "last_tick_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_automation_schedules_automation": { + "name": "idx_automation_schedules_automation", + "columns": [ + "automation_id" + ], + "isUnique": true + }, + "idx_automation_schedules_due": { + "name": "idx_automation_schedules_due", + "columns": [ + "next_due_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "automation_schedules_automation_id_automations_id_fk": { + "name": "automation_schedules_automation_id_automations_id_fk", + "tableFrom": "automation_schedules", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "automation_schedules_id": { + "name": "automation_schedules_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "automation_trigger_state": { + "name": "automation_trigger_state", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "automation_id": { + "name": "automation_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "state_key": { + "name": "state_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "breach_started_at": { + "name": "breach_started_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_fired_at": { + "name": "last_fired_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_value": { + "name": "last_value", + "type": "double", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_observed_state": { + "name": "last_observed_state", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_automation_trigger_state_key": { + "name": "idx_automation_trigger_state_key", + "columns": [ + "automation_id", + "state_key" + ], + "isUnique": true + } + }, + "foreignKeys": { + "automation_trigger_state_automation_id_automations_id_fk": { + "name": "automation_trigger_state_automation_id_automations_id_fk", + "tableFrom": "automation_trigger_state", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "automation_trigger_state_id": { + "name": "automation_trigger_state_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "automations": { + "name": "automations", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "definition": { + "name": "definition", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "definition_version": { + "name": "definition_version", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "concurrency_policy": { + "name": "concurrency_policy", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('skip')" + }, + "max_run_seconds": { + "name": "max_run_seconds", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 300 + }, + "dry_run": { + "name": "dry_run", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "last_run_at": { + "name": "last_run_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_run_status": { + "name": "last_run_status", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_automations_user": { + "name": "idx_automations_user", + "columns": [ + "user_id", + "enabled" + ], + "isUnique": false + } + }, + "foreignKeys": { + "automations_user_id_users_id_fk": { + "name": "automations_user_id_users_id_fk", + "tableFrom": "automations", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "automations_id": { + "name": "automations_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "c2s_tunnel_presets": { + "name": "c2s_tunnel_presets", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "computer_name": { + "name": "computer_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "c2s_tunnel_presets_user_id_users_id_fk": { + "name": "c2s_tunnel_presets_user_id_users_id_fk", + "tableFrom": "c2s_tunnel_presets", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "c2s_tunnel_presets_id": { + "name": "c2s_tunnel_presets_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "collab_room_members": { + "name": "collab_room_members", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "room_id": { + "name": "room_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "room_role": { + "name": "room_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('member')" + }, + "added_by": { + "name": "added_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_collab_room_members_room_user": { + "name": "idx_collab_room_members_room_user", + "columns": [ + "room_id", + "user_id" + ], + "isUnique": true + }, + "idx_collab_room_members_user": { + "name": "idx_collab_room_members_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "collab_room_members_room_id_collab_rooms_id_fk": { + "name": "collab_room_members_room_id_collab_rooms_id_fk", + "tableFrom": "collab_room_members", + "tableTo": "collab_rooms", + "columnsFrom": [ + "room_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "collab_room_members_user_id_users_id_fk": { + "name": "collab_room_members_user_id_users_id_fk", + "tableFrom": "collab_room_members", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "collab_room_members_added_by_users_id_fk": { + "name": "collab_room_members_added_by_users_id_fk", + "tableFrom": "collab_room_members", + "tableTo": "users", + "columnsFrom": [ + "added_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "collab_room_members_id": { + "name": "collab_room_members_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "collab_rooms": { + "name": "collab_rooms", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "persistent": { + "name": "persistent", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "presenter_user_id": { + "name": "presenter_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stage_protocol": { + "name": "stage_protocol", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stage_host_id": { + "name": "stage_host_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stage_share_id": { + "name": "stage_share_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "guest_link_token": { + "name": "guest_link_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "ended_at": { + "name": "ended_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_collab_rooms_owner": { + "name": "idx_collab_rooms_owner", + "columns": [ + "owner_user_id" + ], + "isUnique": false + }, + "idx_collab_rooms_guest_token": { + "name": "idx_collab_rooms_guest_token", + "columns": [ + "guest_link_token" + ], + "isUnique": true + } + }, + "foreignKeys": { + "collab_rooms_owner_user_id_users_id_fk": { + "name": "collab_rooms_owner_user_id_users_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "users", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "collab_rooms_presenter_user_id_users_id_fk": { + "name": "collab_rooms_presenter_user_id_users_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "users", + "columnsFrom": [ + "presenter_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "collab_rooms_stage_host_id_ssh_data_id_fk": { + "name": "collab_rooms_stage_host_id_ssh_data_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "ssh_data", + "columnsFrom": [ + "stage_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "collab_rooms_stage_share_id_session_shares_id_fk": { + "name": "collab_rooms_stage_share_id_session_shares_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "session_shares", + "columnsFrom": [ + "stage_share_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "collab_rooms_id": { + "name": "collab_rooms_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "command_history": { + "name": "command_history", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "executed_at": { + "name": "executed_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_command_history_user_host": { + "name": "idx_command_history_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "command_history_user_id_users_id_fk": { + "name": "command_history_user_id_users_id_fk", + "tableFrom": "command_history", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "command_history_host_id_ssh_data_id_fk": { + "name": "command_history_host_id_ssh_data_id_fk", + "tableFrom": "command_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "command_history_id": { + "name": "command_history_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "credential_access": { + "name": "credential_access", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "credential_id": { + "name": "credential_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('use')" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_credential_access_user_id": { + "name": "idx_credential_access_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_credential_access_role_id": { + "name": "idx_credential_access_role_id", + "columns": [ + "role_id" + ], + "isUnique": false + }, + "idx_credential_access_credential_id": { + "name": "idx_credential_access_credential_id", + "columns": [ + "credential_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "credential_access_credential_id_ssh_credentials_id_fk": { + "name": "credential_access_credential_id_ssh_credentials_id_fk", + "tableFrom": "credential_access", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credential_access_user_id_users_id_fk": { + "name": "credential_access_user_id_users_id_fk", + "tableFrom": "credential_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credential_access_role_id_roles_id_fk": { + "name": "credential_access_role_id_roles_id_fk", + "tableFrom": "credential_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credential_access_granted_by_users_id_fk": { + "name": "credential_access_granted_by_users_id_fk", + "tableFrom": "credential_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "credential_access_id": { + "name": "credential_access_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "credential_sidebar_preferences": { + "name": "credential_sidebar_preferences", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "credential_sidebar_preferences_user_id_users_id_fk": { + "name": "credential_sidebar_preferences_user_id_users_id_fk", + "tableFrom": "credential_sidebar_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "credential_sidebar_preferences_user_id": { + "name": "credential_sidebar_preferences_user_id", + "columns": [ + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "dashboard_service_links": { + "name": "dashboard_service_links", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "label": { + "name": "label", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "order": { + "name": "order", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "dashboard_service_links_user_id_users_id_fk": { + "name": "dashboard_service_links_user_id_users_id_fk", + "tableFrom": "dashboard_service_links", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "dashboard_service_links_id": { + "name": "dashboard_service_links_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "dashboard_service_links_sync_id_unique": { + "name": "dashboard_service_links_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "dismissed_alerts": { + "name": "dismissed_alerts", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "alert_id": { + "name": "alert_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dismissed_at": { + "name": "dismissed_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_dismissed_alerts_user_id": { + "name": "idx_dismissed_alerts_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "dismissed_alerts_user_id_users_id_fk": { + "name": "dismissed_alerts_user_id_users_id_fk", + "tableFrom": "dismissed_alerts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "dismissed_alerts_id": { + "name": "dismissed_alerts_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "file_manager_pinned": { + "name": "file_manager_pinned", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "pinned_at": { + "name": "pinned_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_file_manager_pinned_user": { + "name": "idx_file_manager_pinned_user", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "file_manager_pinned_user_id_users_id_fk": { + "name": "file_manager_pinned_user_id_users_id_fk", + "tableFrom": "file_manager_pinned", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "file_manager_pinned_host_id_ssh_data_id_fk": { + "name": "file_manager_pinned_host_id_ssh_data_id_fk", + "tableFrom": "file_manager_pinned", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "file_manager_pinned_id": { + "name": "file_manager_pinned_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "file_manager_recent": { + "name": "file_manager_recent", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_opened": { + "name": "last_opened", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_file_manager_recent_user": { + "name": "idx_file_manager_recent_user", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "file_manager_recent_user_id_users_id_fk": { + "name": "file_manager_recent_user_id_users_id_fk", + "tableFrom": "file_manager_recent", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "file_manager_recent_host_id_ssh_data_id_fk": { + "name": "file_manager_recent_host_id_ssh_data_id_fk", + "tableFrom": "file_manager_recent", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "file_manager_recent_id": { + "name": "file_manager_recent_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "file_manager_shortcuts": { + "name": "file_manager_shortcuts", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_file_manager_shortcuts_user": { + "name": "idx_file_manager_shortcuts_user", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "file_manager_shortcuts_user_id_users_id_fk": { + "name": "file_manager_shortcuts_user_id_users_id_fk", + "tableFrom": "file_manager_shortcuts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "file_manager_shortcuts_host_id_ssh_data_id_fk": { + "name": "file_manager_shortcuts_host_id_ssh_data_id_fk", + "tableFrom": "file_manager_shortcuts", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "file_manager_shortcuts_id": { + "name": "file_manager_shortcuts_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "fleet_inventory": { + "name": "fleet_inventory", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "os_pretty_name": { + "name": "os_pretty_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "kernel": { + "name": "kernel", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "architecture": { + "name": "architecture", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "uptime_seconds": { + "name": "uptime_seconds", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "package_manager": { + "name": "package_manager", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "collected_at": { + "name": "collected_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_fleet_inventory_host": { + "name": "idx_fleet_inventory_host", + "columns": [ + "host_id", + "user_id" + ], + "isUnique": true + }, + "idx_fleet_inventory_user": { + "name": "idx_fleet_inventory_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "fleet_inventory_host_id_ssh_data_id_fk": { + "name": "fleet_inventory_host_id_ssh_data_id_fk", + "tableFrom": "fleet_inventory", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "fleet_inventory_user_id_users_id_fk": { + "name": "fleet_inventory_user_id_users_id_fk", + "tableFrom": "fleet_inventory", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "fleet_inventory_id": { + "name": "fleet_inventory_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "fleet_members": { + "name": "fleet_members", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "fleet_id": { + "name": "fleet_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "added_at": { + "name": "added_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_fleet_members_fleet_host": { + "name": "idx_fleet_members_fleet_host", + "columns": [ + "fleet_id", + "host_id" + ], + "isUnique": true + }, + "idx_fleet_members_host": { + "name": "idx_fleet_members_host", + "columns": [ + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "fleet_members_fleet_id_fleets_id_fk": { + "name": "fleet_members_fleet_id_fleets_id_fk", + "tableFrom": "fleet_members", + "tableTo": "fleets", + "columnsFrom": [ + "fleet_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "fleet_members_host_id_ssh_data_id_fk": { + "name": "fleet_members_host_id_ssh_data_id_fk", + "tableFrom": "fleet_members", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "fleet_members_id": { + "name": "fleet_members_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "fleets": { + "name": "fleets", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tag_rules": { + "name": "tag_rules", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "fleets_user_id_users_id_fk": { + "name": "fleets_user_id_users_id_fk", + "tableFrom": "fleets", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "fleets_id": { + "name": "fleets_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "fleets_sync_id_unique": { + "name": "fleets_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "folder_access": { + "name": "folder_access", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('connect')" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_folder_access_owner_folder": { + "name": "idx_folder_access_owner_folder", + "columns": [ + "owner_user_id", + "folder" + ], + "isUnique": false + } + }, + "foreignKeys": { + "folder_access_owner_user_id_users_id_fk": { + "name": "folder_access_owner_user_id_users_id_fk", + "tableFrom": "folder_access", + "tableTo": "users", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "folder_access_user_id_users_id_fk": { + "name": "folder_access_user_id_users_id_fk", + "tableFrom": "folder_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "folder_access_role_id_roles_id_fk": { + "name": "folder_access_role_id_roles_id_fk", + "tableFrom": "folder_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "folder_access_granted_by_users_id_fk": { + "name": "folder_access_granted_by_users_id_fk", + "tableFrom": "folder_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "folder_access_id": { + "name": "folder_access_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "homepage_items": { + "name": "homepage_items", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type_id": { + "name": "type_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('{}')" + }, + "folder_id": { + "name": "folder_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_homepage_items_user_id": { + "name": "idx_homepage_items_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "homepage_items_user_id_users_id_fk": { + "name": "homepage_items_user_id_users_id_fk", + "tableFrom": "homepage_items", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "homepage_items_id": { + "name": "homepage_items_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "homepage_items_sync_id_unique": { + "name": "homepage_items_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "homepage_layouts": { + "name": "homepage_layouts", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('{}')" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "homepage_layouts_user_id_users_id_fk": { + "name": "homepage_layouts_user_id_users_id_fk", + "tableFrom": "homepage_layouts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "homepage_layouts_id": { + "name": "homepage_layouts_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "homepage_layouts_user_id_unique": { + "name": "homepage_layouts_user_id_unique", + "columns": [ + "user_id" + ] + } + }, + "checkConstraint": {} + }, + "host_access": { + "name": "host_access", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('connect')" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "last_accessed_at": { + "name": "last_accessed_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_count": { + "name": "access_count", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + } + }, + "indexes": { + "idx_host_access_user_id": { + "name": "idx_host_access_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_host_access_role_id": { + "name": "idx_host_access_role_id", + "columns": [ + "role_id" + ], + "isUnique": false + }, + "idx_host_access_host_id": { + "name": "idx_host_access_host_id", + "columns": [ + "host_id" + ], + "isUnique": false + }, + "idx_host_access_expires_at": { + "name": "idx_host_access_expires_at", + "columns": [ + "expires_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "host_access_host_id_ssh_data_id_fk": { + "name": "host_access_host_id_ssh_data_id_fk", + "tableFrom": "host_access", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_access_user_id_users_id_fk": { + "name": "host_access_user_id_users_id_fk", + "tableFrom": "host_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_access_role_id_roles_id_fk": { + "name": "host_access_role_id_roles_id_fk", + "tableFrom": "host_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_access_granted_by_users_id_fk": { + "name": "host_access_granted_by_users_id_fk", + "tableFrom": "host_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "host_access_id": { + "name": "host_access_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "host_health_checks": { + "name": "host_health_checks", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "checks": { + "name": "checks", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "interval_seconds": { + "name": "interval_seconds", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 300 + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_host_health_checks_user_host": { + "name": "idx_host_health_checks_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "host_health_checks_user_id_users_id_fk": { + "name": "host_health_checks_user_id_users_id_fk", + "tableFrom": "host_health_checks", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_health_checks_host_id_ssh_data_id_fk": { + "name": "host_health_checks_host_id_ssh_data_id_fk", + "tableFrom": "host_health_checks", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "host_health_checks_id": { + "name": "host_health_checks_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "host_health_history": { + "name": "host_health_history", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "check_id": { + "name": "check_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ts": { + "name": "ts", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "ok": { + "name": "ok", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "latency_ms": { + "name": "latency_ms", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "detail": { + "name": "detail", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "host_health_history_user_id_users_id_fk": { + "name": "host_health_history_user_id_users_id_fk", + "tableFrom": "host_health_history", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_health_history_host_id_ssh_data_id_fk": { + "name": "host_health_history_host_id_ssh_data_id_fk", + "tableFrom": "host_health_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "host_health_history_id": { + "name": "host_health_history_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "host_metrics_history": { + "name": "host_metrics_history", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ts": { + "name": "ts", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "cpu_percent": { + "name": "cpu_percent", + "type": "double", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mem_percent": { + "name": "mem_percent", + "type": "double", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "disk_percent": { + "name": "disk_percent", + "type": "double", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "net_rx_bytes": { + "name": "net_rx_bytes", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "net_tx_bytes": { + "name": "net_tx_bytes", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "host_metrics_history_host_id_ssh_data_id_fk": { + "name": "host_metrics_history_host_id_ssh_data_id_fk", + "tableFrom": "host_metrics_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "host_metrics_history_id": { + "name": "host_metrics_history_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "host_metrics_preferences": { + "name": "host_metrics_preferences", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_host_metrics_prefs_user_host": { + "name": "idx_host_metrics_prefs_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "host_metrics_preferences_user_id_users_id_fk": { + "name": "host_metrics_preferences_user_id_users_id_fk", + "tableFrom": "host_metrics_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_metrics_preferences_host_id_ssh_data_id_fk": { + "name": "host_metrics_preferences_host_id_ssh_data_id_fk", + "tableFrom": "host_metrics_preferences", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "host_metrics_preferences_id": { + "name": "host_metrics_preferences_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "host_sidebar_preferences": { + "name": "host_sidebar_preferences", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "host_sidebar_preferences_user_id_users_id_fk": { + "name": "host_sidebar_preferences_user_id_users_id_fk", + "tableFrom": "host_sidebar_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "host_sidebar_preferences_user_id": { + "name": "host_sidebar_preferences_user_id", + "columns": [ + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "ssh_data": { + "name": "ssh_data", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "connection_type": { + "name": "connection_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('ssh')" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "port": { + "name": "port", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "parent_host_id": { + "name": "parent_host_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tags": { + "name": "tags", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "pin": { + "name": "pin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "sort_order": { + "name": "sort_order", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "use_warpgate": { + "name": "use_warpgate", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "share_ssh_auth": { + "name": "share_ssh_auth", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "force_keyboard_interactive": { + "name": "force_keyboard_interactive", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_password": { + "name": "key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sudo_password": { + "name": "sudo_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "autostart_password": { + "name": "autostart_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "autostart_key": { + "name": "autostart_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "autostart_key_password": { + "name": "autostart_key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "credential_id": { + "name": "credential_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "override_credential_username": { + "name": "override_credential_username", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vault_profile_id": { + "name": "vault_profile_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_terminal": { + "name": "enable_terminal", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_session_logging": { + "name": "enable_session_logging", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "allow_session_sharing": { + "name": "allow_session_sharing", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_command_history": { + "name": "enable_command_history", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_tunnel": { + "name": "enable_tunnel", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "tunnel_connections": { + "name": "tunnel_connections", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "jump_hosts": { + "name": "jump_hosts", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_file_manager": { + "name": "enable_file_manager", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "scp_legacy": { + "name": "scp_legacy", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_docker": { + "name": "enable_docker", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_web_ui": { + "name": "enable_web_ui", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_tmux_monitor": { + "name": "enable_tmux_monitor", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_terminal_toolbar": { + "name": "enable_terminal_toolbar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_ai_assistant": { + "name": "enable_ai_assistant", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "show_terminal_in_sidebar": { + "name": "show_terminal_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "show_file_manager_in_sidebar": { + "name": "show_file_manager_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "show_tunnel_in_sidebar": { + "name": "show_tunnel_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "show_docker_in_sidebar": { + "name": "show_docker_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "show_server_stats_in_sidebar": { + "name": "show_server_stats_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "default_path": { + "name": "default_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stats_config": { + "name": "stats_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "docker_config": { + "name": "docker_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "web_ui_config": { + "name": "web_ui_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_proxmox": { + "name": "enable_proxmox", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "proxmox_config": { + "name": "proxmox_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_proxmox_stats": { + "name": "enable_proxmox_stats", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "proxmox_stats_config": { + "name": "proxmox_stats_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "terminal_config": { + "name": "terminal_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "quick_actions": { + "name": "quick_actions", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_ssh": { + "name": "enable_ssh", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_rdp": { + "name": "enable_rdp", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_vnc": { + "name": "enable_vnc", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_telnet": { + "name": "enable_telnet", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "ssh_port": { + "name": "ssh_port", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 22 + }, + "rdp_port": { + "name": "rdp_port", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 3389 + }, + "vnc_port": { + "name": "vnc_port", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 5900 + }, + "telnet_port": { + "name": "telnet_port", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 23 + }, + "rdp_credential_id": { + "name": "rdp_credential_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_user": { + "name": "rdp_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_password": { + "name": "rdp_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_domain": { + "name": "rdp_domain", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_security": { + "name": "rdp_security", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_ignore_cert": { + "name": "rdp_ignore_cert", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "vnc_credential_id": { + "name": "vnc_credential_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vnc_password": { + "name": "vnc_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vnc_user": { + "name": "vnc_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "telnet_user": { + "name": "telnet_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "telnet_password": { + "name": "telnet_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "telnet_credential_id": { + "name": "telnet_credential_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_auth_type": { + "name": "rdp_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vnc_auth_type": { + "name": "vnc_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "telnet_auth_type": { + "name": "telnet_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "security": { + "name": "security", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ignore_cert": { + "name": "ignore_cert", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "guacamole_config": { + "name": "guacamole_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "use_socks5": { + "name": "use_socks5", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_host": { + "name": "socks5_host", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_port": { + "name": "socks5_port", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_username": { + "name": "socks5_username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_password": { + "name": "socks5_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_proxy_chain": { + "name": "socks5_proxy_chain", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "connection_origin": { + "name": "connection_origin", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mac_address": { + "name": "mac_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "wol_broadcast_address": { + "name": "wol_broadcast_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "port_knock_sequence": { + "name": "port_knock_sequence", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_fingerprint": { + "name": "host_key_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_type": { + "name": "host_key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_algorithm": { + "name": "host_key_algorithm", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "('sha256')" + }, + "host_key_first_seen": { + "name": "host_key_first_seen", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_last_verified": { + "name": "host_key_last_verified", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_changed_count": { + "name": "host_key_changed_count", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_ssh_data_user_id": { + "name": "idx_ssh_data_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_ssh_data_parent_host": { + "name": "idx_ssh_data_parent_host", + "columns": [ + "parent_host_id" + ], + "isUnique": false + }, + "idx_ssh_data_credential": { + "name": "idx_ssh_data_credential", + "columns": [ + "credential_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ssh_data_user_id_users_id_fk": { + "name": "ssh_data_user_id_users_id_fk", + "tableFrom": "ssh_data", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_data_parent_host_id_ssh_data_id_fk": { + "name": "ssh_data_parent_host_id_ssh_data_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_data", + "columnsFrom": [ + "parent_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_vault_profile_id_vault_profiles_id_fk": { + "name": "ssh_data_vault_profile_id_vault_profiles_id_fk", + "tableFrom": "ssh_data", + "tableTo": "vault_profiles", + "columnsFrom": [ + "vault_profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_rdp_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_rdp_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "rdp_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_vnc_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_vnc_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "vnc_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_telnet_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_telnet_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "telnet_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "ssh_data_id": { + "name": "ssh_data_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "ssh_data_sync_id_unique": { + "name": "ssh_data_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "network_topology": { + "name": "network_topology", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "topology": { + "name": "topology", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "network_topology_user_id_users_id_fk": { + "name": "network_topology_user_id_users_id_fk", + "tableFrom": "network_topology", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "network_topology_id": { + "name": "network_topology_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "notification_channels": { + "name": "notification_channels", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "notification_channels_user_id_users_id_fk": { + "name": "notification_channels_user_id_users_id_fk", + "tableFrom": "notification_channels", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "notification_channels_id": { + "name": "notification_channels_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "opkssh_tokens": { + "name": "opkssh_tokens", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ssh_cert": { + "name": "ssh_cert", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sub": { + "name": "sub", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "issuer": { + "name": "issuer", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "audience": { + "name": "audience", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_opkssh_tokens_user_host": { + "name": "idx_opkssh_tokens_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "opkssh_tokens_user_id_users_id_fk": { + "name": "opkssh_tokens_user_id_users_id_fk", + "tableFrom": "opkssh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "opkssh_tokens_host_id_ssh_data_id_fk": { + "name": "opkssh_tokens_host_id_ssh_data_id_fk", + "tableFrom": "opkssh_tokens", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "opkssh_tokens_id": { + "name": "opkssh_tokens_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "plugin_install_counts": { + "name": "plugin_install_counts", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "plugin_id": { + "name": "plugin_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "registry_id": { + "name": "registry_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "count": { + "name": "count", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('aggregate-telemetry')" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_plugin_install_counts_plugin_registry": { + "name": "idx_plugin_install_counts_plugin_registry", + "columns": [ + "plugin_id", + "registry_id" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "plugin_install_counts_id": { + "name": "plugin_install_counts_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "plugin_permission_grants": { + "name": "plugin_permission_grants", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "plugin_id": { + "name": "plugin_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "capability": { + "name": "capability", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "granted_at": { + "name": "granted_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_plugin_permission_grants_plugin_capability": { + "name": "idx_plugin_permission_grants_plugin_capability", + "columns": [ + "plugin_id", + "capability" + ], + "isUnique": true + } + }, + "foreignKeys": { + "plugin_permission_grants_plugin_id_plugins_id_fk": { + "name": "plugin_permission_grants_plugin_id_plugins_id_fk", + "tableFrom": "plugin_permission_grants", + "tableTo": "plugins", + "columnsFrom": [ + "plugin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "plugin_permission_grants_granted_by_users_id_fk": { + "name": "plugin_permission_grants_granted_by_users_id_fk", + "tableFrom": "plugin_permission_grants", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "plugin_permission_grants_id": { + "name": "plugin_permission_grants_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "plugin_registries": { + "name": "plugin_registries", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('community')" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "signing_key": { + "name": "signing_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_index_hash": { + "name": "last_index_hash", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "plugin_registries_id": { + "name": "plugin_registries_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "plugin_storage": { + "name": "plugin_storage", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "plugin_id": { + "name": "plugin_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "key": { + "name": "key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_plugin_storage_plugin_key": { + "name": "idx_plugin_storage_plugin_key", + "columns": [ + "plugin_id", + "key" + ], + "isUnique": true + } + }, + "foreignKeys": { + "plugin_storage_plugin_id_plugins_id_fk": { + "name": "plugin_storage_plugin_id_plugins_id_fk", + "tableFrom": "plugin_storage", + "tableTo": "plugins", + "columnsFrom": [ + "plugin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "plugin_storage_id": { + "name": "plugin_storage_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "plugins": { + "name": "plugins", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "version": { + "name": "version", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tier": { + "name": "tier", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('available')" + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('community')" + }, + "registry_id": { + "name": "registry_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('disabled')" + }, + "installed_at": { + "name": "installed_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "auto_update": { + "name": "auto_update", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "manifest_json": { + "name": "manifest_json", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_plugins_registry_id": { + "name": "idx_plugins_registry_id", + "columns": [ + "registry_id" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "plugins_id": { + "name": "plugins_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "proxmox_node_history": { + "name": "proxmox_node_history", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ts": { + "name": "ts", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "cpu_percent": { + "name": "cpu_percent", + "type": "double", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mem_percent": { + "name": "mem_percent", + "type": "double", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "disk_percent": { + "name": "disk_percent", + "type": "double", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "net_rx_bytes": { + "name": "net_rx_bytes", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "net_tx_bytes": { + "name": "net_tx_bytes", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "proxmox_node_history_host_id_ssh_data_id_fk": { + "name": "proxmox_node_history_host_id_ssh_data_id_fk", + "tableFrom": "proxmox_node_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "proxmox_node_history_id": { + "name": "proxmox_node_history_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "proxmox_stats_preferences": { + "name": "proxmox_stats_preferences", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_proxmox_stats_prefs_user_host": { + "name": "idx_proxmox_stats_prefs_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "proxmox_stats_preferences_user_id_users_id_fk": { + "name": "proxmox_stats_preferences_user_id_users_id_fk", + "tableFrom": "proxmox_stats_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "proxmox_stats_preferences_host_id_ssh_data_id_fk": { + "name": "proxmox_stats_preferences_host_id_ssh_data_id_fk", + "tableFrom": "proxmox_stats_preferences", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "proxmox_stats_preferences_id": { + "name": "proxmox_stats_preferences_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "recent_activity": { + "name": "recent_activity", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_name": { + "name": "host_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "timestamp": { + "name": "timestamp", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_recent_activity_user_ts": { + "name": "idx_recent_activity_user_ts", + "columns": [ + "user_id", + "timestamp" + ], + "isUnique": false + } + }, + "foreignKeys": { + "recent_activity_user_id_users_id_fk": { + "name": "recent_activity_user_id_users_id_fk", + "tableFrom": "recent_activity", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "recent_activity_host_id_ssh_data_id_fk": { + "name": "recent_activity_host_id_ssh_data_id_fk", + "tableFrom": "recent_activity", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "recent_activity_id": { + "name": "recent_activity_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "roles": { + "name": "roles", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_system": { + "name": "is_system", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "roles_id": { + "name": "roles_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "roles_name_unique": { + "name": "roles_name_unique", + "columns": [ + "name" + ] + } + }, + "checkConstraint": {} + }, + "secret_sources": { + "name": "secret_sources", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('onepassword-connect')" + }, + "base_url": { + "name": "base_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "shared": { + "name": "shared", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_secret_sources_user": { + "name": "idx_secret_sources_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "secret_sources_user_id_users_id_fk": { + "name": "secret_sources_user_id_users_id_fk", + "tableFrom": "secret_sources", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "secret_sources_id": { + "name": "secret_sources_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "session_recordings": { + "name": "session_recordings", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_id": { + "name": "access_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "ended_at": { + "name": "ended_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "duration": { + "name": "duration", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "commands": { + "name": "commands", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "dangerous_actions": { + "name": "dangerous_actions", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "recording_path": { + "name": "recording_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "protocol": { + "name": "protocol", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ssh'" + }, + "format": { + "name": "format", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('text')" + }, + "terminated_by_owner": { + "name": "terminated_by_owner", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "termination_reason": { + "name": "termination_reason", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_session_recordings_user_started": { + "name": "idx_session_recordings_user_started", + "columns": [ + "user_id", + "started_at" + ], + "isUnique": false + }, + "idx_session_recordings_host": { + "name": "idx_session_recordings_host", + "columns": [ + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "session_recordings_host_id_ssh_data_id_fk": { + "name": "session_recordings_host_id_ssh_data_id_fk", + "tableFrom": "session_recordings", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_recordings_user_id_users_id_fk": { + "name": "session_recordings_user_id_users_id_fk", + "tableFrom": "session_recordings", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "session_recordings_access_id_host_access_id_fk": { + "name": "session_recordings_access_id_host_access_id_fk", + "tableFrom": "session_recordings", + "tableTo": "host_access", + "columnsFrom": [ + "access_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "session_recordings_id": { + "name": "session_recordings_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "session_share_participants": { + "name": "session_share_participants", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "share_id": { + "name": "share_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "guest_label": { + "name": "guest_label", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "joined_at": { + "name": "joined_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "left_at": { + "name": "left_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "session_share_participants_share_id_session_shares_id_fk": { + "name": "session_share_participants_share_id_session_shares_id_fk", + "tableFrom": "session_share_participants", + "tableTo": "session_shares", + "columnsFrom": [ + "share_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_share_participants_user_id_users_id_fk": { + "name": "session_share_participants_user_id_users_id_fk", + "tableFrom": "session_share_participants", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "session_share_participants_id": { + "name": "session_share_participants_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "session_shares": { + "name": "session_shares", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "protocol": { + "name": "protocol", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "session_id": { + "name": "session_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tab_instance_id": { + "name": "tab_instance_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "share_type": { + "name": "share_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_user_id": { + "name": "target_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "link_token": { + "name": "link_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('read-only')" + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_joined_at": { + "name": "last_joined_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "join_count": { + "name": "join_count", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + } + }, + "indexes": { + "idx_session_shares_session_id": { + "name": "idx_session_shares_session_id", + "columns": [ + "session_id" + ], + "isUnique": false + }, + "idx_session_shares_host_id": { + "name": "idx_session_shares_host_id", + "columns": [ + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "session_shares_host_id_ssh_data_id_fk": { + "name": "session_shares_host_id_ssh_data_id_fk", + "tableFrom": "session_shares", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_shares_owner_user_id_users_id_fk": { + "name": "session_shares_owner_user_id_users_id_fk", + "tableFrom": "session_shares", + "tableTo": "users", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_shares_target_user_id_users_id_fk": { + "name": "session_shares_target_user_id_users_id_fk", + "tableFrom": "session_shares", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "session_shares_id": { + "name": "session_shares_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "session_shares_link_token_unique": { + "name": "session_shares_link_token_unique", + "columns": [ + "link_token" + ] + } + }, + "checkConstraint": {} + }, + "sessions": { + "name": "sessions", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "jwt_token": { + "name": "jwt_token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_info": { + "name": "device_info", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "oidc_sub": { + "name": "oidc_sub", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "oidc_sid": { + "name": "oidc_sid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sso_provider_id": { + "name": "sso_provider_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_active_at": { + "name": "last_active_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_sessions_user_id": { + "name": "idx_sessions_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_sessions_expires_at": { + "name": "idx_sessions_expires_at", + "columns": [ + "expires_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "sessions_id": { + "name": "sessions_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "settings": { + "name": "settings", + "columns": { + "key": { + "name": "key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "settings_key": { + "name": "settings_key", + "columns": [ + "key" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "shared_credential_secrets": { + "name": "shared_credential_secrets", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "credential_access_id": { + "name": "credential_access_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_user_id": { + "name": "target_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "credential_id": { + "name": "credential_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "encrypted_username": { + "name": "encrypted_username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('password')" + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key": { + "name": "encrypted_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key_password": { + "name": "encrypted_key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cert_public_key": { + "name": "cert_public_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_shared_credential_secrets_scope": { + "name": "idx_shared_credential_secrets_scope", + "columns": [ + "credential_access_id", + "target_user_id" + ], + "isUnique": true + }, + "idx_shared_credential_secrets_target": { + "name": "idx_shared_credential_secrets_target", + "columns": [ + "target_user_id", + "credential_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "shared_credential_secrets_target_user_id_users_id_fk": { + "name": "shared_credential_secrets_target_user_id_users_id_fk", + "tableFrom": "shared_credential_secrets", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_credential_secrets_credential_id_ssh_credentials_id_fk": { + "name": "shared_credential_secrets_credential_id_ssh_credentials_id_fk", + "tableFrom": "shared_credential_secrets", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_cred_secrets_access_id_fk": { + "name": "shared_cred_secrets_access_id_fk", + "tableFrom": "shared_credential_secrets", + "tableTo": "credential_access", + "columnsFrom": [ + "credential_access_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "shared_credential_secrets_id": { + "name": "shared_credential_secrets_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "shared_host_auth_overrides": { + "name": "shared_host_auth_overrides", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "protocol": { + "name": "protocol", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ssh'" + }, + "credential_id": { + "name": "credential_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "shared_host_auth_overrides_host_user_protocol_unique": { + "name": "shared_host_auth_overrides_host_user_protocol_unique", + "columns": [ + "host_id", + "user_id", + "protocol" + ], + "isUnique": true + } + }, + "foreignKeys": { + "shared_host_auth_overrides_host_id_ssh_data_id_fk": { + "name": "shared_host_auth_overrides_host_id_ssh_data_id_fk", + "tableFrom": "shared_host_auth_overrides", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_auth_overrides_user_id_users_id_fk": { + "name": "shared_host_auth_overrides_user_id_users_id_fk", + "tableFrom": "shared_host_auth_overrides", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_auth_overrides_credential_id_ssh_credentials_id_fk": { + "name": "shared_host_auth_overrides_credential_id_ssh_credentials_id_fk", + "tableFrom": "shared_host_auth_overrides", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "shared_host_auth_overrides_id": { + "name": "shared_host_auth_overrides_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "shared_host_secrets": { + "name": "shared_host_secrets", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "host_access_id": { + "name": "host_access_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_user_id": { + "name": "target_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "protocol": { + "name": "protocol", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ssh'" + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('credential')" + }, + "original_credential_id": { + "name": "original_credential_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_username": { + "name": "encrypted_username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_auth_type": { + "name": "encrypted_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key": { + "name": "encrypted_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key_password": { + "name": "encrypted_key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key_type": { + "name": "encrypted_key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_domain": { + "name": "encrypted_domain", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_shared_host_secrets_scope": { + "name": "idx_shared_host_secrets_scope", + "columns": [ + "host_access_id", + "target_user_id", + "protocol" + ], + "isUnique": true + } + }, + "foreignKeys": { + "shared_host_secrets_host_access_id_host_access_id_fk": { + "name": "shared_host_secrets_host_access_id_host_access_id_fk", + "tableFrom": "shared_host_secrets", + "tableTo": "host_access", + "columnsFrom": [ + "host_access_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_secrets_target_user_id_users_id_fk": { + "name": "shared_host_secrets_target_user_id_users_id_fk", + "tableFrom": "shared_host_secrets", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_secrets_original_credential_id_ssh_credentials_id_fk": { + "name": "shared_host_secrets_original_credential_id_ssh_credentials_id_fk", + "tableFrom": "shared_host_secrets", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "original_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "shared_host_secrets_id": { + "name": "shared_host_secrets_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "snippet_access": { + "name": "snippet_access", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "snippet_id": { + "name": "snippet_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('view')" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_snippet_access_user_id": { + "name": "idx_snippet_access_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_snippet_access_snippet_id": { + "name": "idx_snippet_access_snippet_id", + "columns": [ + "snippet_id" + ], + "isUnique": false + }, + "idx_snippet_access_role_id": { + "name": "idx_snippet_access_role_id", + "columns": [ + "role_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "snippet_access_snippet_id_snippets_id_fk": { + "name": "snippet_access_snippet_id_snippets_id_fk", + "tableFrom": "snippet_access", + "tableTo": "snippets", + "columnsFrom": [ + "snippet_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "snippet_access_user_id_users_id_fk": { + "name": "snippet_access_user_id_users_id_fk", + "tableFrom": "snippet_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "snippet_access_role_id_roles_id_fk": { + "name": "snippet_access_role_id_roles_id_fk", + "tableFrom": "snippet_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "snippet_access_granted_by_users_id_fk": { + "name": "snippet_access_granted_by_users_id_fk", + "tableFrom": "snippet_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "snippet_access_id": { + "name": "snippet_access_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "snippet_folders": { + "name": "snippet_folders", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "snippet_folders_user_id_users_id_fk": { + "name": "snippet_folders_user_id_users_id_fk", + "tableFrom": "snippet_folders", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "snippet_folders_id": { + "name": "snippet_folders_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "snippet_folders_sync_id_unique": { + "name": "snippet_folders_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "snippets": { + "name": "snippets", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "order": { + "name": "order", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "host_filter": { + "name": "host_filter", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_note": { + "name": "is_note", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": { + "idx_snippets_user_id": { + "name": "idx_snippets_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "snippets_user_id_users_id_fk": { + "name": "snippets_user_id_users_id_fk", + "tableFrom": "snippets", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "snippets_id": { + "name": "snippets_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "snippets_sync_id_unique": { + "name": "snippets_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "ssh_credential_usage": { + "name": "ssh_credential_usage", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "credential_id": { + "name": "credential_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "used_at": { + "name": "used_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_ssh_credential_usage_credential": { + "name": "idx_ssh_credential_usage_credential", + "columns": [ + "credential_id" + ], + "isUnique": false + }, + "idx_ssh_credential_usage_user": { + "name": "idx_ssh_credential_usage_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ssh_credential_usage_credential_id_ssh_credentials_id_fk": { + "name": "ssh_credential_usage_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_credential_usage", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_credential_usage_host_id_ssh_data_id_fk": { + "name": "ssh_credential_usage_host_id_ssh_data_id_fk", + "tableFrom": "ssh_credential_usage", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_credential_usage_user_id_users_id_fk": { + "name": "ssh_credential_usage_user_id_users_id_fk", + "tableFrom": "ssh_credential_usage", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "ssh_credential_usage_id": { + "name": "ssh_credential_usage_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "ssh_credentials": { + "name": "ssh_credentials", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tags": { + "name": "tags", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "pin": { + "name": "pin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "sort_order": { + "name": "sort_order", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_password": { + "name": "key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "detected_key_type": { + "name": "detected_key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cert_public_key": { + "name": "cert_public_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "usage_count": { + "name": "usage_count", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_ssh_credentials_user_id": { + "name": "idx_ssh_credentials_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ssh_credentials_user_id_users_id_fk": { + "name": "ssh_credentials_user_id_users_id_fk", + "tableFrom": "ssh_credentials", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "ssh_credentials_id": { + "name": "ssh_credentials_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "ssh_credentials_sync_id_unique": { + "name": "ssh_credentials_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "ssh_folders": { + "name": "ssh_folders", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "credential_id": { + "name": "credential_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sort_order": { + "name": "sort_order", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_ssh_folders_user_id": { + "name": "idx_ssh_folders_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ssh_folders_user_id_users_id_fk": { + "name": "ssh_folders_user_id_users_id_fk", + "tableFrom": "ssh_folders", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_folders_credential_id_ssh_credentials_id_fk": { + "name": "ssh_folders_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_folders", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "ssh_folders_id": { + "name": "ssh_folders_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "ssh_folders_sync_id_unique": { + "name": "ssh_folders_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "sso_providers": { + "name": "sso_providers", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "display_order": { + "name": "display_order", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "sso_providers_id": { + "name": "sso_providers_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "sync_tombstones": { + "name": "sync_tombstones", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "sync_tombstones_user_id_users_id_fk": { + "name": "sync_tombstones_user_id_users_id_fk", + "tableFrom": "sync_tombstones", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "sync_tombstones_id": { + "name": "sync_tombstones_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "termix_identities": { + "name": "termix_identities", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "handle": { + "name": "handle", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "termix_identities_user_id_users_id_fk": { + "name": "termix_identities_user_id_users_id_fk", + "tableFrom": "termix_identities", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "termix_identities_id": { + "name": "termix_identities_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "termix_identities_user_id_unique": { + "name": "termix_identities_user_id_unique", + "columns": [ + "user_id" + ] + }, + "termix_identities_handle_unique": { + "name": "termix_identities_handle_unique", + "columns": [ + "handle" + ] + } + }, + "checkConstraint": {} + }, + "termix_identity_ca": { + "name": "termix_identity_ca", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "identity_id": { + "name": "identity_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "validity_days": { + "name": "validity_days", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 90 + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "termix_identity_ca_identity_id_termix_identities_id_fk": { + "name": "termix_identity_ca_identity_id_termix_identities_id_fk", + "tableFrom": "termix_identity_ca", + "tableTo": "termix_identities", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "termix_identity_ca_user_id_users_id_fk": { + "name": "termix_identity_ca_user_id_users_id_fk", + "tableFrom": "termix_identity_ca", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "termix_identity_ca_id": { + "name": "termix_identity_ca_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "termix_identity_ca_identity_id_unique": { + "name": "termix_identity_ca_identity_id_unique", + "columns": [ + "identity_id" + ] + } + }, + "checkConstraint": {} + }, + "termix_identity_keys": { + "name": "termix_identity_keys", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "identity_id": { + "name": "identity_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "algorithm": { + "name": "algorithm", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "label": { + "name": "label", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "comment": { + "name": "comment", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('manual')" + }, + "credential_id": { + "name": "credential_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "termix_identity_keys_identity_id_termix_identities_id_fk": { + "name": "termix_identity_keys_identity_id_termix_identities_id_fk", + "tableFrom": "termix_identity_keys", + "tableTo": "termix_identities", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "termix_identity_keys_user_id_users_id_fk": { + "name": "termix_identity_keys_user_id_users_id_fk", + "tableFrom": "termix_identity_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "termix_identity_keys_credential_id_ssh_credentials_id_fk": { + "name": "termix_identity_keys_credential_id_ssh_credentials_id_fk", + "tableFrom": "termix_identity_keys", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "termix_identity_keys_id": { + "name": "termix_identity_keys_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "tmux_session_tags": { + "name": "tmux_session_tags", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "session_name": { + "name": "session_name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tag": { + "name": "tag", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "tmux_session_tags_user_id_users_id_fk": { + "name": "tmux_session_tags_user_id_users_id_fk", + "tableFrom": "tmux_session_tags", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tmux_session_tags_host_id_ssh_data_id_fk": { + "name": "tmux_session_tags_host_id_ssh_data_id_fk", + "tableFrom": "tmux_session_tags", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "tmux_session_tags_id": { + "name": "tmux_session_tags_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "transfer_recent": { + "name": "transfer_recent", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_host_id": { + "name": "source_host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dest_host_id": { + "name": "dest_host_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dest_path": { + "name": "dest_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dest_path_label": { + "name": "dest_path_label", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_transfer_recent_user": { + "name": "idx_transfer_recent_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "transfer_recent_user_id_users_id_fk": { + "name": "transfer_recent_user_id_users_id_fk", + "tableFrom": "transfer_recent", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "transfer_recent_source_host_id_ssh_data_id_fk": { + "name": "transfer_recent_source_host_id_ssh_data_id_fk", + "tableFrom": "transfer_recent", + "tableTo": "ssh_data", + "columnsFrom": [ + "source_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "transfer_recent_dest_host_id_ssh_data_id_fk": { + "name": "transfer_recent_dest_host_id_ssh_data_id_fk", + "tableFrom": "transfer_recent", + "tableTo": "ssh_data", + "columnsFrom": [ + "dest_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "transfer_recent_id": { + "name": "transfer_recent_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "trusted_devices": { + "name": "trusted_devices", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_fingerprint": { + "name": "device_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_info": { + "name": "device_info", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_trusted_devices_user_id": { + "name": "idx_trusted_devices_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "trusted_devices_user_id_users_id_fk": { + "name": "trusted_devices_user_id_users_id_fk", + "tableFrom": "trusted_devices", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "trusted_devices_id": { + "name": "trusted_devices_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "ui_preferences": { + "name": "ui_preferences", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "ui_preferences_user_id_users_id_fk": { + "name": "ui_preferences_user_id_users_id_fk", + "tableFrom": "ui_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "ui_preferences_user_id": { + "name": "ui_preferences_user_id", + "columns": [ + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "user_open_tabs": { + "name": "user_open_tabs", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tab_type": { + "name": "tab_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "label": { + "name": "label", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tab_order": { + "name": "tab_order", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "backend_session_id": { + "name": "backend_session_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_user_open_tabs_user_id": { + "name": "idx_user_open_tabs_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "user_open_tabs_user_id_users_id_fk": { + "name": "user_open_tabs_user_id_users_id_fk", + "tableFrom": "user_open_tabs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_open_tabs_host_id_ssh_data_id_fk": { + "name": "user_open_tabs_host_id_ssh_data_id_fk", + "tableFrom": "user_open_tabs", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_open_tabs_id": { + "name": "user_open_tabs_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "user_preferences": { + "name": "user_preferences", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "reopen_tabs_on_login": { + "name": "reopen_tabs_on_login", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "font_size": { + "name": "font_size", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "language": { + "name": "language", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "storage_mode": { + "name": "storage_mode", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "command_autocomplete": { + "name": "command_autocomplete", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "command_palette_enabled": { + "name": "command_palette_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_host_tags": { + "name": "show_host_tags", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_tray_on_click": { + "name": "host_tray_on_click", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "pin_app_rail": { + "name": "pin_app_rail", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expand_app_rail_on_hover": { + "name": "expand_app_rail_on_hover", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_pin_app_rail_button": { + "name": "show_pin_app_rail_button", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "folders_collapsed": { + "name": "folders_collapsed", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "confirm_snippet_execution": { + "name": "confirm_snippet_execution", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "disable_update_check": { + "name": "disable_update_check", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "confirm_tab_close": { + "name": "confirm_tab_close", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "hidden_rail_tabs": { + "name": "hidden_rail_tabs", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_assistant_enabled": { + "name": "ai_assistant_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_read_only_commands": { + "name": "ai_read_only_commands", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "compact_host_view": { + "name": "compact_host_view", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "status_color_scheme": { + "name": "status_color_scheme", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "custom_themes": { + "name": "custom_themes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "custom_keybindings": { + "name": "custom_keybindings", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "terminal_defaults": { + "name": "terminal_defaults", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_defaults": { + "name": "rdp_defaults", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "terminal_macros": { + "name": "terminal_macros", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "user_preferences_user_id_users_id_fk": { + "name": "user_preferences_user_id_users_id_fk", + "tableFrom": "user_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_preferences_user_id": { + "name": "user_preferences_user_id", + "columns": [ + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "user_roles": { + "name": "user_roles", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_at": { + "name": "granted_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "idx_user_roles_user_role": { + "name": "idx_user_roles_user_role", + "columns": [ + "user_id", + "role_id" + ], + "isUnique": true + }, + "idx_user_roles_role_id": { + "name": "idx_user_roles_role_id", + "columns": [ + "role_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "user_roles_user_id_users_id_fk": { + "name": "user_roles_user_id_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_role_id_roles_id_fk": { + "name": "user_roles_role_id_roles_id_fk", + "tableFrom": "user_roles", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_granted_by_users_id_fk": { + "name": "user_roles_granted_by_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_roles_id": { + "name": "user_roles_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "user_workspaces": { + "name": "user_workspaces", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('manual')" + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('{}')" + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_user_workspaces_user_id": { + "name": "idx_user_workspaces_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "user_workspaces_user_id_users_id_fk": { + "name": "user_workspaces_user_id_users_id_fk", + "tableFrom": "user_workspaces", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_workspaces_id": { + "name": "user_workspaces_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "user_workspaces_sync_id_unique": { + "name": "user_workspaces_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "users": { + "name": "users", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "is_admin": { + "name": "is_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "is_oidc": { + "name": "is_oidc", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "oidc_identifier": { + "name": "oidc_identifier", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sso_provider_id": { + "name": "sso_provider_id", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "client_secret": { + "name": "client_secret", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "issuer_url": { + "name": "issuer_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "authorization_url": { + "name": "authorization_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token_url": { + "name": "token_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "identifier_path": { + "name": "identifier_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name_path": { + "name": "name_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scopes": { + "name": "scopes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "('openid email profile')" + }, + "totp_secret": { + "name": "totp_secret", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "totp_enabled": { + "name": "totp_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "totp_backup_codes": { + "name": "totp_backup_codes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "registered_at": { + "name": "registered_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "donation_modal_dismissed": { + "name": "donation_modal_dismissed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "users_id": { + "name": "users_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "vault_profiles": { + "name": "vault_profiles", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tags": { + "name": "tags", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vault_addr": { + "name": "vault_addr", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "vault_namespace": { + "name": "vault_namespace", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "oidc_mount": { + "name": "oidc_mount", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "oidc_role": { + "name": "oidc_role", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ssh_mount": { + "name": "ssh_mount", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ssh_role": { + "name": "ssh_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "valid_principals": { + "name": "valid_principals", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "shared": { + "name": "shared", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "vault_profiles_user_id_users_id_fk": { + "name": "vault_profiles_user_id_users_id_fk", + "tableFrom": "vault_profiles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "vault_profiles_id": { + "name": "vault_profiles_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "vault_profiles_sync_id_unique": { + "name": "vault_profiles_sync_id_unique", + "columns": [ + "sync_id" + ] + } + }, + "checkConstraint": {} + }, + "vault_tokens": { + "name": "vault_tokens", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "profile_id": { + "name": "profile_id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ssh_cert": { + "name": "ssh_cert", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_vault_tokens_user_profile": { + "name": "idx_vault_tokens_user_profile", + "columns": [ + "user_id", + "profile_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "vault_tokens_user_id_users_id_fk": { + "name": "vault_tokens_user_id_users_id_fk", + "tableFrom": "vault_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "vault_tokens_profile_id_vault_profiles_id_fk": { + "name": "vault_tokens_profile_id_vault_profiles_id_fk", + "tableFrom": "vault_tokens", + "tableTo": "vault_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "vault_tokens_id": { + "name": "vault_tokens_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "webauthn_credentials": { + "name": "webauthn_credentials", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "credential_id": { + "name": "credential_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "counter": { + "name": "counter", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "backed_up": { + "name": "backed_up", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "transports": { + "name": "transports", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_verification": { + "name": "user_verification", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('preferred')" + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "webauthn_credentials_user_id_users_id_fk": { + "name": "webauthn_credentials_user_id_users_id_fk", + "tableFrom": "webauthn_credentials", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "webauthn_credentials_id": { + "name": "webauthn_credentials_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + } + }, + "views": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "tables": {}, + "indexes": {} + } +} \ No newline at end of file diff --git a/drizzle/mysql/meta/_journal.json b/drizzle/mysql/meta/_journal.json index 16169dbc9..d69201202 100644 --- a/drizzle/mysql/meta/_journal.json +++ b/drizzle/mysql/meta/_journal.json @@ -176,6 +176,13 @@ "when": 1789991404402, "tag": "0024_thin_colleen_wing", "breakpoints": true + }, + { + "idx": 25, + "version": "5", + "when": 1790083819606, + "tag": "0025_wet_master_mold", + "breakpoints": true } ] } \ No newline at end of file diff --git a/drizzle/postgres/0026_perfect_masque.sql b/drizzle/postgres/0026_perfect_masque.sql new file mode 100644 index 000000000..f4e656f99 --- /dev/null +++ b/drizzle/postgres/0026_perfect_masque.sql @@ -0,0 +1,3 @@ +DROP TABLE "alert_firings" CASCADE;--> statement-breakpoint +DROP TABLE "alert_rule_channels" CASCADE;--> statement-breakpoint +DROP TABLE "alert_rules" CASCADE; \ No newline at end of file diff --git a/drizzle/postgres/meta/0026_snapshot.json b/drizzle/postgres/meta/0026_snapshot.json new file mode 100644 index 000000000..823cdd165 --- /dev/null +++ b/drizzle/postgres/meta/0026_snapshot.json @@ -0,0 +1,9468 @@ +{ + "id": "9d5495bc-c4df-4c7a-8c1c-2f0a7c35aeaa", + "prevId": "b291d411-eff4-4a65-854d-a70e22c17f67", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.ai_conversations": { + "name": "ai_conversations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_id": { + "name": "provider_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ai_conversations_user": { + "name": "idx_ai_conversations_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ai_conversations_user_id_users_id_fk": { + "name": "ai_conversations_user_id_users_id_fk", + "tableFrom": "ai_conversations", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ai_messages": { + "name": "ai_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "tool_calls": { + "name": "tool_calls", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ai_messages_conversation": { + "name": "idx_ai_messages_conversation", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ai_messages_conversation_id_ai_conversations_id_fk": { + "name": "ai_messages_conversation_id_ai_conversations_id_fk", + "tableFrom": "ai_messages", + "tableTo": "ai_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ai_proposals": { + "name": "ai_proposals", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "applied_at": { + "name": "applied_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "result_summary": { + "name": "result_summary", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ai_proposals_user": { + "name": "idx_ai_proposals_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_ai_proposals_conversation": { + "name": "idx_ai_proposals_conversation", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ai_proposals_conversation_id_ai_conversations_id_fk": { + "name": "ai_proposals_conversation_id_ai_conversations_id_fk", + "tableFrom": "ai_proposals", + "tableTo": "ai_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ai_proposals_user_id_users_id_fk": { + "name": "ai_proposals_user_id_users_id_fk", + "tableFrom": "ai_proposals", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ai_providers": { + "name": "ai_providers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_type": { + "name": "provider_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "base_url": { + "name": "base_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key": { + "name": "api_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_prefix": { + "name": "api_key_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_model": { + "name": "default_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ai_providers_user_label": { + "name": "idx_ai_providers_user_label", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "label", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ai_providers_user_id_users_id_fk": { + "name": "ai_providers_user_id_users_id_fk", + "tableFrom": "ai_providers", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.api_keys": { + "name": "api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_prefix": { + "name": "token_prefix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + } + }, + "indexes": { + "idx_api_keys_user_id": { + "name": "idx_api_keys_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_keys_user_id_users_id_fk": { + "name": "api_keys_user_id_users_id_fk", + "tableFrom": "api_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resource_name": { + "name": "resource_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "details": { + "name": "details", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "success": { + "name": "success", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "timestamp": { + "name": "timestamp", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_audit_logs_timestamp": { + "name": "idx_audit_logs_timestamp", + "columns": [ + { + "expression": "timestamp", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_logs_user_ts": { + "name": "idx_audit_logs_user_ts", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "timestamp", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_logs_action_ts": { + "name": "idx_audit_logs_action_ts", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "timestamp", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_logs_resource_ts": { + "name": "idx_audit_logs_resource_ts", + "columns": [ + { + "expression": "resource_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "timestamp", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_user_id_users_id_fk": { + "name": "audit_logs_user_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.automation_channels": { + "name": "automation_channels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "automation_id": { + "name": "automation_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "channel_id": { + "name": "channel_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "idx_automation_channels_pair": { + "name": "idx_automation_channels_pair", + "columns": [ + { + "expression": "automation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "channel_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "automation_channels_automation_id_automations_id_fk": { + "name": "automation_channels_automation_id_automations_id_fk", + "tableFrom": "automation_channels", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "automation_channels_channel_id_notification_channels_id_fk": { + "name": "automation_channels_channel_id_notification_channels_id_fk", + "tableFrom": "automation_channels", + "tableTo": "notification_channels", + "columnsFrom": [ + "channel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.automation_run_steps": { + "name": "automation_run_steps", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "run_id": { + "name": "run_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "step_index": { + "name": "step_index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "step_id": { + "name": "step_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "step_type": { + "name": "step_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "finished_at": { + "name": "finished_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "output": { + "name": "output", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "truncated": { + "name": "truncated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "idx_automation_run_steps_run": { + "name": "idx_automation_run_steps_run", + "columns": [ + { + "expression": "run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "step_index", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "automation_run_steps_run_id_automation_runs_id_fk": { + "name": "automation_run_steps_run_id_automation_runs_id_fk", + "tableFrom": "automation_run_steps", + "tableTo": "automation_runs", + "columnsFrom": [ + "run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.automation_runs": { + "name": "automation_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "automation_id": { + "name": "automation_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "trigger_type": { + "name": "trigger_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "trigger_context": { + "name": "trigger_context", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "finished_at": { + "name": "finished_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dry_run": { + "name": "dry_run", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "parent_run_id": { + "name": "parent_run_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_automation_runs_automation": { + "name": "idx_automation_runs_automation", + "columns": [ + { + "expression": "automation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "started_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_automation_runs_user": { + "name": "idx_automation_runs_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "started_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "automation_runs_automation_id_automations_id_fk": { + "name": "automation_runs_automation_id_automations_id_fk", + "tableFrom": "automation_runs", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "automation_runs_user_id_users_id_fk": { + "name": "automation_runs_user_id_users_id_fk", + "tableFrom": "automation_runs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.automation_schedules": { + "name": "automation_schedules", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "automation_id": { + "name": "automation_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "cron": { + "name": "cron", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "interval_seconds": { + "name": "interval_seconds", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "next_due_at": { + "name": "next_due_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "last_tick_at": { + "name": "last_tick_at", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_automation_schedules_automation": { + "name": "idx_automation_schedules_automation", + "columns": [ + { + "expression": "automation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_automation_schedules_due": { + "name": "idx_automation_schedules_due", + "columns": [ + { + "expression": "next_due_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "automation_schedules_automation_id_automations_id_fk": { + "name": "automation_schedules_automation_id_automations_id_fk", + "tableFrom": "automation_schedules", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.automation_trigger_state": { + "name": "automation_trigger_state", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "automation_id": { + "name": "automation_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "state_key": { + "name": "state_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "breach_started_at": { + "name": "breach_started_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_fired_at": { + "name": "last_fired_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_value": { + "name": "last_value", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "last_observed_state": { + "name": "last_observed_state", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_automation_trigger_state_key": { + "name": "idx_automation_trigger_state_key", + "columns": [ + { + "expression": "automation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "state_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "automation_trigger_state_automation_id_automations_id_fk": { + "name": "automation_trigger_state_automation_id_automations_id_fk", + "tableFrom": "automation_trigger_state", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.automations": { + "name": "automations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "definition": { + "name": "definition", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "definition_version": { + "name": "definition_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "concurrency_policy": { + "name": "concurrency_policy", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'skip'" + }, + "max_run_seconds": { + "name": "max_run_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 300 + }, + "dry_run": { + "name": "dry_run", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_run_at": { + "name": "last_run_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_run_status": { + "name": "last_run_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_automations_user": { + "name": "idx_automations_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "enabled", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "automations_user_id_users_id_fk": { + "name": "automations_user_id_users_id_fk", + "tableFrom": "automations", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.c2s_tunnel_presets": { + "name": "c2s_tunnel_presets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "computer_name": { + "name": "computer_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "c2s_tunnel_presets_user_id_users_id_fk": { + "name": "c2s_tunnel_presets_user_id_users_id_fk", + "tableFrom": "c2s_tunnel_presets", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.collab_room_members": { + "name": "collab_room_members", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "room_id": { + "name": "room_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "room_role": { + "name": "room_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "added_by": { + "name": "added_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_collab_room_members_room_user": { + "name": "idx_collab_room_members_room_user", + "columns": [ + { + "expression": "room_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_collab_room_members_user": { + "name": "idx_collab_room_members_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "collab_room_members_room_id_collab_rooms_id_fk": { + "name": "collab_room_members_room_id_collab_rooms_id_fk", + "tableFrom": "collab_room_members", + "tableTo": "collab_rooms", + "columnsFrom": [ + "room_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "collab_room_members_user_id_users_id_fk": { + "name": "collab_room_members_user_id_users_id_fk", + "tableFrom": "collab_room_members", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "collab_room_members_added_by_users_id_fk": { + "name": "collab_room_members_added_by_users_id_fk", + "tableFrom": "collab_room_members", + "tableTo": "users", + "columnsFrom": [ + "added_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.collab_rooms": { + "name": "collab_rooms", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "persistent": { + "name": "persistent", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "presenter_user_id": { + "name": "presenter_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "stage_protocol": { + "name": "stage_protocol", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stage_host_id": { + "name": "stage_host_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "stage_share_id": { + "name": "stage_share_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "guest_link_token": { + "name": "guest_link_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "ended_at": { + "name": "ended_at", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_collab_rooms_owner": { + "name": "idx_collab_rooms_owner", + "columns": [ + { + "expression": "owner_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_collab_rooms_guest_token": { + "name": "idx_collab_rooms_guest_token", + "columns": [ + { + "expression": "guest_link_token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "collab_rooms_owner_user_id_users_id_fk": { + "name": "collab_rooms_owner_user_id_users_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "users", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "collab_rooms_presenter_user_id_users_id_fk": { + "name": "collab_rooms_presenter_user_id_users_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "users", + "columnsFrom": [ + "presenter_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "collab_rooms_stage_host_id_ssh_data_id_fk": { + "name": "collab_rooms_stage_host_id_ssh_data_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "ssh_data", + "columnsFrom": [ + "stage_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "collab_rooms_stage_share_id_session_shares_id_fk": { + "name": "collab_rooms_stage_share_id_session_shares_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "session_shares", + "columnsFrom": [ + "stage_share_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.command_history": { + "name": "command_history", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "executed_at": { + "name": "executed_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_command_history_user_host": { + "name": "idx_command_history_user_host", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "command_history_user_id_users_id_fk": { + "name": "command_history_user_id_users_id_fk", + "tableFrom": "command_history", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "command_history_host_id_ssh_data_id_fk": { + "name": "command_history_host_id_ssh_data_id_fk", + "tableFrom": "command_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.credential_access": { + "name": "credential_access", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'use'" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_credential_access_user_id": { + "name": "idx_credential_access_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_credential_access_role_id": { + "name": "idx_credential_access_role_id", + "columns": [ + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_credential_access_credential_id": { + "name": "idx_credential_access_credential_id", + "columns": [ + { + "expression": "credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "credential_access_credential_id_ssh_credentials_id_fk": { + "name": "credential_access_credential_id_ssh_credentials_id_fk", + "tableFrom": "credential_access", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credential_access_user_id_users_id_fk": { + "name": "credential_access_user_id_users_id_fk", + "tableFrom": "credential_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credential_access_role_id_roles_id_fk": { + "name": "credential_access_role_id_roles_id_fk", + "tableFrom": "credential_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credential_access_granted_by_users_id_fk": { + "name": "credential_access_granted_by_users_id_fk", + "tableFrom": "credential_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.credential_sidebar_preferences": { + "name": "credential_sidebar_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "credential_sidebar_preferences_user_id_users_id_fk": { + "name": "credential_sidebar_preferences_user_id_users_id_fk", + "tableFrom": "credential_sidebar_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dashboard_service_links": { + "name": "dashboard_service_links", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "dashboard_service_links_user_id_users_id_fk": { + "name": "dashboard_service_links_user_id_users_id_fk", + "tableFrom": "dashboard_service_links", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "dashboard_service_links_sync_id_unique": { + "name": "dashboard_service_links_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dismissed_alerts": { + "name": "dismissed_alerts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "alert_id": { + "name": "alert_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dismissed_at": { + "name": "dismissed_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_dismissed_alerts_user_id": { + "name": "idx_dismissed_alerts_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dismissed_alerts_user_id_users_id_fk": { + "name": "dismissed_alerts_user_id_users_id_fk", + "tableFrom": "dismissed_alerts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.file_manager_pinned": { + "name": "file_manager_pinned", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pinned_at": { + "name": "pinned_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_file_manager_pinned_user": { + "name": "idx_file_manager_pinned_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "file_manager_pinned_user_id_users_id_fk": { + "name": "file_manager_pinned_user_id_users_id_fk", + "tableFrom": "file_manager_pinned", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "file_manager_pinned_host_id_ssh_data_id_fk": { + "name": "file_manager_pinned_host_id_ssh_data_id_fk", + "tableFrom": "file_manager_pinned", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.file_manager_recent": { + "name": "file_manager_recent", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_opened": { + "name": "last_opened", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_file_manager_recent_user": { + "name": "idx_file_manager_recent_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "file_manager_recent_user_id_users_id_fk": { + "name": "file_manager_recent_user_id_users_id_fk", + "tableFrom": "file_manager_recent", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "file_manager_recent_host_id_ssh_data_id_fk": { + "name": "file_manager_recent_host_id_ssh_data_id_fk", + "tableFrom": "file_manager_recent", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.file_manager_shortcuts": { + "name": "file_manager_shortcuts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_file_manager_shortcuts_user": { + "name": "idx_file_manager_shortcuts_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "file_manager_shortcuts_user_id_users_id_fk": { + "name": "file_manager_shortcuts_user_id_users_id_fk", + "tableFrom": "file_manager_shortcuts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "file_manager_shortcuts_host_id_ssh_data_id_fk": { + "name": "file_manager_shortcuts_host_id_ssh_data_id_fk", + "tableFrom": "file_manager_shortcuts", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.fleet_inventory": { + "name": "fleet_inventory", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "os_pretty_name": { + "name": "os_pretty_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kernel": { + "name": "kernel", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "architecture": { + "name": "architecture", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uptime_seconds": { + "name": "uptime_seconds", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "package_manager": { + "name": "package_manager", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "collected_at": { + "name": "collected_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_fleet_inventory_host": { + "name": "idx_fleet_inventory_host", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_fleet_inventory_user": { + "name": "idx_fleet_inventory_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "fleet_inventory_host_id_ssh_data_id_fk": { + "name": "fleet_inventory_host_id_ssh_data_id_fk", + "tableFrom": "fleet_inventory", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "fleet_inventory_user_id_users_id_fk": { + "name": "fleet_inventory_user_id_users_id_fk", + "tableFrom": "fleet_inventory", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.fleet_members": { + "name": "fleet_members", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "fleet_id": { + "name": "fleet_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "added_at": { + "name": "added_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_fleet_members_fleet_host": { + "name": "idx_fleet_members_fleet_host", + "columns": [ + { + "expression": "fleet_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_fleet_members_host": { + "name": "idx_fleet_members_host", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "fleet_members_fleet_id_fleets_id_fk": { + "name": "fleet_members_fleet_id_fleets_id_fk", + "tableFrom": "fleet_members", + "tableTo": "fleets", + "columnsFrom": [ + "fleet_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "fleet_members_host_id_ssh_data_id_fk": { + "name": "fleet_members_host_id_ssh_data_id_fk", + "tableFrom": "fleet_members", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.fleets": { + "name": "fleets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tag_rules": { + "name": "tag_rules", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "fleets_user_id_users_id_fk": { + "name": "fleets_user_id_users_id_fk", + "tableFrom": "fleets", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "fleets_sync_id_unique": { + "name": "fleets_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.folder_access": { + "name": "folder_access", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'connect'" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_folder_access_owner_folder": { + "name": "idx_folder_access_owner_folder", + "columns": [ + { + "expression": "owner_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "folder", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "folder_access_owner_user_id_users_id_fk": { + "name": "folder_access_owner_user_id_users_id_fk", + "tableFrom": "folder_access", + "tableTo": "users", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "folder_access_user_id_users_id_fk": { + "name": "folder_access_user_id_users_id_fk", + "tableFrom": "folder_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "folder_access_role_id_roles_id_fk": { + "name": "folder_access_role_id_roles_id_fk", + "tableFrom": "folder_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "folder_access_granted_by_users_id_fk": { + "name": "folder_access_granted_by_users_id_fk", + "tableFrom": "folder_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.homepage_items": { + "name": "homepage_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "type_id": { + "name": "type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "folder_id": { + "name": "folder_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_homepage_items_user_id": { + "name": "idx_homepage_items_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "homepage_items_user_id_users_id_fk": { + "name": "homepage_items_user_id_users_id_fk", + "tableFrom": "homepage_items", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "homepage_items_sync_id_unique": { + "name": "homepage_items_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.homepage_layouts": { + "name": "homepage_layouts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "homepage_layouts_user_id_users_id_fk": { + "name": "homepage_layouts_user_id_users_id_fk", + "tableFrom": "homepage_layouts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "homepage_layouts_user_id_unique": { + "name": "homepage_layouts_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.host_access": { + "name": "host_access", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'connect'" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "last_accessed_at": { + "name": "last_accessed_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_count": { + "name": "access_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "idx_host_access_user_id": { + "name": "idx_host_access_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_host_access_role_id": { + "name": "idx_host_access_role_id", + "columns": [ + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_host_access_host_id": { + "name": "idx_host_access_host_id", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_host_access_expires_at": { + "name": "idx_host_access_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "host_access_host_id_ssh_data_id_fk": { + "name": "host_access_host_id_ssh_data_id_fk", + "tableFrom": "host_access", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_access_user_id_users_id_fk": { + "name": "host_access_user_id_users_id_fk", + "tableFrom": "host_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_access_role_id_roles_id_fk": { + "name": "host_access_role_id_roles_id_fk", + "tableFrom": "host_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_access_granted_by_users_id_fk": { + "name": "host_access_granted_by_users_id_fk", + "tableFrom": "host_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.host_health_checks": { + "name": "host_health_checks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "checks": { + "name": "checks", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "interval_seconds": { + "name": "interval_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 300 + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_host_health_checks_user_host": { + "name": "idx_host_health_checks_user_host", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "host_health_checks_user_id_users_id_fk": { + "name": "host_health_checks_user_id_users_id_fk", + "tableFrom": "host_health_checks", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_health_checks_host_id_ssh_data_id_fk": { + "name": "host_health_checks_host_id_ssh_data_id_fk", + "tableFrom": "host_health_checks", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.host_health_history": { + "name": "host_health_history", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "check_id": { + "name": "check_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "ts": { + "name": "ts", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "ok": { + "name": "ok", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "latency_ms": { + "name": "latency_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "detail": { + "name": "detail", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "host_health_history_user_id_users_id_fk": { + "name": "host_health_history_user_id_users_id_fk", + "tableFrom": "host_health_history", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_health_history_host_id_ssh_data_id_fk": { + "name": "host_health_history_host_id_ssh_data_id_fk", + "tableFrom": "host_health_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.host_metrics_history": { + "name": "host_metrics_history", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "ts": { + "name": "ts", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "cpu_percent": { + "name": "cpu_percent", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "mem_percent": { + "name": "mem_percent", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "disk_percent": { + "name": "disk_percent", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "net_rx_bytes": { + "name": "net_rx_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "net_tx_bytes": { + "name": "net_tx_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "host_metrics_history_host_id_ssh_data_id_fk": { + "name": "host_metrics_history_host_id_ssh_data_id_fk", + "tableFrom": "host_metrics_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.host_metrics_preferences": { + "name": "host_metrics_preferences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_host_metrics_prefs_user_host": { + "name": "idx_host_metrics_prefs_user_host", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "host_metrics_preferences_user_id_users_id_fk": { + "name": "host_metrics_preferences_user_id_users_id_fk", + "tableFrom": "host_metrics_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_metrics_preferences_host_id_ssh_data_id_fk": { + "name": "host_metrics_preferences_host_id_ssh_data_id_fk", + "tableFrom": "host_metrics_preferences", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.host_sidebar_preferences": { + "name": "host_sidebar_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "host_sidebar_preferences_user_id_users_id_fk": { + "name": "host_sidebar_preferences_user_id_users_id_fk", + "tableFrom": "host_sidebar_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ssh_data": { + "name": "ssh_data", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "connection_type": { + "name": "connection_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'ssh'" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "parent_host_id": { + "name": "parent_host_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "tags": { + "name": "tags", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pin": { + "name": "pin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "use_warpgate": { + "name": "use_warpgate", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "share_ssh_auth": { + "name": "share_ssh_auth", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "force_keyboard_interactive": { + "name": "force_keyboard_interactive", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key_password": { + "name": "key_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sudo_password": { + "name": "sudo_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "autostart_password": { + "name": "autostart_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "autostart_key": { + "name": "autostart_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "autostart_key_password": { + "name": "autostart_key_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "override_credential_username": { + "name": "override_credential_username", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "vault_profile_id": { + "name": "vault_profile_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "enable_terminal": { + "name": "enable_terminal", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "enable_session_logging": { + "name": "enable_session_logging", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "allow_session_sharing": { + "name": "allow_session_sharing", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "enable_command_history": { + "name": "enable_command_history", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "enable_tunnel": { + "name": "enable_tunnel", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "tunnel_connections": { + "name": "tunnel_connections", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "jump_hosts": { + "name": "jump_hosts", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enable_file_manager": { + "name": "enable_file_manager", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "scp_legacy": { + "name": "scp_legacy", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "enable_docker": { + "name": "enable_docker", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "enable_web_ui": { + "name": "enable_web_ui", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "enable_tmux_monitor": { + "name": "enable_tmux_monitor", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "enable_terminal_toolbar": { + "name": "enable_terminal_toolbar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "enable_ai_assistant": { + "name": "enable_ai_assistant", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "show_terminal_in_sidebar": { + "name": "show_terminal_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "show_file_manager_in_sidebar": { + "name": "show_file_manager_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "show_tunnel_in_sidebar": { + "name": "show_tunnel_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "show_docker_in_sidebar": { + "name": "show_docker_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "show_server_stats_in_sidebar": { + "name": "show_server_stats_in_sidebar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "default_path": { + "name": "default_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stats_config": { + "name": "stats_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "docker_config": { + "name": "docker_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "web_ui_config": { + "name": "web_ui_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enable_proxmox": { + "name": "enable_proxmox", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "proxmox_config": { + "name": "proxmox_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enable_proxmox_stats": { + "name": "enable_proxmox_stats", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "proxmox_stats_config": { + "name": "proxmox_stats_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terminal_config": { + "name": "terminal_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "quick_actions": { + "name": "quick_actions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enable_ssh": { + "name": "enable_ssh", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "enable_rdp": { + "name": "enable_rdp", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "enable_vnc": { + "name": "enable_vnc", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "enable_telnet": { + "name": "enable_telnet", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "ssh_port": { + "name": "ssh_port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 22 + }, + "rdp_port": { + "name": "rdp_port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 3389 + }, + "vnc_port": { + "name": "vnc_port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 5900 + }, + "telnet_port": { + "name": "telnet_port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 23 + }, + "rdp_credential_id": { + "name": "rdp_credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rdp_user": { + "name": "rdp_user", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rdp_password": { + "name": "rdp_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rdp_domain": { + "name": "rdp_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rdp_security": { + "name": "rdp_security", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rdp_ignore_cert": { + "name": "rdp_ignore_cert", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "vnc_credential_id": { + "name": "vnc_credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vnc_password": { + "name": "vnc_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vnc_user": { + "name": "vnc_user", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "telnet_user": { + "name": "telnet_user", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "telnet_password": { + "name": "telnet_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "telnet_credential_id": { + "name": "telnet_credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rdp_auth_type": { + "name": "rdp_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vnc_auth_type": { + "name": "vnc_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "telnet_auth_type": { + "name": "telnet_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "security": { + "name": "security", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ignore_cert": { + "name": "ignore_cert", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "guacamole_config": { + "name": "guacamole_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "use_socks5": { + "name": "use_socks5", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "socks5_host": { + "name": "socks5_host", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "socks5_port": { + "name": "socks5_port", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "socks5_username": { + "name": "socks5_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "socks5_password": { + "name": "socks5_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "socks5_proxy_chain": { + "name": "socks5_proxy_chain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "connection_origin": { + "name": "connection_origin", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mac_address": { + "name": "mac_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "wol_broadcast_address": { + "name": "wol_broadcast_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "port_knock_sequence": { + "name": "port_knock_sequence", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_key_fingerprint": { + "name": "host_key_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_key_type": { + "name": "host_key_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_key_algorithm": { + "name": "host_key_algorithm", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'sha256'" + }, + "host_key_first_seen": { + "name": "host_key_first_seen", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_key_last_verified": { + "name": "host_key_last_verified", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_key_changed_count": { + "name": "host_key_changed_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ssh_data_user_id": { + "name": "idx_ssh_data_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_ssh_data_parent_host": { + "name": "idx_ssh_data_parent_host", + "columns": [ + { + "expression": "parent_host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_ssh_data_credential": { + "name": "idx_ssh_data_credential", + "columns": [ + { + "expression": "credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ssh_data_user_id_users_id_fk": { + "name": "ssh_data_user_id_users_id_fk", + "tableFrom": "ssh_data", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_data_parent_host_id_ssh_data_id_fk": { + "name": "ssh_data_parent_host_id_ssh_data_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_data", + "columnsFrom": [ + "parent_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_vault_profile_id_vault_profiles_id_fk": { + "name": "ssh_data_vault_profile_id_vault_profiles_id_fk", + "tableFrom": "ssh_data", + "tableTo": "vault_profiles", + "columnsFrom": [ + "vault_profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_rdp_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_rdp_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "rdp_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_vnc_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_vnc_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "vnc_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_telnet_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_telnet_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "telnet_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "ssh_data_sync_id_unique": { + "name": "ssh_data_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.network_topology": { + "name": "network_topology", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "topology": { + "name": "topology", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "network_topology_user_id_users_id_fk": { + "name": "network_topology_user_id_users_id_fk", + "tableFrom": "network_topology", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notification_channels": { + "name": "notification_channels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "notification_channels_user_id_users_id_fk": { + "name": "notification_channels_user_id_users_id_fk", + "tableFrom": "notification_channels", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.opkssh_tokens": { + "name": "opkssh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "ssh_cert": { + "name": "ssh_cert", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sub": { + "name": "sub", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "issuer": { + "name": "issuer", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audience": { + "name": "audience", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_opkssh_tokens_user_host": { + "name": "idx_opkssh_tokens_user_host", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "opkssh_tokens_user_id_users_id_fk": { + "name": "opkssh_tokens_user_id_users_id_fk", + "tableFrom": "opkssh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "opkssh_tokens_host_id_ssh_data_id_fk": { + "name": "opkssh_tokens_host_id_ssh_data_id_fk", + "tableFrom": "opkssh_tokens", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.plugin_install_counts": { + "name": "plugin_install_counts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "plugin_id": { + "name": "plugin_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "registry_id": { + "name": "registry_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'aggregate-telemetry'" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_plugin_install_counts_plugin_registry": { + "name": "idx_plugin_install_counts_plugin_registry", + "columns": [ + { + "expression": "plugin_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "registry_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.plugin_permission_grants": { + "name": "plugin_permission_grants", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "plugin_id": { + "name": "plugin_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "capability": { + "name": "capability", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "granted_at": { + "name": "granted_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "idx_plugin_permission_grants_plugin_capability": { + "name": "idx_plugin_permission_grants_plugin_capability", + "columns": [ + { + "expression": "plugin_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "capability", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "plugin_permission_grants_plugin_id_plugins_id_fk": { + "name": "plugin_permission_grants_plugin_id_plugins_id_fk", + "tableFrom": "plugin_permission_grants", + "tableTo": "plugins", + "columnsFrom": [ + "plugin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "plugin_permission_grants_granted_by_users_id_fk": { + "name": "plugin_permission_grants_granted_by_users_id_fk", + "tableFrom": "plugin_permission_grants", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.plugin_registries": { + "name": "plugin_registries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'community'" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "signing_key": { + "name": "signing_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_index_hash": { + "name": "last_index_hash", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.plugin_storage": { + "name": "plugin_storage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "plugin_id": { + "name": "plugin_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_plugin_storage_plugin_key": { + "name": "idx_plugin_storage_plugin_key", + "columns": [ + { + "expression": "plugin_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "plugin_storage_plugin_id_plugins_id_fk": { + "name": "plugin_storage_plugin_id_plugins_id_fk", + "tableFrom": "plugin_storage", + "tableTo": "plugins", + "columnsFrom": [ + "plugin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.plugins": { + "name": "plugins", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tier": { + "name": "tier", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'available'" + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'community'" + }, + "registry_id": { + "name": "registry_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'disabled'" + }, + "installed_at": { + "name": "installed_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "auto_update": { + "name": "auto_update", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "manifest_json": { + "name": "manifest_json", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "idx_plugins_registry_id": { + "name": "idx_plugins_registry_id", + "columns": [ + { + "expression": "registry_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.proxmox_node_history": { + "name": "proxmox_node_history", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "ts": { + "name": "ts", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "cpu_percent": { + "name": "cpu_percent", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "mem_percent": { + "name": "mem_percent", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "disk_percent": { + "name": "disk_percent", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "net_rx_bytes": { + "name": "net_rx_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "net_tx_bytes": { + "name": "net_tx_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "proxmox_node_history_host_id_ssh_data_id_fk": { + "name": "proxmox_node_history_host_id_ssh_data_id_fk", + "tableFrom": "proxmox_node_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.proxmox_stats_preferences": { + "name": "proxmox_stats_preferences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_proxmox_stats_prefs_user_host": { + "name": "idx_proxmox_stats_prefs_user_host", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "proxmox_stats_preferences_user_id_users_id_fk": { + "name": "proxmox_stats_preferences_user_id_users_id_fk", + "tableFrom": "proxmox_stats_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "proxmox_stats_preferences_host_id_ssh_data_id_fk": { + "name": "proxmox_stats_preferences_host_id_ssh_data_id_fk", + "tableFrom": "proxmox_stats_preferences", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.recent_activity": { + "name": "recent_activity", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "host_name": { + "name": "host_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "timestamp": { + "name": "timestamp", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_recent_activity_user_ts": { + "name": "idx_recent_activity_user_ts", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "timestamp", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "recent_activity_user_id_users_id_fk": { + "name": "recent_activity_user_id_users_id_fk", + "tableFrom": "recent_activity", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "recent_activity_host_id_ssh_data_id_fk": { + "name": "recent_activity_host_id_ssh_data_id_fk", + "tableFrom": "recent_activity", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.roles": { + "name": "roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_system": { + "name": "is_system", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "roles_name_unique": { + "name": "roles_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.secret_sources": { + "name": "secret_sources", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'onepassword-connect'" + }, + "base_url": { + "name": "base_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "shared": { + "name": "shared", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_secret_sources_user": { + "name": "idx_secret_sources_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "secret_sources_user_id_users_id_fk": { + "name": "secret_sources_user_id_users_id_fk", + "tableFrom": "secret_sources", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session_recordings": { + "name": "session_recordings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_id": { + "name": "access_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "ended_at": { + "name": "ended_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "commands": { + "name": "commands", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dangerous_actions": { + "name": "dangerous_actions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "recording_path": { + "name": "recording_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "protocol": { + "name": "protocol", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'ssh'" + }, + "format": { + "name": "format", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'text'" + }, + "terminated_by_owner": { + "name": "terminated_by_owner", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "termination_reason": { + "name": "termination_reason", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_session_recordings_user_started": { + "name": "idx_session_recordings_user_started", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "started_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_session_recordings_host": { + "name": "idx_session_recordings_host", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "session_recordings_host_id_ssh_data_id_fk": { + "name": "session_recordings_host_id_ssh_data_id_fk", + "tableFrom": "session_recordings", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_recordings_user_id_users_id_fk": { + "name": "session_recordings_user_id_users_id_fk", + "tableFrom": "session_recordings", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "session_recordings_access_id_host_access_id_fk": { + "name": "session_recordings_access_id_host_access_id_fk", + "tableFrom": "session_recordings", + "tableTo": "host_access", + "columnsFrom": [ + "access_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session_share_participants": { + "name": "session_share_participants", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "share_id": { + "name": "share_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "guest_label": { + "name": "guest_label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "left_at": { + "name": "left_at", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "session_share_participants_share_id_session_shares_id_fk": { + "name": "session_share_participants_share_id_session_shares_id_fk", + "tableFrom": "session_share_participants", + "tableTo": "session_shares", + "columnsFrom": [ + "share_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_share_participants_user_id_users_id_fk": { + "name": "session_share_participants_user_id_users_id_fk", + "tableFrom": "session_share_participants", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session_shares": { + "name": "session_shares", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "protocol": { + "name": "protocol", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "tab_instance_id": { + "name": "tab_instance_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "share_type": { + "name": "share_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_user_id": { + "name": "target_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "link_token": { + "name": "link_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'read-only'" + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_joined_at": { + "name": "last_joined_at", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "join_count": { + "name": "join_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "idx_session_shares_session_id": { + "name": "idx_session_shares_session_id", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_session_shares_host_id": { + "name": "idx_session_shares_host_id", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "session_shares_host_id_ssh_data_id_fk": { + "name": "session_shares_host_id_ssh_data_id_fk", + "tableFrom": "session_shares", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_shares_owner_user_id_users_id_fk": { + "name": "session_shares_owner_user_id_users_id_fk", + "tableFrom": "session_shares", + "tableTo": "users", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_shares_target_user_id_users_id_fk": { + "name": "session_shares_target_user_id_users_id_fk", + "tableFrom": "session_shares", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_shares_link_token_unique": { + "name": "session_shares_link_token_unique", + "nullsNotDistinct": false, + "columns": [ + "link_token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sessions": { + "name": "sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "jwt_token": { + "name": "jwt_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "device_info": { + "name": "device_info", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "oidc_sub": { + "name": "oidc_sub", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "oidc_sid": { + "name": "oidc_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sso_provider_id": { + "name": "sso_provider_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_active_at": { + "name": "last_active_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_sessions_user_id": { + "name": "idx_sessions_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_sessions_expires_at": { + "name": "idx_sessions_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shared_credential_secrets": { + "name": "shared_credential_secrets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "credential_access_id": { + "name": "credential_access_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "target_user_id": { + "name": "target_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "encrypted_username": { + "name": "encrypted_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'password'" + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_key": { + "name": "encrypted_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_key_password": { + "name": "encrypted_key_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cert_public_key": { + "name": "cert_public_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_shared_credential_secrets_scope": { + "name": "idx_shared_credential_secrets_scope", + "columns": [ + { + "expression": "credential_access_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_shared_credential_secrets_target": { + "name": "idx_shared_credential_secrets_target", + "columns": [ + { + "expression": "target_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shared_credential_secrets_target_user_id_users_id_fk": { + "name": "shared_credential_secrets_target_user_id_users_id_fk", + "tableFrom": "shared_credential_secrets", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_credential_secrets_credential_id_ssh_credentials_id_fk": { + "name": "shared_credential_secrets_credential_id_ssh_credentials_id_fk", + "tableFrom": "shared_credential_secrets", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_cred_secrets_access_id_fk": { + "name": "shared_cred_secrets_access_id_fk", + "tableFrom": "shared_credential_secrets", + "tableTo": "credential_access", + "columnsFrom": [ + "credential_access_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shared_host_auth_overrides": { + "name": "shared_host_auth_overrides", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "protocol": { + "name": "protocol", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'ssh'" + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "shared_host_auth_overrides_host_user_protocol_unique": { + "name": "shared_host_auth_overrides_host_user_protocol_unique", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "protocol", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shared_host_auth_overrides_host_id_ssh_data_id_fk": { + "name": "shared_host_auth_overrides_host_id_ssh_data_id_fk", + "tableFrom": "shared_host_auth_overrides", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_auth_overrides_user_id_users_id_fk": { + "name": "shared_host_auth_overrides_user_id_users_id_fk", + "tableFrom": "shared_host_auth_overrides", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_auth_overrides_credential_id_ssh_credentials_id_fk": { + "name": "shared_host_auth_overrides_credential_id_ssh_credentials_id_fk", + "tableFrom": "shared_host_auth_overrides", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shared_host_secrets": { + "name": "shared_host_secrets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "host_access_id": { + "name": "host_access_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "target_user_id": { + "name": "target_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "protocol": { + "name": "protocol", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'ssh'" + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'credential'" + }, + "original_credential_id": { + "name": "original_credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "encrypted_username": { + "name": "encrypted_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_auth_type": { + "name": "encrypted_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_key": { + "name": "encrypted_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_key_password": { + "name": "encrypted_key_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_key_type": { + "name": "encrypted_key_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_domain": { + "name": "encrypted_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_shared_host_secrets_scope": { + "name": "idx_shared_host_secrets_scope", + "columns": [ + { + "expression": "host_access_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "protocol", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shared_host_secrets_host_access_id_host_access_id_fk": { + "name": "shared_host_secrets_host_access_id_host_access_id_fk", + "tableFrom": "shared_host_secrets", + "tableTo": "host_access", + "columnsFrom": [ + "host_access_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_secrets_target_user_id_users_id_fk": { + "name": "shared_host_secrets_target_user_id_users_id_fk", + "tableFrom": "shared_host_secrets", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_secrets_original_credential_id_ssh_credentials_id_fk": { + "name": "shared_host_secrets_original_credential_id_ssh_credentials_id_fk", + "tableFrom": "shared_host_secrets", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "original_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.snippet_access": { + "name": "snippet_access", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "snippet_id": { + "name": "snippet_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'view'" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_snippet_access_user_id": { + "name": "idx_snippet_access_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_snippet_access_snippet_id": { + "name": "idx_snippet_access_snippet_id", + "columns": [ + { + "expression": "snippet_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_snippet_access_role_id": { + "name": "idx_snippet_access_role_id", + "columns": [ + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "snippet_access_snippet_id_snippets_id_fk": { + "name": "snippet_access_snippet_id_snippets_id_fk", + "tableFrom": "snippet_access", + "tableTo": "snippets", + "columnsFrom": [ + "snippet_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "snippet_access_user_id_users_id_fk": { + "name": "snippet_access_user_id_users_id_fk", + "tableFrom": "snippet_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "snippet_access_role_id_roles_id_fk": { + "name": "snippet_access_role_id_roles_id_fk", + "tableFrom": "snippet_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "snippet_access_granted_by_users_id_fk": { + "name": "snippet_access_granted_by_users_id_fk", + "tableFrom": "snippet_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.snippet_folders": { + "name": "snippet_folders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "snippet_folders_user_id_users_id_fk": { + "name": "snippet_folders_user_id_users_id_fk", + "tableFrom": "snippet_folders", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "snippet_folders_sync_id_unique": { + "name": "snippet_folders_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.snippets": { + "name": "snippets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "host_filter": { + "name": "host_filter", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_note": { + "name": "is_note", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "idx_snippets_user_id": { + "name": "idx_snippets_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "snippets_user_id_users_id_fk": { + "name": "snippets_user_id_users_id_fk", + "tableFrom": "snippets", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "snippets_sync_id_unique": { + "name": "snippets_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ssh_credential_usage": { + "name": "ssh_credential_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ssh_credential_usage_credential": { + "name": "idx_ssh_credential_usage_credential", + "columns": [ + { + "expression": "credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_ssh_credential_usage_user": { + "name": "idx_ssh_credential_usage_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ssh_credential_usage_credential_id_ssh_credentials_id_fk": { + "name": "ssh_credential_usage_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_credential_usage", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_credential_usage_host_id_ssh_data_id_fk": { + "name": "ssh_credential_usage_host_id_ssh_data_id_fk", + "tableFrom": "ssh_credential_usage", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_credential_usage_user_id_users_id_fk": { + "name": "ssh_credential_usage_user_id_users_id_fk", + "tableFrom": "ssh_credential_usage", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ssh_credentials": { + "name": "ssh_credentials", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "tags": { + "name": "tags", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pin": { + "name": "pin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key_password": { + "name": "key_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "detected_key_type": { + "name": "detected_key_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cert_public_key": { + "name": "cert_public_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_count": { + "name": "usage_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ssh_credentials_user_id": { + "name": "idx_ssh_credentials_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ssh_credentials_user_id_users_id_fk": { + "name": "ssh_credentials_user_id_users_id_fk", + "tableFrom": "ssh_credentials", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "ssh_credentials_sync_id_unique": { + "name": "ssh_credentials_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ssh_folders": { + "name": "ssh_folders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ssh_folders_user_id": { + "name": "idx_ssh_folders_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ssh_folders_user_id_users_id_fk": { + "name": "ssh_folders_user_id_users_id_fk", + "tableFrom": "ssh_folders", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_folders_credential_id_ssh_credentials_id_fk": { + "name": "ssh_folders_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_folders", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "ssh_folders_sync_id_unique": { + "name": "ssh_folders_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sso_providers": { + "name": "sso_providers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sync_tombstones": { + "name": "sync_tombstones", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "sync_tombstones_user_id_users_id_fk": { + "name": "sync_tombstones_user_id_users_id_fk", + "tableFrom": "sync_tombstones", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.termix_identities": { + "name": "termix_identities", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "handle": { + "name": "handle", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "termix_identities_user_id_users_id_fk": { + "name": "termix_identities_user_id_users_id_fk", + "tableFrom": "termix_identities", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "termix_identities_user_id_unique": { + "name": "termix_identities_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + }, + "termix_identities_handle_unique": { + "name": "termix_identities_handle_unique", + "nullsNotDistinct": false, + "columns": [ + "handle" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.termix_identity_ca": { + "name": "termix_identity_ca", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "identity_id": { + "name": "identity_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "validity_days": { + "name": "validity_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 90 + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "termix_identity_ca_identity_id_termix_identities_id_fk": { + "name": "termix_identity_ca_identity_id_termix_identities_id_fk", + "tableFrom": "termix_identity_ca", + "tableTo": "termix_identities", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "termix_identity_ca_user_id_users_id_fk": { + "name": "termix_identity_ca_user_id_users_id_fk", + "tableFrom": "termix_identity_ca", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "termix_identity_ca_identity_id_unique": { + "name": "termix_identity_ca_identity_id_unique", + "nullsNotDistinct": false, + "columns": [ + "identity_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.termix_identity_keys": { + "name": "termix_identity_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "identity_id": { + "name": "identity_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "algorithm": { + "name": "algorithm", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "comment": { + "name": "comment", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'manual'" + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "termix_identity_keys_identity_id_termix_identities_id_fk": { + "name": "termix_identity_keys_identity_id_termix_identities_id_fk", + "tableFrom": "termix_identity_keys", + "tableTo": "termix_identities", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "termix_identity_keys_user_id_users_id_fk": { + "name": "termix_identity_keys_user_id_users_id_fk", + "tableFrom": "termix_identity_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "termix_identity_keys_credential_id_ssh_credentials_id_fk": { + "name": "termix_identity_keys_credential_id_ssh_credentials_id_fk", + "tableFrom": "termix_identity_keys", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tmux_session_tags": { + "name": "tmux_session_tags", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "session_name": { + "name": "session_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tag": { + "name": "tag", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "tmux_session_tags_user_id_users_id_fk": { + "name": "tmux_session_tags_user_id_users_id_fk", + "tableFrom": "tmux_session_tags", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tmux_session_tags_host_id_ssh_data_id_fk": { + "name": "tmux_session_tags_host_id_ssh_data_id_fk", + "tableFrom": "tmux_session_tags", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.transfer_recent": { + "name": "transfer_recent", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "source_host_id": { + "name": "source_host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "dest_host_id": { + "name": "dest_host_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "dest_path": { + "name": "dest_path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dest_path_label": { + "name": "dest_path_label", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_transfer_recent_user": { + "name": "idx_transfer_recent_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "transfer_recent_user_id_users_id_fk": { + "name": "transfer_recent_user_id_users_id_fk", + "tableFrom": "transfer_recent", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "transfer_recent_source_host_id_ssh_data_id_fk": { + "name": "transfer_recent_source_host_id_ssh_data_id_fk", + "tableFrom": "transfer_recent", + "tableTo": "ssh_data", + "columnsFrom": [ + "source_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "transfer_recent_dest_host_id_ssh_data_id_fk": { + "name": "transfer_recent_dest_host_id_ssh_data_id_fk", + "tableFrom": "transfer_recent", + "tableTo": "ssh_data", + "columnsFrom": [ + "dest_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.trusted_devices": { + "name": "trusted_devices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "device_fingerprint": { + "name": "device_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "device_info": { + "name": "device_info", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_trusted_devices_user_id": { + "name": "idx_trusted_devices_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "trusted_devices_user_id_users_id_fk": { + "name": "trusted_devices_user_id_users_id_fk", + "tableFrom": "trusted_devices", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ui_preferences": { + "name": "ui_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "ui_preferences_user_id_users_id_fk": { + "name": "ui_preferences_user_id_users_id_fk", + "tableFrom": "ui_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_open_tabs": { + "name": "user_open_tabs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "tab_type": { + "name": "tab_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "label": { + "name": "label", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "tab_order": { + "name": "tab_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "backend_session_id": { + "name": "backend_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_user_open_tabs_user_id": { + "name": "idx_user_open_tabs_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_open_tabs_user_id_users_id_fk": { + "name": "user_open_tabs_user_id_users_id_fk", + "tableFrom": "user_open_tabs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_open_tabs_host_id_ssh_data_id_fk": { + "name": "user_open_tabs_host_id_ssh_data_id_fk", + "tableFrom": "user_open_tabs", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_preferences": { + "name": "user_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "reopen_tabs_on_login": { + "name": "reopen_tabs_on_login", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "font_size": { + "name": "font_size", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "language": { + "name": "language", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "storage_mode": { + "name": "storage_mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "command_autocomplete": { + "name": "command_autocomplete", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "command_palette_enabled": { + "name": "command_palette_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "show_host_tags": { + "name": "show_host_tags", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "host_tray_on_click": { + "name": "host_tray_on_click", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "pin_app_rail": { + "name": "pin_app_rail", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "expand_app_rail_on_hover": { + "name": "expand_app_rail_on_hover", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "show_pin_app_rail_button": { + "name": "show_pin_app_rail_button", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "folders_collapsed": { + "name": "folders_collapsed", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "confirm_snippet_execution": { + "name": "confirm_snippet_execution", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "disable_update_check": { + "name": "disable_update_check", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "confirm_tab_close": { + "name": "confirm_tab_close", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "hidden_rail_tabs": { + "name": "hidden_rail_tabs", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ai_assistant_enabled": { + "name": "ai_assistant_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "ai_read_only_commands": { + "name": "ai_read_only_commands", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "compact_host_view": { + "name": "compact_host_view", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "status_color_scheme": { + "name": "status_color_scheme", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "custom_themes": { + "name": "custom_themes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "custom_keybindings": { + "name": "custom_keybindings", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terminal_defaults": { + "name": "terminal_defaults", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rdp_defaults": { + "name": "rdp_defaults", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terminal_macros": { + "name": "terminal_macros", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "user_preferences_user_id_users_id_fk": { + "name": "user_preferences_user_id_users_id_fk", + "tableFrom": "user_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_roles": { + "name": "user_roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "granted_by": { + "name": "granted_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "granted_at": { + "name": "granted_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_user_roles_user_role": { + "name": "idx_user_roles_user_role", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_user_roles_role_id": { + "name": "idx_user_roles_role_id", + "columns": [ + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_roles_user_id_users_id_fk": { + "name": "user_roles_user_id_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_role_id_roles_id_fk": { + "name": "user_roles_role_id_roles_id_fk", + "tableFrom": "user_roles", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_granted_by_users_id_fk": { + "name": "user_roles_granted_by_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_workspaces": { + "name": "user_workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'manual'" + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_user_workspaces_user_id": { + "name": "idx_user_workspaces_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_workspaces_user_id_users_id_fk": { + "name": "user_workspaces_user_id_users_id_fk", + "tableFrom": "user_workspaces", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_workspaces_sync_id_unique": { + "name": "user_workspaces_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_admin": { + "name": "is_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_oidc": { + "name": "is_oidc", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "oidc_identifier": { + "name": "oidc_identifier", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sso_provider_id": { + "name": "sso_provider_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_secret": { + "name": "client_secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "issuer_url": { + "name": "issuer_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "authorization_url": { + "name": "authorization_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_url": { + "name": "token_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "identifier_path": { + "name": "identifier_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name_path": { + "name": "name_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'openid email profile'" + }, + "totp_secret": { + "name": "totp_secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "totp_enabled": { + "name": "totp_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "totp_backup_codes": { + "name": "totp_backup_codes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "registered_at": { + "name": "registered_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "donation_modal_dismissed": { + "name": "donation_modal_dismissed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.vault_profiles": { + "name": "vault_profiles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "folder": { + "name": "folder", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "tags": { + "name": "tags", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vault_addr": { + "name": "vault_addr", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "vault_namespace": { + "name": "vault_namespace", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "oidc_mount": { + "name": "oidc_mount", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "oidc_role": { + "name": "oidc_role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ssh_mount": { + "name": "ssh_mount", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ssh_role": { + "name": "ssh_role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "valid_principals": { + "name": "valid_principals", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "shared": { + "name": "shared", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "sync_id": { + "name": "sync_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "vault_profiles_user_id_users_id_fk": { + "name": "vault_profiles_user_id_users_id_fk", + "tableFrom": "vault_profiles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "vault_profiles_sync_id_unique": { + "name": "vault_profiles_sync_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sync_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.vault_tokens": { + "name": "vault_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "profile_id": { + "name": "profile_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "ssh_cert": { + "name": "ssh_cert", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_vault_tokens_user_profile": { + "name": "idx_vault_tokens_user_profile", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "vault_tokens_user_id_users_id_fk": { + "name": "vault_tokens_user_id_users_id_fk", + "tableFrom": "vault_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "vault_tokens_profile_id_vault_profiles_id_fk": { + "name": "vault_tokens_profile_id_vault_profiles_id_fk", + "tableFrom": "vault_tokens", + "tableTo": "vault_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webauthn_credentials": { + "name": "webauthn_credentials", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "counter": { + "name": "counter", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "backed_up": { + "name": "backed_up", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "transports": { + "name": "transports", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_verification": { + "name": "user_verification", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'preferred'" + }, + "created_at": { + "name": "created_at", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "webauthn_credentials_user_id_users_id_fk": { + "name": "webauthn_credentials_user_id_users_id_fk", + "tableFrom": "webauthn_credentials", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/postgres/meta/_journal.json b/drizzle/postgres/meta/_journal.json index 0a9f7e647..73591356b 100644 --- a/drizzle/postgres/meta/_journal.json +++ b/drizzle/postgres/meta/_journal.json @@ -183,6 +183,13 @@ "when": 1789991403847, "tag": "0025_purple_squirrel_girl", "breakpoints": true + }, + { + "idx": 26, + "version": "7", + "when": 1790083819084, + "tag": "0026_perfect_masque", + "breakpoints": true } ] } \ No newline at end of file diff --git a/drizzle/sqlite/0022_steady_the_hood.sql b/drizzle/sqlite/0022_steady_the_hood.sql new file mode 100644 index 000000000..cb1b5e74b --- /dev/null +++ b/drizzle/sqlite/0022_steady_the_hood.sql @@ -0,0 +1,3 @@ +DROP TABLE `alert_firings`;--> statement-breakpoint +DROP TABLE `alert_rule_channels`;--> statement-breakpoint +DROP TABLE `alert_rules`; \ No newline at end of file diff --git a/drizzle/sqlite/meta/0022_snapshot.json b/drizzle/sqlite/meta/0022_snapshot.json new file mode 100644 index 000000000..e90608396 --- /dev/null +++ b/drizzle/sqlite/meta/0022_snapshot.json @@ -0,0 +1,9203 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "94343ac6-c547-4bea-8700-476074e63e3b", + "prevId": "65bda738-95d9-489a-9681-0d395615ad4e", + "tables": { + "ai_conversations": { + "name": "ai_conversations", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "provider_id": { + "name": "provider_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ai_conversations_user": { + "name": "idx_ai_conversations_user", + "columns": [ + "user_id", + "updated_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ai_conversations_user_id_users_id_fk": { + "name": "ai_conversations_user_id_users_id_fk", + "tableFrom": "ai_conversations", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "ai_messages": { + "name": "ai_messages", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "tool_calls": { + "name": "tool_calls", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ai_messages_conversation": { + "name": "idx_ai_messages_conversation", + "columns": [ + "conversation_id", + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ai_messages_conversation_id_ai_conversations_id_fk": { + "name": "ai_messages_conversation_id_ai_conversations_id_fk", + "tableFrom": "ai_messages", + "tableTo": "ai_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "ai_proposals": { + "name": "ai_proposals", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{}'" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pending'" + }, + "applied_at": { + "name": "applied_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "result_summary": { + "name": "result_summary", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ai_proposals_user": { + "name": "idx_ai_proposals_user", + "columns": [ + "user_id", + "status" + ], + "isUnique": false + }, + "idx_ai_proposals_conversation": { + "name": "idx_ai_proposals_conversation", + "columns": [ + "conversation_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ai_proposals_conversation_id_ai_conversations_id_fk": { + "name": "ai_proposals_conversation_id_ai_conversations_id_fk", + "tableFrom": "ai_proposals", + "tableTo": "ai_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ai_proposals_user_id_users_id_fk": { + "name": "ai_proposals_user_id_users_id_fk", + "tableFrom": "ai_proposals", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "ai_providers": { + "name": "ai_providers", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_type": { + "name": "provider_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "base_url": { + "name": "base_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "api_key": { + "name": "api_key", + "type": "text(8192)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "api_key_prefix": { + "name": "api_key_prefix", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_model": { + "name": "default_model", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ai_providers_user_label": { + "name": "idx_ai_providers_user_label", + "columns": [ + "user_id", + "label" + ], + "isUnique": true + } + }, + "foreignKeys": { + "ai_providers_user_id_users_id_fk": { + "name": "ai_providers_user_id_users_id_fk", + "tableFrom": "ai_providers", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "api_keys": { + "name": "api_keys", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token_prefix": { + "name": "token_prefix", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_active": { + "name": "is_active", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + } + }, + "indexes": { + "idx_api_keys_user_id": { + "name": "idx_api_keys_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "api_keys_user_id_users_id_fk": { + "name": "api_keys_user_id_users_id_fk", + "tableFrom": "api_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "audit_logs": { + "name": "audit_logs", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "resource_type": { + "name": "resource_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "resource_id": { + "name": "resource_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "resource_name": { + "name": "resource_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "details": { + "name": "details", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "success": { + "name": "success", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "timestamp": { + "name": "timestamp", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_audit_logs_timestamp": { + "name": "idx_audit_logs_timestamp", + "columns": [ + "timestamp" + ], + "isUnique": false + }, + "idx_audit_logs_user_ts": { + "name": "idx_audit_logs_user_ts", + "columns": [ + "user_id", + "timestamp" + ], + "isUnique": false + }, + "idx_audit_logs_action_ts": { + "name": "idx_audit_logs_action_ts", + "columns": [ + "action", + "timestamp" + ], + "isUnique": false + }, + "idx_audit_logs_resource_ts": { + "name": "idx_audit_logs_resource_ts", + "columns": [ + "resource_type", + "timestamp" + ], + "isUnique": false + } + }, + "foreignKeys": { + "audit_logs_user_id_users_id_fk": { + "name": "audit_logs_user_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "automation_channels": { + "name": "automation_channels", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "automation_id": { + "name": "automation_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "channel_id": { + "name": "channel_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_automation_channels_pair": { + "name": "idx_automation_channels_pair", + "columns": [ + "automation_id", + "channel_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "automation_channels_automation_id_automations_id_fk": { + "name": "automation_channels_automation_id_automations_id_fk", + "tableFrom": "automation_channels", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "automation_channels_channel_id_notification_channels_id_fk": { + "name": "automation_channels_channel_id_notification_channels_id_fk", + "tableFrom": "automation_channels", + "tableTo": "notification_channels", + "columnsFrom": [ + "channel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "automation_run_steps": { + "name": "automation_run_steps", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "run_id": { + "name": "run_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "step_index": { + "name": "step_index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "step_id": { + "name": "step_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "step_type": { + "name": "step_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "finished_at": { + "name": "finished_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "output": { + "name": "output", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "truncated": { + "name": "truncated", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": { + "idx_automation_run_steps_run": { + "name": "idx_automation_run_steps_run", + "columns": [ + "run_id", + "step_index" + ], + "isUnique": false + } + }, + "foreignKeys": { + "automation_run_steps_run_id_automation_runs_id_fk": { + "name": "automation_run_steps_run_id_automation_runs_id_fk", + "tableFrom": "automation_run_steps", + "tableTo": "automation_runs", + "columnsFrom": [ + "run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "automation_runs": { + "name": "automation_runs", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "automation_id": { + "name": "automation_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "trigger_type": { + "name": "trigger_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "trigger_context": { + "name": "trigger_context", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "finished_at": { + "name": "finished_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "dry_run": { + "name": "dry_run", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "parent_run_id": { + "name": "parent_run_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_automation_runs_automation": { + "name": "idx_automation_runs_automation", + "columns": [ + "automation_id", + "started_at" + ], + "isUnique": false + }, + "idx_automation_runs_user": { + "name": "idx_automation_runs_user", + "columns": [ + "user_id", + "started_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "automation_runs_automation_id_automations_id_fk": { + "name": "automation_runs_automation_id_automations_id_fk", + "tableFrom": "automation_runs", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "automation_runs_user_id_users_id_fk": { + "name": "automation_runs_user_id_users_id_fk", + "tableFrom": "automation_runs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "automation_schedules": { + "name": "automation_schedules", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "automation_id": { + "name": "automation_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cron": { + "name": "cron", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "interval_seconds": { + "name": "interval_seconds", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "next_due_at": { + "name": "next_due_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_tick_at": { + "name": "last_tick_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_automation_schedules_automation": { + "name": "idx_automation_schedules_automation", + "columns": [ + "automation_id" + ], + "isUnique": true + }, + "idx_automation_schedules_due": { + "name": "idx_automation_schedules_due", + "columns": [ + "next_due_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "automation_schedules_automation_id_automations_id_fk": { + "name": "automation_schedules_automation_id_automations_id_fk", + "tableFrom": "automation_schedules", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "automation_trigger_state": { + "name": "automation_trigger_state", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "automation_id": { + "name": "automation_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "state_key": { + "name": "state_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "breach_started_at": { + "name": "breach_started_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_fired_at": { + "name": "last_fired_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_value": { + "name": "last_value", + "type": "real", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_observed_state": { + "name": "last_observed_state", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_automation_trigger_state_key": { + "name": "idx_automation_trigger_state_key", + "columns": [ + "automation_id", + "state_key" + ], + "isUnique": true + } + }, + "foreignKeys": { + "automation_trigger_state_automation_id_automations_id_fk": { + "name": "automation_trigger_state_automation_id_automations_id_fk", + "tableFrom": "automation_trigger_state", + "tableTo": "automations", + "columnsFrom": [ + "automation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "automations": { + "name": "automations", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "definition": { + "name": "definition", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "definition_version": { + "name": "definition_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "concurrency_policy": { + "name": "concurrency_policy", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'skip'" + }, + "max_run_seconds": { + "name": "max_run_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 300 + }, + "dry_run": { + "name": "dry_run", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "last_run_at": { + "name": "last_run_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_run_status": { + "name": "last_run_status", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_automations_user": { + "name": "idx_automations_user", + "columns": [ + "user_id", + "enabled" + ], + "isUnique": false + } + }, + "foreignKeys": { + "automations_user_id_users_id_fk": { + "name": "automations_user_id_users_id_fk", + "tableFrom": "automations", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "c2s_tunnel_presets": { + "name": "c2s_tunnel_presets", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "computer_name": { + "name": "computer_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "c2s_tunnel_presets_user_id_users_id_fk": { + "name": "c2s_tunnel_presets_user_id_users_id_fk", + "tableFrom": "c2s_tunnel_presets", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "collab_room_members": { + "name": "collab_room_members", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "room_id": { + "name": "room_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "room_role": { + "name": "room_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'member'" + }, + "added_by": { + "name": "added_by", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_collab_room_members_room_user": { + "name": "idx_collab_room_members_room_user", + "columns": [ + "room_id", + "user_id" + ], + "isUnique": true + }, + "idx_collab_room_members_user": { + "name": "idx_collab_room_members_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "collab_room_members_room_id_collab_rooms_id_fk": { + "name": "collab_room_members_room_id_collab_rooms_id_fk", + "tableFrom": "collab_room_members", + "tableTo": "collab_rooms", + "columnsFrom": [ + "room_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "collab_room_members_user_id_users_id_fk": { + "name": "collab_room_members_user_id_users_id_fk", + "tableFrom": "collab_room_members", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "collab_room_members_added_by_users_id_fk": { + "name": "collab_room_members_added_by_users_id_fk", + "tableFrom": "collab_room_members", + "tableTo": "users", + "columnsFrom": [ + "added_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "collab_rooms": { + "name": "collab_rooms", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "persistent": { + "name": "persistent", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "presenter_user_id": { + "name": "presenter_user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stage_protocol": { + "name": "stage_protocol", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stage_host_id": { + "name": "stage_host_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stage_share_id": { + "name": "stage_share_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "guest_link_token": { + "name": "guest_link_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "ended_at": { + "name": "ended_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_collab_rooms_owner": { + "name": "idx_collab_rooms_owner", + "columns": [ + "owner_user_id" + ], + "isUnique": false + }, + "idx_collab_rooms_guest_token": { + "name": "idx_collab_rooms_guest_token", + "columns": [ + "guest_link_token" + ], + "isUnique": true + } + }, + "foreignKeys": { + "collab_rooms_owner_user_id_users_id_fk": { + "name": "collab_rooms_owner_user_id_users_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "users", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "collab_rooms_presenter_user_id_users_id_fk": { + "name": "collab_rooms_presenter_user_id_users_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "users", + "columnsFrom": [ + "presenter_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "collab_rooms_stage_host_id_ssh_data_id_fk": { + "name": "collab_rooms_stage_host_id_ssh_data_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "ssh_data", + "columnsFrom": [ + "stage_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "collab_rooms_stage_share_id_session_shares_id_fk": { + "name": "collab_rooms_stage_share_id_session_shares_id_fk", + "tableFrom": "collab_rooms", + "tableTo": "session_shares", + "columnsFrom": [ + "stage_share_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "command_history": { + "name": "command_history", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "executed_at": { + "name": "executed_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_command_history_user_host": { + "name": "idx_command_history_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "command_history_user_id_users_id_fk": { + "name": "command_history_user_id_users_id_fk", + "tableFrom": "command_history", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "command_history_host_id_ssh_data_id_fk": { + "name": "command_history_host_id_ssh_data_id_fk", + "tableFrom": "command_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "credential_access": { + "name": "credential_access", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'use'" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_credential_access_user_id": { + "name": "idx_credential_access_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_credential_access_role_id": { + "name": "idx_credential_access_role_id", + "columns": [ + "role_id" + ], + "isUnique": false + }, + "idx_credential_access_credential_id": { + "name": "idx_credential_access_credential_id", + "columns": [ + "credential_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "credential_access_credential_id_ssh_credentials_id_fk": { + "name": "credential_access_credential_id_ssh_credentials_id_fk", + "tableFrom": "credential_access", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credential_access_user_id_users_id_fk": { + "name": "credential_access_user_id_users_id_fk", + "tableFrom": "credential_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credential_access_role_id_roles_id_fk": { + "name": "credential_access_role_id_roles_id_fk", + "tableFrom": "credential_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credential_access_granted_by_users_id_fk": { + "name": "credential_access_granted_by_users_id_fk", + "tableFrom": "credential_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "credential_sidebar_preferences": { + "name": "credential_sidebar_preferences", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "credential_sidebar_preferences_user_id_users_id_fk": { + "name": "credential_sidebar_preferences_user_id_users_id_fk", + "tableFrom": "credential_sidebar_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "dashboard_service_links": { + "name": "dashboard_service_links", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "dashboard_service_links_sync_id_unique": { + "name": "dashboard_service_links_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "dashboard_service_links_user_id_users_id_fk": { + "name": "dashboard_service_links_user_id_users_id_fk", + "tableFrom": "dashboard_service_links", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "dismissed_alerts": { + "name": "dismissed_alerts", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "alert_id": { + "name": "alert_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dismissed_at": { + "name": "dismissed_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_dismissed_alerts_user_id": { + "name": "idx_dismissed_alerts_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "dismissed_alerts_user_id_users_id_fk": { + "name": "dismissed_alerts_user_id_users_id_fk", + "tableFrom": "dismissed_alerts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "file_manager_pinned": { + "name": "file_manager_pinned", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "pinned_at": { + "name": "pinned_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_file_manager_pinned_user": { + "name": "idx_file_manager_pinned_user", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "file_manager_pinned_user_id_users_id_fk": { + "name": "file_manager_pinned_user_id_users_id_fk", + "tableFrom": "file_manager_pinned", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "file_manager_pinned_host_id_ssh_data_id_fk": { + "name": "file_manager_pinned_host_id_ssh_data_id_fk", + "tableFrom": "file_manager_pinned", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "file_manager_recent": { + "name": "file_manager_recent", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_opened": { + "name": "last_opened", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_file_manager_recent_user": { + "name": "idx_file_manager_recent_user", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "file_manager_recent_user_id_users_id_fk": { + "name": "file_manager_recent_user_id_users_id_fk", + "tableFrom": "file_manager_recent", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "file_manager_recent_host_id_ssh_data_id_fk": { + "name": "file_manager_recent_host_id_ssh_data_id_fk", + "tableFrom": "file_manager_recent", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "file_manager_shortcuts": { + "name": "file_manager_shortcuts", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_file_manager_shortcuts_user": { + "name": "idx_file_manager_shortcuts_user", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "file_manager_shortcuts_user_id_users_id_fk": { + "name": "file_manager_shortcuts_user_id_users_id_fk", + "tableFrom": "file_manager_shortcuts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "file_manager_shortcuts_host_id_ssh_data_id_fk": { + "name": "file_manager_shortcuts_host_id_ssh_data_id_fk", + "tableFrom": "file_manager_shortcuts", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "fleet_inventory": { + "name": "fleet_inventory", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "os_pretty_name": { + "name": "os_pretty_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "kernel": { + "name": "kernel", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "architecture": { + "name": "architecture", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "uptime_seconds": { + "name": "uptime_seconds", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "package_manager": { + "name": "package_manager", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "collected_at": { + "name": "collected_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_fleet_inventory_host": { + "name": "idx_fleet_inventory_host", + "columns": [ + "host_id", + "user_id" + ], + "isUnique": true + }, + "idx_fleet_inventory_user": { + "name": "idx_fleet_inventory_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "fleet_inventory_host_id_ssh_data_id_fk": { + "name": "fleet_inventory_host_id_ssh_data_id_fk", + "tableFrom": "fleet_inventory", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "fleet_inventory_user_id_users_id_fk": { + "name": "fleet_inventory_user_id_users_id_fk", + "tableFrom": "fleet_inventory", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "fleet_members": { + "name": "fleet_members", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "fleet_id": { + "name": "fleet_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "added_at": { + "name": "added_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_fleet_members_fleet_host": { + "name": "idx_fleet_members_fleet_host", + "columns": [ + "fleet_id", + "host_id" + ], + "isUnique": true + }, + "idx_fleet_members_host": { + "name": "idx_fleet_members_host", + "columns": [ + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "fleet_members_fleet_id_fleets_id_fk": { + "name": "fleet_members_fleet_id_fleets_id_fk", + "tableFrom": "fleet_members", + "tableTo": "fleets", + "columnsFrom": [ + "fleet_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "fleet_members_host_id_ssh_data_id_fk": { + "name": "fleet_members_host_id_ssh_data_id_fk", + "tableFrom": "fleet_members", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "fleets": { + "name": "fleets", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tag_rules": { + "name": "tag_rules", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "fleets_sync_id_unique": { + "name": "fleets_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "fleets_user_id_users_id_fk": { + "name": "fleets_user_id_users_id_fk", + "tableFrom": "fleets", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "folder_access": { + "name": "folder_access", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'connect'" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_folder_access_owner_folder": { + "name": "idx_folder_access_owner_folder", + "columns": [ + "owner_user_id", + "folder" + ], + "isUnique": false + } + }, + "foreignKeys": { + "folder_access_owner_user_id_users_id_fk": { + "name": "folder_access_owner_user_id_users_id_fk", + "tableFrom": "folder_access", + "tableTo": "users", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "folder_access_user_id_users_id_fk": { + "name": "folder_access_user_id_users_id_fk", + "tableFrom": "folder_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "folder_access_role_id_roles_id_fk": { + "name": "folder_access_role_id_roles_id_fk", + "tableFrom": "folder_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "folder_access_granted_by_users_id_fk": { + "name": "folder_access_granted_by_users_id_fk", + "tableFrom": "folder_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "homepage_items": { + "name": "homepage_items", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type_id": { + "name": "type_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{}'" + }, + "folder_id": { + "name": "folder_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "homepage_items_sync_id_unique": { + "name": "homepage_items_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + }, + "idx_homepage_items_user_id": { + "name": "idx_homepage_items_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "homepage_items_user_id_users_id_fk": { + "name": "homepage_items_user_id_users_id_fk", + "tableFrom": "homepage_items", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "homepage_layouts": { + "name": "homepage_layouts", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{}'" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "homepage_layouts_user_id_unique": { + "name": "homepage_layouts_user_id_unique", + "columns": [ + "user_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "homepage_layouts_user_id_users_id_fk": { + "name": "homepage_layouts_user_id_users_id_fk", + "tableFrom": "homepage_layouts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "host_access": { + "name": "host_access", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'connect'" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "last_accessed_at": { + "name": "last_accessed_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_count": { + "name": "access_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + } + }, + "indexes": { + "idx_host_access_user_id": { + "name": "idx_host_access_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_host_access_role_id": { + "name": "idx_host_access_role_id", + "columns": [ + "role_id" + ], + "isUnique": false + }, + "idx_host_access_host_id": { + "name": "idx_host_access_host_id", + "columns": [ + "host_id" + ], + "isUnique": false + }, + "idx_host_access_expires_at": { + "name": "idx_host_access_expires_at", + "columns": [ + "expires_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "host_access_host_id_ssh_data_id_fk": { + "name": "host_access_host_id_ssh_data_id_fk", + "tableFrom": "host_access", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_access_user_id_users_id_fk": { + "name": "host_access_user_id_users_id_fk", + "tableFrom": "host_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_access_role_id_roles_id_fk": { + "name": "host_access_role_id_roles_id_fk", + "tableFrom": "host_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_access_granted_by_users_id_fk": { + "name": "host_access_granted_by_users_id_fk", + "tableFrom": "host_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "host_health_checks": { + "name": "host_health_checks", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "checks": { + "name": "checks", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "interval_seconds": { + "name": "interval_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 300 + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_host_health_checks_user_host": { + "name": "idx_host_health_checks_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "host_health_checks_user_id_users_id_fk": { + "name": "host_health_checks_user_id_users_id_fk", + "tableFrom": "host_health_checks", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_health_checks_host_id_ssh_data_id_fk": { + "name": "host_health_checks_host_id_ssh_data_id_fk", + "tableFrom": "host_health_checks", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "host_health_history": { + "name": "host_health_history", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "check_id": { + "name": "check_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ts": { + "name": "ts", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "ok": { + "name": "ok", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "latency_ms": { + "name": "latency_ms", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "detail": { + "name": "detail", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "host_health_history_user_id_users_id_fk": { + "name": "host_health_history_user_id_users_id_fk", + "tableFrom": "host_health_history", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_health_history_host_id_ssh_data_id_fk": { + "name": "host_health_history_host_id_ssh_data_id_fk", + "tableFrom": "host_health_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "host_metrics_history": { + "name": "host_metrics_history", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ts": { + "name": "ts", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "cpu_percent": { + "name": "cpu_percent", + "type": "real", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mem_percent": { + "name": "mem_percent", + "type": "real", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "disk_percent": { + "name": "disk_percent", + "type": "real", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "net_rx_bytes": { + "name": "net_rx_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "net_tx_bytes": { + "name": "net_tx_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "host_metrics_history_host_id_ssh_data_id_fk": { + "name": "host_metrics_history_host_id_ssh_data_id_fk", + "tableFrom": "host_metrics_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "host_metrics_preferences": { + "name": "host_metrics_preferences", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_host_metrics_prefs_user_host": { + "name": "idx_host_metrics_prefs_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "host_metrics_preferences_user_id_users_id_fk": { + "name": "host_metrics_preferences_user_id_users_id_fk", + "tableFrom": "host_metrics_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "host_metrics_preferences_host_id_ssh_data_id_fk": { + "name": "host_metrics_preferences_host_id_ssh_data_id_fk", + "tableFrom": "host_metrics_preferences", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "host_sidebar_preferences": { + "name": "host_sidebar_preferences", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "host_sidebar_preferences_user_id_users_id_fk": { + "name": "host_sidebar_preferences_user_id_users_id_fk", + "tableFrom": "host_sidebar_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "ssh_data": { + "name": "ssh_data", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "connection_type": { + "name": "connection_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ssh'" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "parent_host_id": { + "name": "parent_host_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tags": { + "name": "tags", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "pin": { + "name": "pin", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "use_warpgate": { + "name": "use_warpgate", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "share_ssh_auth": { + "name": "share_ssh_auth", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "force_keyboard_interactive": { + "name": "force_keyboard_interactive", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key": { + "name": "key", + "type": "text(8192)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_password": { + "name": "key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sudo_password": { + "name": "sudo_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "autostart_password": { + "name": "autostart_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "autostart_key": { + "name": "autostart_key", + "type": "text(8192)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "autostart_key_password": { + "name": "autostart_key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "override_credential_username": { + "name": "override_credential_username", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vault_profile_id": { + "name": "vault_profile_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_terminal": { + "name": "enable_terminal", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_session_logging": { + "name": "enable_session_logging", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "allow_session_sharing": { + "name": "allow_session_sharing", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_command_history": { + "name": "enable_command_history", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_tunnel": { + "name": "enable_tunnel", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "tunnel_connections": { + "name": "tunnel_connections", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "jump_hosts": { + "name": "jump_hosts", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_file_manager": { + "name": "enable_file_manager", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "scp_legacy": { + "name": "scp_legacy", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_docker": { + "name": "enable_docker", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_web_ui": { + "name": "enable_web_ui", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_tmux_monitor": { + "name": "enable_tmux_monitor", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_terminal_toolbar": { + "name": "enable_terminal_toolbar", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_ai_assistant": { + "name": "enable_ai_assistant", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "show_terminal_in_sidebar": { + "name": "show_terminal_in_sidebar", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "show_file_manager_in_sidebar": { + "name": "show_file_manager_in_sidebar", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "show_tunnel_in_sidebar": { + "name": "show_tunnel_in_sidebar", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "show_docker_in_sidebar": { + "name": "show_docker_in_sidebar", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "show_server_stats_in_sidebar": { + "name": "show_server_stats_in_sidebar", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "default_path": { + "name": "default_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stats_config": { + "name": "stats_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "docker_config": { + "name": "docker_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "web_ui_config": { + "name": "web_ui_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_proxmox": { + "name": "enable_proxmox", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "proxmox_config": { + "name": "proxmox_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_proxmox_stats": { + "name": "enable_proxmox_stats", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "proxmox_stats_config": { + "name": "proxmox_stats_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "terminal_config": { + "name": "terminal_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "quick_actions": { + "name": "quick_actions", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enable_ssh": { + "name": "enable_ssh", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "enable_rdp": { + "name": "enable_rdp", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_vnc": { + "name": "enable_vnc", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "enable_telnet": { + "name": "enable_telnet", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "ssh_port": { + "name": "ssh_port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 22 + }, + "rdp_port": { + "name": "rdp_port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 3389 + }, + "vnc_port": { + "name": "vnc_port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 5900 + }, + "telnet_port": { + "name": "telnet_port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 23 + }, + "rdp_credential_id": { + "name": "rdp_credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_user": { + "name": "rdp_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_password": { + "name": "rdp_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_domain": { + "name": "rdp_domain", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_security": { + "name": "rdp_security", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_ignore_cert": { + "name": "rdp_ignore_cert", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "vnc_credential_id": { + "name": "vnc_credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vnc_password": { + "name": "vnc_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vnc_user": { + "name": "vnc_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "telnet_user": { + "name": "telnet_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "telnet_password": { + "name": "telnet_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "telnet_credential_id": { + "name": "telnet_credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_auth_type": { + "name": "rdp_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vnc_auth_type": { + "name": "vnc_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "telnet_auth_type": { + "name": "telnet_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "security": { + "name": "security", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ignore_cert": { + "name": "ignore_cert", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "guacamole_config": { + "name": "guacamole_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "use_socks5": { + "name": "use_socks5", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_host": { + "name": "socks5_host", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_port": { + "name": "socks5_port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_username": { + "name": "socks5_username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_password": { + "name": "socks5_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "socks5_proxy_chain": { + "name": "socks5_proxy_chain", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "connection_origin": { + "name": "connection_origin", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mac_address": { + "name": "mac_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "wol_broadcast_address": { + "name": "wol_broadcast_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "port_knock_sequence": { + "name": "port_knock_sequence", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_fingerprint": { + "name": "host_key_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_type": { + "name": "host_key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_algorithm": { + "name": "host_key_algorithm", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'sha256'" + }, + "host_key_first_seen": { + "name": "host_key_first_seen", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_last_verified": { + "name": "host_key_last_verified", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_key_changed_count": { + "name": "host_key_changed_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "ssh_data_sync_id_unique": { + "name": "ssh_data_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + }, + "idx_ssh_data_user_id": { + "name": "idx_ssh_data_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_ssh_data_parent_host": { + "name": "idx_ssh_data_parent_host", + "columns": [ + "parent_host_id" + ], + "isUnique": false + }, + "idx_ssh_data_credential": { + "name": "idx_ssh_data_credential", + "columns": [ + "credential_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ssh_data_user_id_users_id_fk": { + "name": "ssh_data_user_id_users_id_fk", + "tableFrom": "ssh_data", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_data_parent_host_id_ssh_data_id_fk": { + "name": "ssh_data_parent_host_id_ssh_data_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_data", + "columnsFrom": [ + "parent_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_vault_profile_id_vault_profiles_id_fk": { + "name": "ssh_data_vault_profile_id_vault_profiles_id_fk", + "tableFrom": "ssh_data", + "tableTo": "vault_profiles", + "columnsFrom": [ + "vault_profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_rdp_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_rdp_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "rdp_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_vnc_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_vnc_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "vnc_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "ssh_data_telnet_credential_id_ssh_credentials_id_fk": { + "name": "ssh_data_telnet_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_data", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "telnet_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "network_topology": { + "name": "network_topology", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "topology": { + "name": "topology", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "network_topology_user_id_users_id_fk": { + "name": "network_topology_user_id_users_id_fk", + "tableFrom": "network_topology", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "notification_channels": { + "name": "notification_channels", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "notification_channels_user_id_users_id_fk": { + "name": "notification_channels_user_id_users_id_fk", + "tableFrom": "notification_channels", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "opkssh_tokens": { + "name": "opkssh_tokens", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ssh_cert": { + "name": "ssh_cert", + "type": "text(8192)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text(8192)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sub": { + "name": "sub", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "issuer": { + "name": "issuer", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "audience": { + "name": "audience", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_opkssh_tokens_user_host": { + "name": "idx_opkssh_tokens_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "opkssh_tokens_user_id_users_id_fk": { + "name": "opkssh_tokens_user_id_users_id_fk", + "tableFrom": "opkssh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "opkssh_tokens_host_id_ssh_data_id_fk": { + "name": "opkssh_tokens_host_id_ssh_data_id_fk", + "tableFrom": "opkssh_tokens", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "plugin_install_counts": { + "name": "plugin_install_counts", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "plugin_id": { + "name": "plugin_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "registry_id": { + "name": "registry_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'aggregate-telemetry'" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_plugin_install_counts_plugin_registry": { + "name": "idx_plugin_install_counts_plugin_registry", + "columns": [ + "plugin_id", + "registry_id" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "plugin_permission_grants": { + "name": "plugin_permission_grants", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "plugin_id": { + "name": "plugin_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "capability": { + "name": "capability", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "granted_at": { + "name": "granted_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "granted_by": { + "name": "granted_by", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_plugin_permission_grants_plugin_capability": { + "name": "idx_plugin_permission_grants_plugin_capability", + "columns": [ + "plugin_id", + "capability" + ], + "isUnique": true + } + }, + "foreignKeys": { + "plugin_permission_grants_plugin_id_plugins_id_fk": { + "name": "plugin_permission_grants_plugin_id_plugins_id_fk", + "tableFrom": "plugin_permission_grants", + "tableTo": "plugins", + "columnsFrom": [ + "plugin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "plugin_permission_grants_granted_by_users_id_fk": { + "name": "plugin_permission_grants_granted_by_users_id_fk", + "tableFrom": "plugin_permission_grants", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "plugin_registries": { + "name": "plugin_registries", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'community'" + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "signing_key": { + "name": "signing_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_index_hash": { + "name": "last_index_hash", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "plugin_storage": { + "name": "plugin_storage", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "plugin_id": { + "name": "plugin_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_plugin_storage_plugin_key": { + "name": "idx_plugin_storage_plugin_key", + "columns": [ + "plugin_id", + "key" + ], + "isUnique": true + } + }, + "foreignKeys": { + "plugin_storage_plugin_id_plugins_id_fk": { + "name": "plugin_storage_plugin_id_plugins_id_fk", + "tableFrom": "plugin_storage", + "tableTo": "plugins", + "columnsFrom": [ + "plugin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "plugins": { + "name": "plugins", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "version": { + "name": "version", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tier": { + "name": "tier", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'available'" + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'community'" + }, + "registry_id": { + "name": "registry_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'disabled'" + }, + "installed_at": { + "name": "installed_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "auto_update": { + "name": "auto_update", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "manifest_json": { + "name": "manifest_json", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_plugins_registry_id": { + "name": "idx_plugins_registry_id", + "columns": [ + "registry_id" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "proxmox_node_history": { + "name": "proxmox_node_history", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ts": { + "name": "ts", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "cpu_percent": { + "name": "cpu_percent", + "type": "real", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mem_percent": { + "name": "mem_percent", + "type": "real", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "disk_percent": { + "name": "disk_percent", + "type": "real", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "net_rx_bytes": { + "name": "net_rx_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "net_tx_bytes": { + "name": "net_tx_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "proxmox_node_history_host_id_ssh_data_id_fk": { + "name": "proxmox_node_history_host_id_ssh_data_id_fk", + "tableFrom": "proxmox_node_history", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "proxmox_stats_preferences": { + "name": "proxmox_stats_preferences", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_proxmox_stats_prefs_user_host": { + "name": "idx_proxmox_stats_prefs_user_host", + "columns": [ + "user_id", + "host_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "proxmox_stats_preferences_user_id_users_id_fk": { + "name": "proxmox_stats_preferences_user_id_users_id_fk", + "tableFrom": "proxmox_stats_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "proxmox_stats_preferences_host_id_ssh_data_id_fk": { + "name": "proxmox_stats_preferences_host_id_ssh_data_id_fk", + "tableFrom": "proxmox_stats_preferences", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "recent_activity": { + "name": "recent_activity", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_name": { + "name": "host_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "timestamp": { + "name": "timestamp", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_recent_activity_user_ts": { + "name": "idx_recent_activity_user_ts", + "columns": [ + "user_id", + "timestamp" + ], + "isUnique": false + } + }, + "foreignKeys": { + "recent_activity_user_id_users_id_fk": { + "name": "recent_activity_user_id_users_id_fk", + "tableFrom": "recent_activity", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "recent_activity_host_id_ssh_data_id_fk": { + "name": "recent_activity_host_id_ssh_data_id_fk", + "tableFrom": "recent_activity", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "roles": { + "name": "roles", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_system": { + "name": "is_system", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "roles_name_unique": { + "name": "roles_name_unique", + "columns": [ + "name" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "secret_sources": { + "name": "secret_sources", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'onepassword-connect'" + }, + "base_url": { + "name": "base_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "shared": { + "name": "shared", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_secret_sources_user": { + "name": "idx_secret_sources_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "secret_sources_user_id_users_id_fk": { + "name": "secret_sources_user_id_users_id_fk", + "tableFrom": "secret_sources", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "session_recordings": { + "name": "session_recordings", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_id": { + "name": "access_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "ended_at": { + "name": "ended_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "commands": { + "name": "commands", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "dangerous_actions": { + "name": "dangerous_actions", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "recording_path": { + "name": "recording_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "protocol": { + "name": "protocol", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ssh'" + }, + "format": { + "name": "format", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'text'" + }, + "terminated_by_owner": { + "name": "terminated_by_owner", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "termination_reason": { + "name": "termination_reason", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_session_recordings_user_started": { + "name": "idx_session_recordings_user_started", + "columns": [ + "user_id", + "started_at" + ], + "isUnique": false + }, + "idx_session_recordings_host": { + "name": "idx_session_recordings_host", + "columns": [ + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "session_recordings_host_id_ssh_data_id_fk": { + "name": "session_recordings_host_id_ssh_data_id_fk", + "tableFrom": "session_recordings", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_recordings_user_id_users_id_fk": { + "name": "session_recordings_user_id_users_id_fk", + "tableFrom": "session_recordings", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "session_recordings_access_id_host_access_id_fk": { + "name": "session_recordings_access_id_host_access_id_fk", + "tableFrom": "session_recordings", + "tableTo": "host_access", + "columnsFrom": [ + "access_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "session_share_participants": { + "name": "session_share_participants", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "share_id": { + "name": "share_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "guest_label": { + "name": "guest_label", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "joined_at": { + "name": "joined_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "left_at": { + "name": "left_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "session_share_participants_share_id_session_shares_id_fk": { + "name": "session_share_participants_share_id_session_shares_id_fk", + "tableFrom": "session_share_participants", + "tableTo": "session_shares", + "columnsFrom": [ + "share_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_share_participants_user_id_users_id_fk": { + "name": "session_share_participants_user_id_users_id_fk", + "tableFrom": "session_share_participants", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "session_shares": { + "name": "session_shares", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "protocol": { + "name": "protocol", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tab_instance_id": { + "name": "tab_instance_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "share_type": { + "name": "share_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_user_id": { + "name": "target_user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "link_token": { + "name": "link_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'read-only'" + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_joined_at": { + "name": "last_joined_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "join_count": { + "name": "join_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + } + }, + "indexes": { + "session_shares_link_token_unique": { + "name": "session_shares_link_token_unique", + "columns": [ + "link_token" + ], + "isUnique": true + }, + "idx_session_shares_session_id": { + "name": "idx_session_shares_session_id", + "columns": [ + "session_id" + ], + "isUnique": false + }, + "idx_session_shares_host_id": { + "name": "idx_session_shares_host_id", + "columns": [ + "host_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "session_shares_host_id_ssh_data_id_fk": { + "name": "session_shares_host_id_ssh_data_id_fk", + "tableFrom": "session_shares", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_shares_owner_user_id_users_id_fk": { + "name": "session_shares_owner_user_id_users_id_fk", + "tableFrom": "session_shares", + "tableTo": "users", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_shares_target_user_id_users_id_fk": { + "name": "session_shares_target_user_id_users_id_fk", + "tableFrom": "session_shares", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "sessions": { + "name": "sessions", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "jwt_token": { + "name": "jwt_token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_info": { + "name": "device_info", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "oidc_sub": { + "name": "oidc_sub", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "oidc_sid": { + "name": "oidc_sid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sso_provider_id": { + "name": "sso_provider_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_active_at": { + "name": "last_active_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_sessions_user_id": { + "name": "idx_sessions_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_sessions_expires_at": { + "name": "idx_sessions_expires_at", + "columns": [ + "expires_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "settings": { + "name": "settings", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "shared_credential_secrets": { + "name": "shared_credential_secrets", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "credential_access_id": { + "name": "credential_access_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_user_id": { + "name": "target_user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "encrypted_username": { + "name": "encrypted_username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'password'" + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key": { + "name": "encrypted_key", + "type": "text(16384)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key_password": { + "name": "encrypted_key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text(4096)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cert_public_key": { + "name": "cert_public_key", + "type": "text(8192)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_shared_credential_secrets_scope": { + "name": "idx_shared_credential_secrets_scope", + "columns": [ + "credential_access_id", + "target_user_id" + ], + "isUnique": true + }, + "idx_shared_credential_secrets_target": { + "name": "idx_shared_credential_secrets_target", + "columns": [ + "target_user_id", + "credential_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "shared_credential_secrets_target_user_id_users_id_fk": { + "name": "shared_credential_secrets_target_user_id_users_id_fk", + "tableFrom": "shared_credential_secrets", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_credential_secrets_credential_id_ssh_credentials_id_fk": { + "name": "shared_credential_secrets_credential_id_ssh_credentials_id_fk", + "tableFrom": "shared_credential_secrets", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_cred_secrets_access_id_fk": { + "name": "shared_cred_secrets_access_id_fk", + "tableFrom": "shared_credential_secrets", + "tableTo": "credential_access", + "columnsFrom": [ + "credential_access_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "shared_host_auth_overrides": { + "name": "shared_host_auth_overrides", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "protocol": { + "name": "protocol", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ssh'" + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "shared_host_auth_overrides_host_user_protocol_unique": { + "name": "shared_host_auth_overrides_host_user_protocol_unique", + "columns": [ + "host_id", + "user_id", + "protocol" + ], + "isUnique": true + } + }, + "foreignKeys": { + "shared_host_auth_overrides_host_id_ssh_data_id_fk": { + "name": "shared_host_auth_overrides_host_id_ssh_data_id_fk", + "tableFrom": "shared_host_auth_overrides", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_auth_overrides_user_id_users_id_fk": { + "name": "shared_host_auth_overrides_user_id_users_id_fk", + "tableFrom": "shared_host_auth_overrides", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_auth_overrides_credential_id_ssh_credentials_id_fk": { + "name": "shared_host_auth_overrides_credential_id_ssh_credentials_id_fk", + "tableFrom": "shared_host_auth_overrides", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "shared_host_secrets": { + "name": "shared_host_secrets", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "host_access_id": { + "name": "host_access_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_user_id": { + "name": "target_user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "protocol": { + "name": "protocol", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ssh'" + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'credential'" + }, + "original_credential_id": { + "name": "original_credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_username": { + "name": "encrypted_username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_auth_type": { + "name": "encrypted_auth_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key": { + "name": "encrypted_key", + "type": "text(16384)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key_password": { + "name": "encrypted_key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_key_type": { + "name": "encrypted_key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encrypted_domain": { + "name": "encrypted_domain", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_shared_host_secrets_scope": { + "name": "idx_shared_host_secrets_scope", + "columns": [ + "host_access_id", + "target_user_id", + "protocol" + ], + "isUnique": true + } + }, + "foreignKeys": { + "shared_host_secrets_host_access_id_host_access_id_fk": { + "name": "shared_host_secrets_host_access_id_host_access_id_fk", + "tableFrom": "shared_host_secrets", + "tableTo": "host_access", + "columnsFrom": [ + "host_access_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_secrets_target_user_id_users_id_fk": { + "name": "shared_host_secrets_target_user_id_users_id_fk", + "tableFrom": "shared_host_secrets", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shared_host_secrets_original_credential_id_ssh_credentials_id_fk": { + "name": "shared_host_secrets_original_credential_id_ssh_credentials_id_fk", + "tableFrom": "shared_host_secrets", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "original_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "snippet_access": { + "name": "snippet_access", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "snippet_id": { + "name": "snippet_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission_level": { + "name": "permission_level", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'view'" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_snippet_access_user_id": { + "name": "idx_snippet_access_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_snippet_access_snippet_id": { + "name": "idx_snippet_access_snippet_id", + "columns": [ + "snippet_id" + ], + "isUnique": false + }, + "idx_snippet_access_role_id": { + "name": "idx_snippet_access_role_id", + "columns": [ + "role_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "snippet_access_snippet_id_snippets_id_fk": { + "name": "snippet_access_snippet_id_snippets_id_fk", + "tableFrom": "snippet_access", + "tableTo": "snippets", + "columnsFrom": [ + "snippet_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "snippet_access_user_id_users_id_fk": { + "name": "snippet_access_user_id_users_id_fk", + "tableFrom": "snippet_access", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "snippet_access_role_id_roles_id_fk": { + "name": "snippet_access_role_id_roles_id_fk", + "tableFrom": "snippet_access", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "snippet_access_granted_by_users_id_fk": { + "name": "snippet_access_granted_by_users_id_fk", + "tableFrom": "snippet_access", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "snippet_folders": { + "name": "snippet_folders", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "snippet_folders_sync_id_unique": { + "name": "snippet_folders_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "snippet_folders_user_id_users_id_fk": { + "name": "snippet_folders_user_id_users_id_fk", + "tableFrom": "snippet_folders", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "snippets": { + "name": "snippets", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "host_filter": { + "name": "host_filter", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_note": { + "name": "is_note", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": { + "snippets_sync_id_unique": { + "name": "snippets_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + }, + "idx_snippets_user_id": { + "name": "idx_snippets_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "snippets_user_id_users_id_fk": { + "name": "snippets_user_id_users_id_fk", + "tableFrom": "snippets", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "ssh_credential_usage": { + "name": "ssh_credential_usage", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "used_at": { + "name": "used_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_ssh_credential_usage_credential": { + "name": "idx_ssh_credential_usage_credential", + "columns": [ + "credential_id" + ], + "isUnique": false + }, + "idx_ssh_credential_usage_user": { + "name": "idx_ssh_credential_usage_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ssh_credential_usage_credential_id_ssh_credentials_id_fk": { + "name": "ssh_credential_usage_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_credential_usage", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_credential_usage_host_id_ssh_data_id_fk": { + "name": "ssh_credential_usage_host_id_ssh_data_id_fk", + "tableFrom": "ssh_credential_usage", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_credential_usage_user_id_users_id_fk": { + "name": "ssh_credential_usage_user_id_users_id_fk", + "tableFrom": "ssh_credential_usage", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "ssh_credentials": { + "name": "ssh_credentials", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tags": { + "name": "tags", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "pin": { + "name": "pin", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key": { + "name": "key", + "type": "text(16384)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text(16384)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text(4096)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_password": { + "name": "key_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "detected_key_type": { + "name": "detected_key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cert_public_key": { + "name": "cert_public_key", + "type": "text(8192)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "usage_count": { + "name": "usage_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "ssh_credentials_sync_id_unique": { + "name": "ssh_credentials_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + }, + "idx_ssh_credentials_user_id": { + "name": "idx_ssh_credentials_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ssh_credentials_user_id_users_id_fk": { + "name": "ssh_credentials_user_id_users_id_fk", + "tableFrom": "ssh_credentials", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "ssh_folders": { + "name": "ssh_folders", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "ssh_folders_sync_id_unique": { + "name": "ssh_folders_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + }, + "idx_ssh_folders_user_id": { + "name": "idx_ssh_folders_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "ssh_folders_user_id_users_id_fk": { + "name": "ssh_folders_user_id_users_id_fk", + "tableFrom": "ssh_folders", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ssh_folders_credential_id_ssh_credentials_id_fk": { + "name": "ssh_folders_credential_id_ssh_credentials_id_fk", + "tableFrom": "ssh_folders", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "sso_providers": { + "name": "sso_providers", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "config": { + "name": "config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "sync_tombstones": { + "name": "sync_tombstones", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "sync_tombstones_user_id_users_id_fk": { + "name": "sync_tombstones_user_id_users_id_fk", + "tableFrom": "sync_tombstones", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "termix_identities": { + "name": "termix_identities", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "handle": { + "name": "handle", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "termix_identities_user_id_unique": { + "name": "termix_identities_user_id_unique", + "columns": [ + "user_id" + ], + "isUnique": true + }, + "termix_identities_handle_unique": { + "name": "termix_identities_handle_unique", + "columns": [ + "handle" + ], + "isUnique": true + } + }, + "foreignKeys": { + "termix_identities_user_id_users_id_fk": { + "name": "termix_identities_user_id_users_id_fk", + "tableFrom": "termix_identities", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "termix_identity_ca": { + "name": "termix_identity_ca", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "identity_id": { + "name": "identity_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text(4096)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text(8192)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "validity_days": { + "name": "validity_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 90 + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "termix_identity_ca_identity_id_unique": { + "name": "termix_identity_ca_identity_id_unique", + "columns": [ + "identity_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "termix_identity_ca_identity_id_termix_identities_id_fk": { + "name": "termix_identity_ca_identity_id_termix_identities_id_fk", + "tableFrom": "termix_identity_ca", + "tableTo": "termix_identities", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "termix_identity_ca_user_id_users_id_fk": { + "name": "termix_identity_ca_user_id_users_id_fk", + "tableFrom": "termix_identity_ca", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "termix_identity_keys": { + "name": "termix_identity_keys", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "identity_id": { + "name": "identity_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text(8192)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "algorithm": { + "name": "algorithm", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "comment": { + "name": "comment", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'manual'" + }, + "credential_id": { + "name": "credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "termix_identity_keys_identity_id_termix_identities_id_fk": { + "name": "termix_identity_keys_identity_id_termix_identities_id_fk", + "tableFrom": "termix_identity_keys", + "tableTo": "termix_identities", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "termix_identity_keys_user_id_users_id_fk": { + "name": "termix_identity_keys_user_id_users_id_fk", + "tableFrom": "termix_identity_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "termix_identity_keys_credential_id_ssh_credentials_id_fk": { + "name": "termix_identity_keys_credential_id_ssh_credentials_id_fk", + "tableFrom": "termix_identity_keys", + "tableTo": "ssh_credentials", + "columnsFrom": [ + "credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "tmux_session_tags": { + "name": "tmux_session_tags", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "session_name": { + "name": "session_name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tag": { + "name": "tag", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "tmux_session_tags_user_id_users_id_fk": { + "name": "tmux_session_tags_user_id_users_id_fk", + "tableFrom": "tmux_session_tags", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tmux_session_tags_host_id_ssh_data_id_fk": { + "name": "tmux_session_tags_host_id_ssh_data_id_fk", + "tableFrom": "tmux_session_tags", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "transfer_recent": { + "name": "transfer_recent", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_host_id": { + "name": "source_host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dest_host_id": { + "name": "dest_host_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dest_path": { + "name": "dest_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dest_path_label": { + "name": "dest_path_label", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_transfer_recent_user": { + "name": "idx_transfer_recent_user", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "transfer_recent_user_id_users_id_fk": { + "name": "transfer_recent_user_id_users_id_fk", + "tableFrom": "transfer_recent", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "transfer_recent_source_host_id_ssh_data_id_fk": { + "name": "transfer_recent_source_host_id_ssh_data_id_fk", + "tableFrom": "transfer_recent", + "tableTo": "ssh_data", + "columnsFrom": [ + "source_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "transfer_recent_dest_host_id_ssh_data_id_fk": { + "name": "transfer_recent_dest_host_id_ssh_data_id_fk", + "tableFrom": "transfer_recent", + "tableTo": "ssh_data", + "columnsFrom": [ + "dest_host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "trusted_devices": { + "name": "trusted_devices", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_fingerprint": { + "name": "device_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "device_info": { + "name": "device_info", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_trusted_devices_user_id": { + "name": "idx_trusted_devices_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "trusted_devices_user_id_users_id_fk": { + "name": "trusted_devices_user_id_users_id_fk", + "tableFrom": "trusted_devices", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "ui_preferences": { + "name": "ui_preferences", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "ui_preferences_user_id_users_id_fk": { + "name": "ui_preferences_user_id_users_id_fk", + "tableFrom": "ui_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_open_tabs": { + "name": "user_open_tabs", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tab_type": { + "name": "tab_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host_id": { + "name": "host_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tab_order": { + "name": "tab_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "backend_session_id": { + "name": "backend_session_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_user_open_tabs_user_id": { + "name": "idx_user_open_tabs_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "user_open_tabs_user_id_users_id_fk": { + "name": "user_open_tabs_user_id_users_id_fk", + "tableFrom": "user_open_tabs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_open_tabs_host_id_ssh_data_id_fk": { + "name": "user_open_tabs_host_id_ssh_data_id_fk", + "tableFrom": "user_open_tabs", + "tableTo": "ssh_data", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_preferences": { + "name": "user_preferences", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "reopen_tabs_on_login": { + "name": "reopen_tabs_on_login", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "font_size": { + "name": "font_size", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "language": { + "name": "language", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "storage_mode": { + "name": "storage_mode", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "command_autocomplete": { + "name": "command_autocomplete", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "command_palette_enabled": { + "name": "command_palette_enabled", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_host_tags": { + "name": "show_host_tags", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host_tray_on_click": { + "name": "host_tray_on_click", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "pin_app_rail": { + "name": "pin_app_rail", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expand_app_rail_on_hover": { + "name": "expand_app_rail_on_hover", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_pin_app_rail_button": { + "name": "show_pin_app_rail_button", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "folders_collapsed": { + "name": "folders_collapsed", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "confirm_snippet_execution": { + "name": "confirm_snippet_execution", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "disable_update_check": { + "name": "disable_update_check", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "confirm_tab_close": { + "name": "confirm_tab_close", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "hidden_rail_tabs": { + "name": "hidden_rail_tabs", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_assistant_enabled": { + "name": "ai_assistant_enabled", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_read_only_commands": { + "name": "ai_read_only_commands", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "compact_host_view": { + "name": "compact_host_view", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "status_color_scheme": { + "name": "status_color_scheme", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "custom_themes": { + "name": "custom_themes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "custom_keybindings": { + "name": "custom_keybindings", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "terminal_defaults": { + "name": "terminal_defaults", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rdp_defaults": { + "name": "rdp_defaults", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "terminal_macros": { + "name": "terminal_macros", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "user_preferences_user_id_users_id_fk": { + "name": "user_preferences_user_id_users_id_fk", + "tableFrom": "user_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_roles": { + "name": "user_roles", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "granted_by": { + "name": "granted_by", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "granted_at": { + "name": "granted_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_user_roles_user_role": { + "name": "idx_user_roles_user_role", + "columns": [ + "user_id", + "role_id" + ], + "isUnique": true + }, + "idx_user_roles_role_id": { + "name": "idx_user_roles_role_id", + "columns": [ + "role_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "user_roles_user_id_users_id_fk": { + "name": "user_roles_user_id_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_role_id_roles_id_fk": { + "name": "user_roles_role_id_roles_id_fk", + "tableFrom": "user_roles", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_granted_by_users_id_fk": { + "name": "user_roles_granted_by_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "granted_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_workspaces": { + "name": "user_workspaces", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'manual'" + }, + "is_default": { + "name": "is_default", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{}'" + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "user_workspaces_sync_id_unique": { + "name": "user_workspaces_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + }, + "idx_user_workspaces_user_id": { + "name": "idx_user_workspaces_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "user_workspaces_user_id_users_id_fk": { + "name": "user_workspaces_user_id_users_id_fk", + "tableFrom": "user_workspaces", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "users": { + "name": "users", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "is_admin": { + "name": "is_admin", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "is_oidc": { + "name": "is_oidc", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "oidc_identifier": { + "name": "oidc_identifier", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sso_provider_id": { + "name": "sso_provider_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "client_secret": { + "name": "client_secret", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "issuer_url": { + "name": "issuer_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "authorization_url": { + "name": "authorization_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token_url": { + "name": "token_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "identifier_path": { + "name": "identifier_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name_path": { + "name": "name_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scopes": { + "name": "scopes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'openid email profile'" + }, + "totp_secret": { + "name": "totp_secret", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "totp_enabled": { + "name": "totp_enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "totp_backup_codes": { + "name": "totp_backup_codes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "registered_at": { + "name": "registered_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "donation_modal_dismissed": { + "name": "donation_modal_dismissed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "vault_profiles": { + "name": "vault_profiles", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "folder": { + "name": "folder", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tags": { + "name": "tags", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vault_addr": { + "name": "vault_addr", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "vault_namespace": { + "name": "vault_namespace", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "oidc_mount": { + "name": "oidc_mount", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "oidc_role": { + "name": "oidc_role", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ssh_mount": { + "name": "ssh_mount", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ssh_role": { + "name": "ssh_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "valid_principals": { + "name": "valid_principals", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key_type": { + "name": "key_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "shared": { + "name": "shared", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "sync_id": { + "name": "sync_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "vault_profiles_sync_id_unique": { + "name": "vault_profiles_sync_id_unique", + "columns": [ + "sync_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "vault_profiles_user_id_users_id_fk": { + "name": "vault_profiles_user_id_users_id_fk", + "tableFrom": "vault_profiles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "vault_tokens": { + "name": "vault_tokens", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "profile_id": { + "name": "profile_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ssh_cert": { + "name": "ssh_cert", + "type": "text(8192)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text(8192)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_used": { + "name": "last_used", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_vault_tokens_user_profile": { + "name": "idx_vault_tokens_user_profile", + "columns": [ + "user_id", + "profile_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "vault_tokens_user_id_users_id_fk": { + "name": "vault_tokens_user_id_users_id_fk", + "tableFrom": "vault_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "vault_tokens_profile_id_vault_profiles_id_fk": { + "name": "vault_tokens_profile_id_vault_profiles_id_fk", + "tableFrom": "vault_tokens", + "tableTo": "vault_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "webauthn_credentials": { + "name": "webauthn_credentials", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "credential_id": { + "name": "credential_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "counter": { + "name": "counter", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "backed_up": { + "name": "backed_up", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "transports": { + "name": "transports", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_verification": { + "name": "user_verification", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'preferred'" + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "last_used_at": { + "name": "last_used_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "webauthn_credentials_user_id_users_id_fk": { + "name": "webauthn_credentials_user_id_users_id_fk", + "tableFrom": "webauthn_credentials", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/drizzle/sqlite/meta/_journal.json b/drizzle/sqlite/meta/_journal.json index 3a4db56b1..9ebd00de4 100644 --- a/drizzle/sqlite/meta/_journal.json +++ b/drizzle/sqlite/meta/_journal.json @@ -155,6 +155,13 @@ "when": 1789991403283, "tag": "0021_dashing_lester", "breakpoints": true + }, + { + "idx": 22, + "version": "6", + "when": 1790083818524, + "tag": "0022_steady_the_hood", + "breakpoints": true } ] } \ No newline at end of file diff --git a/plugins/ai/backend/context.ts b/plugins/ai/backend/context.ts index ce8fc40ac..a66a79513 100644 --- a/plugins/ai/backend/context.ts +++ b/plugins/ai/backend/context.ts @@ -13,7 +13,7 @@ export function buildSystemPrompt(options: { }): string { const lines: string[] = [ "You are the assistant built into Termix, a self-hosted server management app.", - "You help the user manage their servers, snippets, automations, fleets and alerts.", + "You help the user manage their servers, snippets, automations and fleets.", "", "How you work:", "- You start with no knowledge of this user's setup. Call a read tool to find out anything you need.", @@ -24,7 +24,7 @@ export function buildSystemPrompt(options: { "- Do exactly what was asked, and nothing beyond it. A question is a request for an answer, not for changes.", "- Questions like 'what is running on this server', 'check this host' or 'why is this slow' are answered with information. Read, then report. Do not propose anything.", "- Only propose a change when the user asked for one, in words like 'add', 'create', 'set up', 'fix' or 'change'.", - "- Do not propose follow-up work you thought of yourself: no monitoring, no alert rules, no scripts, no snippets, no cleanup, unless that is what was requested.", + "- Do not propose follow-up work you thought of yourself: no monitoring automations, no scripts, no snippets, no cleanup, unless that is what was requested.", "- If you think something is worth doing, say so in one sentence and stop. Let the user ask.", "- One request means one proposal at most. Do not bundle extras alongside it.", "", diff --git a/plugins/ai/backend/index.mjs b/plugins/ai/backend/index.mjs index 53e065629..da04e1d01 100644 --- a/plugins/ai/backend/index.mjs +++ b/plugins/ai/backend/index.mjs @@ -4,11 +4,11 @@ * This plugin runs on the main thread rather than in a worker for the same * reason ssh-terminal, docker and host-metrics do (see * src/backend/plugins/first-party.ts): it writes directly across hosts, - * snippets, fleets, alert rules and automations through their repositories, + * snippets, fleets and automations through their repositories, * runs approved commands over the shared SSH pool via resolveHostById and * withConnection, and streams its chat replies as server-sent events. None * of that fits the worker ctx -- ctx.hosts is a 13-field read-only view with - * no write methods and no snippets/fleets/alerts/automations surface at all, + * no write methods and no snippets/fleets/automations surface at all, * and ctx.http.route replies with a single postMessage value rather than a * stream. * diff --git a/plugins/ai/backend/tools/executor.ts b/plugins/ai/backend/tools/executor.ts index 0ec334754..ff8a89473 100644 --- a/plugins/ai/backend/tools/executor.ts +++ b/plugins/ai/backend/tools/executor.ts @@ -1,5 +1,4 @@ import { - createCurrentAlertRepository, createCurrentAutomationRepository, createCurrentFleetRepository, createCurrentHostRepository, @@ -217,35 +216,6 @@ export async function applyProposal( }; } - case "propose_create_alert_rule": { - const created = await createCurrentAlertRepository().createAlertRule({ - userId, - name: requireString(payload.name, "name"), - hostId: - payload.hostId === null || payload.hostId === undefined - ? null - : requireNumber(payload.hostId, "hostId"), - enabled: true, - triggerType: requireString(payload.triggerType, "triggerType"), - thresholdValue: - payload.thresholdValue === null || - payload.thresholdValue === undefined - ? null - : Number(payload.thresholdValue), - thresholdDurationSeconds: - payload.thresholdDurationSeconds === null || - payload.thresholdDurationSeconds === undefined - ? null - : Number(payload.thresholdDurationSeconds), - cooldownMinutes: Number(payload.cooldownMinutes) || 15, - channelIds: [], - } as any); - return { - ok: true, - summary: `Created alert rule ${(created as any)?.name ?? ""}`.trim(), - }; - } - case "propose_create_automation": { // Reuses the same validator the automations route runs, so an // LLM-authored definition is held to exactly the human standard. diff --git a/plugins/ai/backend/tools/propose-tools.ts b/plugins/ai/backend/tools/propose-tools.ts index 107d2aa5e..0d737a52a 100644 --- a/plugins/ai/backend/tools/propose-tools.ts +++ b/plugins/ai/backend/tools/propose-tools.ts @@ -216,40 +216,6 @@ export const proposeTools: AiTool[] = [ hostIds: args.hostIds ?? [], }), }, - { - name: "propose_create_alert_rule", - description: - "Propose a new alert rule that fires when a host metric crosses a threshold.", - category: "propose", - parameters: objectSchema( - { - name: str("Rule name"), - hostId: num("Host id to watch, or omit to watch all hosts"), - triggerType: str( - "What to watch, for example cpu, memory, disk or host_status", - ), - thresholdValue: num("Threshold to compare against"), - thresholdDurationSeconds: num( - "How long the breach must persist before firing", - ), - cooldownMinutes: num("Minimum minutes between repeat firings"), - }, - ["name", "triggerType"], - ), - handler: async (args) => - proposal( - "propose_create_alert_rule", - `Create alert rule ${String(args.name)}`, - { - name: args.name, - hostId: args.hostId ?? null, - triggerType: args.triggerType, - thresholdValue: args.thresholdValue ?? null, - thresholdDurationSeconds: args.thresholdDurationSeconds ?? null, - cooldownMinutes: args.cooldownMinutes ?? 15, - }, - ), - }, { name: "propose_run_command", description: diff --git a/plugins/ai/backend/tools/read-tools.ts b/plugins/ai/backend/tools/read-tools.ts index b98f7171c..235a4ff53 100644 --- a/plugins/ai/backend/tools/read-tools.ts +++ b/plugins/ai/backend/tools/read-tools.ts @@ -1,5 +1,5 @@ import { - createCurrentAlertRepository, + createCurrentNotificationChannelRepository, createCurrentAutomationRepository, createCurrentCommandHistoryRepository, createCurrentFleetRepository, @@ -190,30 +190,6 @@ export const readTools: AiTool[] = [ }; }, }, - { - name: "list_alert_rules", - description: - "List the user's alert rules with their thresholds and enabled state.", - category: "read", - parameters: objectSchema({}), - handler: async (_args, context) => { - const rules = await createCurrentAlertRepository().listAlertRules( - context.userId, - ); - return { - rules: rules.map((rule) => ({ - id: rule.id, - name: rule.name, - hostId: rule.host_id, - enabled: rule.enabled === 1, - triggerType: rule.trigger_type, - thresholdValue: rule.threshold_value, - thresholdDurationSeconds: rule.threshold_duration_seconds, - cooldownMinutes: rule.cooldown_minutes, - })), - }; - }, - }, { name: "list_notification_channels", description: @@ -222,7 +198,7 @@ export const readTools: AiTool[] = [ parameters: objectSchema({}), handler: async (_args, context) => { const channels = - await createCurrentAlertRepository().listNotificationChannels( + await createCurrentNotificationChannelRepository().listNotificationChannels( context.userId, ); return { @@ -235,35 +211,6 @@ export const readTools: AiTool[] = [ }; }, }, - { - name: "get_alert_firings", - description: - "Recent alert firings, newest first. Use this to answer questions about what has been alerting.", - category: "read", - parameters: objectSchema({ - limit: num("How many firings to return (default 25, max 100)"), - }), - handler: async (args, context) => { - const limit = Math.min(Math.max(Number(args.limit) || 25, 1), 100); - const result = await createCurrentAlertRepository().listAlertFirings({ - userId: context.userId, - limit, - offset: 0, - }); - return { - firings: (result.firings ?? []).map((firing) => ({ - id: firing.id, - ruleName: firing.rule_name, - hostName: firing.host_name, - firedAt: firing.fired_at, - resolvedAt: firing.resolved_at, - severity: firing.severity, - message: firing.message, - acknowledged: firing.acknowledged === 1, - })), - }; - }, - }, { name: "list_homepage_items", description: "List the user's homepage service-link tiles.", diff --git a/plugins/automations/backend/actions/index.ts b/plugins/automations/backend/actions/index.ts index d56d8f9b5..5a3f54101 100644 --- a/plugins/automations/backend/actions/index.ts +++ b/plugins/automations/backend/actions/index.ts @@ -14,7 +14,7 @@ import { import { withConnection } from "../../../../src/backend/hosts/ssh-connection-pool.js"; import { resolveSnippetCommand } from "../../../../src/backend/database/routes/snippets-execution.js"; import { - createCurrentAlertRepository, + createCurrentNotificationChannelRepository, createCurrentSnippetRepository, } from "../../../../src/backend/database/repositories/factory.js"; import { sendAutomationNotification } from "../notify.js"; @@ -86,7 +86,7 @@ async function runNotify( ); } - const repository = createCurrentAlertRepository(); + const repository = createCurrentNotificationChannelRepository(); const channels = await repository.listNotificationChannels(context.userId); const selected = channels.filter((channel) => step.channelIds.includes(channel.id), diff --git a/plugins/automations/frontend/AutomationsPanel.tsx b/plugins/automations/frontend/AutomationsPanel.tsx index 7ca0395ff..bb4d7d48b 100644 --- a/plugins/automations/frontend/AutomationsPanel.tsx +++ b/plugins/automations/frontend/AutomationsPanel.tsx @@ -31,7 +31,7 @@ import { getNotificationChannels, testNotificationChannel, type NotificationChannel, -} from "@/api/alerts-api"; +} from "@/api/notification-channels-api"; import { NotificationChannelDialog } from "@/sidebar/NotificationChannelDialog"; import { getSnippets } from "@/api/snippets-api"; import { getSSHHosts } from "@/api/ssh-host-management-api"; diff --git a/plugins/host-metrics/backend/alert-engine.ts b/plugins/host-metrics/backend/alert-engine.ts deleted file mode 100644 index 3fcb1ae67..000000000 --- a/plugins/host-metrics/backend/alert-engine.ts +++ /dev/null @@ -1,373 +0,0 @@ -import { createCurrentAlertRepository } from "../../../src/backend/database/repositories/factory.js"; -import { statsLogger } from "../../../src/backend/utils/logger.js"; -import { - sendNotification, - type AlertPayload, - type NotificationChannel, -} from "../../../src/backend/utils/notification-sender.js"; -import { sendDiscord } from "../../../src/backend/utils/discord-sender.js"; - -type AlertTriggerType = - | "host_offline" - | "host_online" - | "cpu_threshold" - | "memory_threshold" - | "disk_threshold" - | "health_check_failure" - | "health_check_recovery" - | "user_login"; - -interface AlertRule { - id: number; - userId: string; - hostId: number | null; - name: string; - enabled: boolean; - triggerType: AlertTriggerType; - thresholdValue: number | null; - thresholdDurationSeconds: number | null; - cooldownMinutes: number; -} - -/** - * Set once the alert rules have been copied into automations. From then on the - * automations engine owns evaluation, and this one stands down rather than - * sending a second notification for every rule. - * - * The class is left in place so an install that has not migrated yet, or one - * rolled back, still alerts exactly as before. - */ -let supersededByAutomations = false; - -export function markAlertEngineSuperseded(): void { - supersededByAutomations = true; -} - -export function isAlertEngineSuperseded(): boolean { - return supersededByAutomations; -} - -export class AlertEngine { - private static instance: AlertEngine; - - // "${ruleId}:${hostId}" → lastFiredAt ms - private cooldownMap = new Map(); - // "${ruleId}:${hostId}" → breachStartTime ms - private breachStartMap = new Map(); - // hostId → last known status - private lastStatusMap = new Map(); - // "${hostId}:${checkId}" → last known ok state - private healthCheckStateMap = new Map(); - - static getInstance(): AlertEngine { - if (!AlertEngine.instance) { - AlertEngine.instance = new AlertEngine(); - } - return AlertEngine.instance; - } - - async evaluateMetrics( - hostId: number, - metrics: { - cpu?: { percent: number | null } | null; - memory?: { percent: number | null } | null; - disk?: { percent: number | null } | null; - }, - ): Promise { - if (supersededByAutomations) return; - const rules = (await this.loadRulesForHost(hostId)).filter((r) => - ["cpu_threshold", "memory_threshold", "disk_threshold"].includes( - r.triggerType, - ), - ); - - if (rules.length === 0) return; - - const now = Date.now(); - - for (const rule of rules) { - let currentValue: number | null | undefined; - if (rule.triggerType === "cpu_threshold") - currentValue = metrics.cpu?.percent; - else if (rule.triggerType === "memory_threshold") - currentValue = metrics.memory?.percent; - else if (rule.triggerType === "disk_threshold") - currentValue = metrics.disk?.percent; - - if (currentValue == null || rule.thresholdValue == null) continue; - - const key = `${rule.id}:${hostId}`; - const isBreaching = currentValue >= rule.thresholdValue; - - if (isBreaching) { - if (!this.breachStartMap.has(key)) { - this.breachStartMap.set(key, now); - } - const breachStart = this.breachStartMap.get(key)!; - const durationMs = (rule.thresholdDurationSeconds ?? 0) * 1000; - if ( - now - breachStart >= durationMs && - !(await this.isCoolingDown(rule.id, hostId)) - ) { - const hostName = await this.getHostName(hostId); - await this.fireAlert(rule, hostId, hostName, { - value: currentValue, - message: `${rule.triggerType.replace("_threshold", "").toUpperCase()} usage at ${currentValue.toFixed(1)}% (threshold: ${rule.thresholdValue}%)`, - severity: currentValue >= 95 ? "critical" : "warning", - }); - } - } else { - this.breachStartMap.delete(key); - } - } - } - - async evaluateStatus(hostId: number, isOnline: boolean): Promise { - if (supersededByAutomations) return; - const currentStatus = isOnline ? "online" : "offline"; - const lastStatus = this.lastStatusMap.get(hostId); - - if (lastStatus === currentStatus) return; - this.lastStatusMap.set(hostId, currentStatus); - - if (lastStatus === undefined) return; - - const triggerType: AlertTriggerType = isOnline - ? "host_online" - : "host_offline"; - const rules = (await this.loadRulesForHost(hostId)).filter( - (r) => r.triggerType === triggerType, - ); - - for (const rule of rules) { - if (!(await this.isCoolingDown(rule.id, hostId))) { - const hostName = await this.getHostName(hostId); - await this.fireAlert(rule, hostId, hostName, { - message: isOnline - ? `Host "${hostName}" is back online` - : `Host "${hostName}" is offline`, - severity: isOnline ? "info" : "critical", - }); - } - } - } - - async evaluateHealthCheck( - hostId: number, - userId: string, - checkId: string, - ok: boolean, - detail?: string, - ): Promise { - if (supersededByAutomations) return; - const stateKey = `${hostId}:${checkId}`; - const lastOk = this.healthCheckStateMap.get(stateKey); - this.healthCheckStateMap.set(stateKey, ok); - - if (lastOk === undefined) return; - - let triggerType: AlertTriggerType | null = null; - if (!ok && lastOk) triggerType = "health_check_failure"; - else if (ok && !lastOk) triggerType = "health_check_recovery"; - - if (!triggerType) return; - - const rules = (await this.loadRulesForHostUser(hostId, userId)).filter( - (r) => r.triggerType === triggerType, - ); - - for (const rule of rules) { - if (!(await this.isCoolingDown(rule.id, hostId))) { - const hostName = await this.getHostName(hostId); - await this.fireAlert(rule, hostId, hostName, { - message: ok - ? `Health check recovered on "${hostName}"${detail ? `: ${detail}` : ""}` - : `Health check failed on "${hostName}"${detail ? `: ${detail}` : ""}`, - severity: ok ? "info" : "warning", - }); - } - } - } - - async evaluateUserLogin( - hostId: number, - userId: string, - sshUser: string, - fromIp: string, - ): Promise { - if (supersededByAutomations) return; - const rules = (await this.loadRulesForHostUser(hostId, userId)).filter( - (r) => r.triggerType === "user_login", - ); - - for (const rule of rules) { - if (!(await this.isCoolingDown(rule.id, hostId))) { - const hostName = await this.getHostName(hostId); - await this.fireAlert(rule, hostId, hostName, { - message: `User "${sshUser}" logged in to "${hostName}" from ${fromIp}`, - severity: "info", - }); - } - } - } - - private async fireAlert( - rule: AlertRule, - hostId: number, - hostName: string, - context: { - value?: number; - message: string; - severity: "info" | "warning" | "critical"; - }, - ): Promise { - this.markCooldown(rule.id, hostId); - - const payload: AlertPayload = { - hostName, - hostId, - triggerType: rule.triggerType, - value: context.value, - threshold: rule.thresholdValue ?? undefined, - message: context.message, - severity: context.severity, - timestamp: new Date().toISOString(), - ruleId: rule.id, - ruleName: rule.name, - }; - - try { - const repository = createCurrentAlertRepository(); - await repository.createFiring({ - userId: rule.userId, - ruleId: rule.id, - hostId, - hostName, - value: context.value ?? null, - message: context.message, - severity: context.severity, - }); - - await repository.pruneFiringsOlderThan(rule.userId, 30); - } catch (err) { - statsLogger.warn("Failed to write alert firing", { - operation: "alert_firing_insert_error", - ruleId: rule.id, - error: err instanceof Error ? err.message : String(err), - }); - } - - const channels = await this.loadChannelsForRule(rule.id); - for (const channel of channels) { - if (channel.type === "discord") { - // parse config and send via Discord sender directly - try { - let parsed: Record; - try { - parsed = JSON.parse(channel.config) as Record; - } catch { - statsLogger.warn("Failed to parse discord channel config", { - operation: "discord_config_parse_error", - channelId: channel.id, - }); - continue; - } - sendDiscord(parsed as any, payload).catch((err) => { - statsLogger.warn("Failed to send discord notification", { - operation: "discord_notification_error", - channelId: channel.id, - error: err instanceof Error ? err.message : String(err), - }); - }); - } catch (err) { - statsLogger.warn("Failed to send discord notification", { - operation: "discord_notification_error", - channelId: channel.id, - error: err instanceof Error ? err.message : String(err), - }); - } - } else { - sendNotification(channel, payload).catch((err) => { - statsLogger.warn("Failed to send notification", { - operation: "notification_delivery_error", - channelId: channel.id, - error: err instanceof Error ? err.message : String(err), - }); - }); - } - } - } - - private async isCoolingDown( - ruleId: number, - hostId: number, - ): Promise { - const key = `${ruleId}:${hostId}`; - const lastFired = this.cooldownMap.get(key); - if (!lastFired) return false; - const rule = await this.loadRuleById(ruleId); - const cooldownMs = (rule?.cooldownMinutes ?? 15) * 60 * 1000; - return Date.now() - lastFired < cooldownMs; - } - - private markCooldown(ruleId: number, hostId: number): void { - this.cooldownMap.set(`${ruleId}:${hostId}`, Date.now()); - } - - private async loadRulesForHost(hostId: number): Promise { - try { - return (await createCurrentAlertRepository().listEnabledRulesForHost( - hostId, - )) as AlertRule[]; - } catch { - return []; - } - } - - private async loadRulesForHostUser( - hostId: number, - userId: string, - ): Promise { - try { - return (await createCurrentAlertRepository().listEnabledRulesForHostUser( - hostId, - userId, - )) as AlertRule[]; - } catch { - return []; - } - } - - private async loadRuleById(ruleId: number): Promise { - try { - return (await createCurrentAlertRepository().findRuleById( - ruleId, - )) as AlertRule | null; - } catch { - return null; - } - } - - private async loadChannelsForRule( - ruleId: number, - ): Promise { - try { - return await createCurrentAlertRepository().listEnabledChannelsForRule( - ruleId, - ); - } catch { - return []; - } - } - - private async getHostName(hostId: number): Promise { - try { - return ( - (await createCurrentAlertRepository().getHostDisplayName(hostId)) ?? - `Host #${hostId}` - ); - } catch { - return `Host #${hostId}`; - } - } -} diff --git a/plugins/host-metrics/backend/managers/health.ts b/plugins/host-metrics/backend/managers/health.ts index f72612dcc..a1e19efd7 100644 --- a/plugins/host-metrics/backend/managers/health.ts +++ b/plugins/host-metrics/backend/managers/health.ts @@ -7,7 +7,6 @@ import { managerHandler, ManagerInputError } from "./route-helpers.js"; import { shellSingleQuote } from "../../../../src/backend/hosts/metrics-shared/exec-elevated.js"; import { isValidPort } from "../../../../src/backend/hosts/metrics-shared/validation.js"; import type { ManagerRoutesDeps } from "./types.js"; -import { AlertEngine } from "../alert-engine.js"; import { notifyAutomationHealthCheck } from "../automation-bridge.js"; export interface HealthCheck { @@ -157,15 +156,6 @@ export function registerHealthRoutes( if (results.length) { await recordHistory(userId, host.id, results); for (const r of results) { - AlertEngine.getInstance() - .evaluateHealthCheck( - host.id, - userId, - r.checkId, - r.ok, - r.detail ?? undefined, - ) - .catch(() => {}); notifyAutomationHealthCheck( host.id, userId, @@ -243,15 +233,6 @@ export function registerHealthRoutes( if (results.length) { await recordHistory(userId, host.id, results); for (const r of results) { - AlertEngine.getInstance() - .evaluateHealthCheck( - host.id, - userId, - r.checkId, - r.ok, - r.detail ?? undefined, - ) - .catch(() => {}); notifyAutomationHealthCheck( host.id, userId, diff --git a/plugins/host-metrics/backend/routes.ts b/plugins/host-metrics/backend/routes.ts index 91798f32a..298d1f6d1 100644 --- a/plugins/host-metrics/backend/routes.ts +++ b/plugins/host-metrics/backend/routes.ts @@ -69,7 +69,6 @@ import { registerProxmoxStatsHistoryRoutes } from "../../../src/backend/hosts/me import { ProxmoxPollingManager } from "../../../src/backend/hosts/metrics/proxmox-stats-polling.js"; import type { HostSessionStatusPayload } from "../../../src/backend/hosts/host-session-status.js"; import { pluginEvents, TOPICS } from "../../../src/backend/plugins/events.js"; -import { AlertEngine } from "./alert-engine.js"; import { notifyAutomationMetrics, notifyAutomationStatus, @@ -662,9 +661,6 @@ class PollingManager { this.scheduleInitialMetricsPoll(config.host, config.viewerUserId); } } - AlertEngine.getInstance() - .evaluateStatus(refreshedHost.id, isOnline) - .catch(() => {}); notifyAutomationStatus(refreshedHost.id, refreshedHost.userId, isOnline); } catch { const statusEntry: StatusEntry = { @@ -672,9 +668,6 @@ class PollingManager { lastChecked: new Date().toISOString(), }; this.statusStore.set(refreshedHost.id, statusEntry); - AlertEngine.getInstance() - .evaluateStatus(refreshedHost.id, false) - .catch(() => {}); notifyAutomationStatus(refreshedHost.id, refreshedHost.userId, false); } } @@ -730,9 +723,6 @@ class PollingManager { timestamp: Date.now(), }); await this.insertMetricsHistory(refreshedHost.id, metrics); - AlertEngine.getInstance() - .evaluateMetrics(refreshedHost.id, metrics) - .catch(() => {}); notifyAutomationMetrics(refreshedHost.id, refreshedHost.userId, metrics); pollingBackoff.reset(refreshedHost.id); authFailureTracker.reset(refreshedHost.id); @@ -1124,9 +1114,6 @@ app.post("/internal/login-alert", async (req, res) => { sshUser, fromIp, }); - AlertEngine.getInstance() - .evaluateUserLogin(hostId, userId, sshUser, fromIp) - .catch(() => {}); res.json({ ok: true }); }); diff --git a/src/backend/database/database.ts b/src/backend/database/database.ts index 6354d3f1b..7ddbacbdd 100644 --- a/src/backend/database/database.ts +++ b/src/backend/database/database.ts @@ -31,7 +31,7 @@ import { registerAuditLogRoutes } from "./routes/audit-log-routes.js"; import { registerTailscaleRoutes } from "./routes/tailscale-routes.js"; import vaultRoutes from "./routes/vault.js"; import secretSourceRoutes from "./routes/secret-sources.js"; -import alertRulesRoutes from "./routes/alert-rules-routes.js"; +import notificationChannelsRoutes from "./routes/notification-channels-routes.js"; import aiDispatch from "./routes/ai-dispatch.js"; import automationsDispatch from "./routes/automation-dispatch.js"; import syncRoutes from "./routes/sync.js"; @@ -1774,11 +1774,9 @@ registerAuditLogRoutes(app, authenticateJWT); registerTailscaleRoutes(app, authenticateJWT); app.use("/vault", vaultRoutes); app.use("/secret-sources", secretSourceRoutes); -// Before the alert routes, which are mounted at the root and would otherwise -// have first claim on the path. app.use("/automations", automationsDispatch); app.use("/ai", aiDispatch); -app.use("/", alertRulesRoutes); +app.use("/", notificationChannelsRoutes); app.use("/sync", syncRoutes); app.use("/plugins", pluginRoutes); app.use("/plugin-api", authenticateJWT, pluginApiRoutes); diff --git a/src/backend/database/db/performance-indexes.ts b/src/backend/database/db/performance-indexes.ts index 2e1ca83a8..6223e79a9 100644 --- a/src/backend/database/db/performance-indexes.ts +++ b/src/backend/database/db/performance-indexes.ts @@ -207,18 +207,6 @@ export const PERFORMANCE_INDEXES: PerformanceIndex[] = [ columns: "user_id", }, - // Alerting. - { - name: "idx_alert_firings_rule", - table: "alert_firings", - columns: "rule_id, fired_at", - }, - { - name: "idx_alert_firings_host", - table: "alert_firings", - columns: "host_id", - }, - // Automations. { name: "idx_automations_user", diff --git a/src/backend/database/db/schema.mysql.ts b/src/backend/database/db/schema.mysql.ts index ae147fe7a..026496fb0 100644 --- a/src/backend/database/db/schema.mysql.ts +++ b/src/backend/database/db/schema.mysql.ts @@ -1440,26 +1440,6 @@ export const proxmoxNodeHistory = mysqlTable("proxmox_node_history", { // --- proxmox-node-history end --- // --- alerts begin --- -export const alertRules = mysqlTable("alert_rules", { - id: int("id").autoincrement().primaryKey(), - userId: varchar("user_id", { length: 255 }) - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - hostId: int("host_id").references(() => hosts.id, { onDelete: "cascade" }), - name: varchar("name", { length: 255 }).notNull(), - enabled: boolean("enabled").notNull().default(true), - triggerType: text("trigger_type").notNull(), - thresholdValue: double("threshold_value"), - thresholdDurationSeconds: int("threshold_duration_seconds"), - cooldownMinutes: int("cooldown_minutes").notNull().default(15), - createdAt: varchar("created_at", { length: 255 }) - .notNull() - .default(sql`(CURRENT_TIMESTAMP)`), - updatedAt: varchar("updated_at", { length: 255 }) - .notNull() - .default(sql`(CURRENT_TIMESTAMP)`), -}); - export const notificationChannels = mysqlTable("notification_channels", { id: int("id").autoincrement().primaryKey(), userId: varchar("user_id", { length: 255 }) @@ -1473,46 +1453,6 @@ export const notificationChannels = mysqlTable("notification_channels", { .notNull() .default(sql`(CURRENT_TIMESTAMP)`), }); - -export const alertRuleChannels = mysqlTable("alert_rule_channels", { - id: int("id").autoincrement().primaryKey(), - ruleId: int("rule_id") - .notNull() - .references(() => alertRules.id, { onDelete: "cascade" }), - channelId: int("channel_id") - .notNull() - .references(() => notificationChannels.id, { onDelete: "cascade" }), -}); - -export const alertFirings = mysqlTable( - "alert_firings", - { - id: int("id").autoincrement().primaryKey(), - userId: varchar("user_id", { length: 255 }) - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - ruleId: int("rule_id") - .notNull() - .references(() => alertRules.id, { onDelete: "cascade" }), - hostId: int("host_id").notNull(), - hostName: text("host_name").notNull(), - firedAt: varchar("fired_at", { length: 255 }) - .notNull() - .default(sql`(CURRENT_TIMESTAMP)`), - resolvedAt: text("resolved_at"), - value: double("value"), - message: text("message").notNull(), - severity: text("severity").notNull().default("warning"), - acknowledged: boolean("acknowledged") - .notNull() - .default(false), - }, - // A rule's history is read newest-first; host_id is filtered on its own. - (table) => [ - index("idx_alert_firings_rule").on(table.ruleId, table.firedAt), - index("idx_alert_firings_host").on(table.hostId), - ], -); // --- alerts end --- // --- automations begin --- diff --git a/src/backend/database/db/schema.pg.ts b/src/backend/database/db/schema.pg.ts index 399d4cb87..bee20b628 100644 --- a/src/backend/database/db/schema.pg.ts +++ b/src/backend/database/db/schema.pg.ts @@ -1441,26 +1441,6 @@ export const proxmoxNodeHistory = pgTable("proxmox_node_history", { // --- proxmox-node-history end --- // --- alerts begin --- -export const alertRules = pgTable("alert_rules", { - id: serial("id").primaryKey(), - userId: varchar("user_id", { length: 255 }) - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - hostId: integer("host_id").references(() => hosts.id, { onDelete: "cascade" }), - name: varchar("name", { length: 255 }).notNull(), - enabled: boolean("enabled").notNull().default(true), - triggerType: text("trigger_type").notNull(), - thresholdValue: doublePrecision("threshold_value"), - thresholdDurationSeconds: integer("threshold_duration_seconds"), - cooldownMinutes: integer("cooldown_minutes").notNull().default(15), - createdAt: varchar("created_at", { length: 255 }) - .notNull() - .default(sql`CURRENT_TIMESTAMP`), - updatedAt: varchar("updated_at", { length: 255 }) - .notNull() - .default(sql`CURRENT_TIMESTAMP`), -}); - export const notificationChannels = pgTable("notification_channels", { id: serial("id").primaryKey(), userId: varchar("user_id", { length: 255 }) @@ -1474,46 +1454,6 @@ export const notificationChannels = pgTable("notification_channels", { .notNull() .default(sql`CURRENT_TIMESTAMP`), }); - -export const alertRuleChannels = pgTable("alert_rule_channels", { - id: serial("id").primaryKey(), - ruleId: integer("rule_id") - .notNull() - .references(() => alertRules.id, { onDelete: "cascade" }), - channelId: integer("channel_id") - .notNull() - .references(() => notificationChannels.id, { onDelete: "cascade" }), -}); - -export const alertFirings = pgTable( - "alert_firings", - { - id: serial("id").primaryKey(), - userId: varchar("user_id", { length: 255 }) - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - ruleId: integer("rule_id") - .notNull() - .references(() => alertRules.id, { onDelete: "cascade" }), - hostId: integer("host_id").notNull(), - hostName: text("host_name").notNull(), - firedAt: varchar("fired_at", { length: 255 }) - .notNull() - .default(sql`CURRENT_TIMESTAMP`), - resolvedAt: text("resolved_at"), - value: doublePrecision("value"), - message: text("message").notNull(), - severity: text("severity").notNull().default("warning"), - acknowledged: boolean("acknowledged") - .notNull() - .default(false), - }, - // A rule's history is read newest-first; host_id is filtered on its own. - (table) => [ - index("idx_alert_firings_rule").on(table.ruleId, table.firedAt), - index("idx_alert_firings_host").on(table.hostId), - ], -); // --- alerts end --- // --- automations begin --- diff --git a/src/backend/database/db/schema.ts b/src/backend/database/db/schema.ts index d60e255dd..de40eba61 100644 --- a/src/backend/database/db/schema.ts +++ b/src/backend/database/db/schema.ts @@ -1439,26 +1439,6 @@ export const proxmoxNodeHistory = sqliteTable("proxmox_node_history", { // --- proxmox-node-history end --- // --- alerts begin --- -export const alertRules = sqliteTable("alert_rules", { - id: integer("id").primaryKey({ autoIncrement: true }), - userId: text("user_id") - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - hostId: integer("host_id").references(() => hosts.id, { onDelete: "cascade" }), - name: text("name").notNull(), - enabled: integer("enabled", { mode: "boolean" }).notNull().default(true), - triggerType: text("trigger_type").notNull(), - thresholdValue: real("threshold_value"), - thresholdDurationSeconds: integer("threshold_duration_seconds"), - cooldownMinutes: integer("cooldown_minutes").notNull().default(15), - createdAt: text("created_at") - .notNull() - .default(sql`CURRENT_TIMESTAMP`), - updatedAt: text("updated_at") - .notNull() - .default(sql`CURRENT_TIMESTAMP`), -}); - export const notificationChannels = sqliteTable("notification_channels", { id: integer("id").primaryKey({ autoIncrement: true }), userId: text("user_id") @@ -1472,46 +1452,6 @@ export const notificationChannels = sqliteTable("notification_channels", { .notNull() .default(sql`CURRENT_TIMESTAMP`), }); - -export const alertRuleChannels = sqliteTable("alert_rule_channels", { - id: integer("id").primaryKey({ autoIncrement: true }), - ruleId: integer("rule_id") - .notNull() - .references(() => alertRules.id, { onDelete: "cascade" }), - channelId: integer("channel_id") - .notNull() - .references(() => notificationChannels.id, { onDelete: "cascade" }), -}); - -export const alertFirings = sqliteTable( - "alert_firings", - { - id: integer("id").primaryKey({ autoIncrement: true }), - userId: text("user_id") - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - ruleId: integer("rule_id") - .notNull() - .references(() => alertRules.id, { onDelete: "cascade" }), - hostId: integer("host_id").notNull(), - hostName: text("host_name").notNull(), - firedAt: text("fired_at") - .notNull() - .default(sql`CURRENT_TIMESTAMP`), - resolvedAt: text("resolved_at"), - value: real("value"), - message: text("message").notNull(), - severity: text("severity").notNull().default("warning"), - acknowledged: integer("acknowledged", { mode: "boolean" }) - .notNull() - .default(false), - }, - // A rule's history is read newest-first; host_id is filtered on its own. - (table) => [ - index("idx_alert_firings_rule").on(table.ruleId, table.firedAt), - index("idx_alert_firings_host").on(table.hostId), - ], -); // --- alerts end --- // --- automations begin --- diff --git a/src/backend/database/repositories/ai-repository.ts b/src/backend/database/repositories/ai-repository.ts index cf313f78b..f76b6a5d0 100644 --- a/src/backend/database/repositories/ai-repository.ts +++ b/src/backend/database/repositories/ai-repository.ts @@ -47,7 +47,7 @@ export class AiRepository { * Provider API keys are field-encrypted like any other credential. The key is * derived from the row id, which does not exist until after the insert, so a * new provider is written once and then re-encrypted in place with its real - * id -- the same approach AlertRepository uses for channel configs. + * id -- the same approach NotificationChannelRepository uses for channel configs. */ private userDataKey(userId: string): Buffer | null { try { diff --git a/src/backend/database/repositories/alert-repository.ts b/src/backend/database/repositories/alert-repository.ts deleted file mode 100644 index f3f845e31..000000000 --- a/src/backend/database/repositories/alert-repository.ts +++ /dev/null @@ -1,712 +0,0 @@ -import { and, count, desc, eq, inArray, isNull, lt, or } from "drizzle-orm"; -import { - alertFirings, - alertRuleChannels, - alertRules, - hosts, - notificationChannels, -} from "../db/schema.js"; -import { DataCrypto } from "../../utils/data-crypto.js"; -import type { DatabaseContext } from "./database-context.js"; -import { sqlTimestampDaysAgo } from "./sql-timestamp.js"; -import { rowsAffected } from "./mutation-result.js"; -import { insertReturning, updateReturning } from "./returning.js"; - -type AlertRuleRecord = typeof alertRules.$inferSelect; -type NotificationChannelRecord = typeof notificationChannels.$inferSelect; -type AlertFiringRecord = typeof alertFirings.$inferSelect; - -export interface NotificationChannelRow { - id: number; - user_id: string; - name: string; - type: string; - config: string; - enabled: number; - created_at: string; -} - -export interface AlertRuleRow { - id: number; - user_id: string; - host_id: number | null; - name: string; - enabled: number; - trigger_type: string; - threshold_value: number | null; - threshold_duration_seconds: number | null; - cooldown_minutes: number; - created_at: string; - updated_at: string; -} - -export interface AlertRuleWithChannelsRow extends AlertRuleRow { - channels: number[]; -} - -export interface AlertFiringRow { - id: number; - user_id: string; - rule_id: number; - host_id: number; - host_name: string; - fired_at: string; - resolved_at: string | null; - value: number | null; - message: string; - severity: string; - acknowledged: number; - rule_name: string | null; -} - -export interface AlertEngineRule { - id: number; - userId: string; - hostId: number | null; - name: string; - enabled: boolean; - triggerType: string; - thresholdValue: number | null; - thresholdDurationSeconds: number | null; - cooldownMinutes: number; -} - -export interface AlertEngineChannel { - id: number; - type: string; - config: string; - enabled: boolean; -} - -export class AlertRepository { - constructor( - private readonly context: DatabaseContext, - private readonly onWrite?: () => void | Promise, - ) {} - - /** - * Channel configs carry ntfy tokens and webhook auth headers, so they are - * field-encrypted like any other secret. The key is derived from the row id, - * which does not exist until after the insert, so a new channel is written - * once and then re-encrypted in place with its real id. - */ - private userDataKey(userId: string): Buffer | null { - try { - return DataCrypto.getUserDataKey(userId); - } catch { - // Crypto is not initialized (tests, early boot); leave the value as is. - return null; - } - } - - private encryptConfig( - config: string, - userId: string, - recordId: number | string, - ): string { - const userDataKey = this.userDataKey(userId); - if (!userDataKey) return config; - return DataCrypto.encryptRecord( - "notification_channels", - { id: recordId, config }, - userId, - userDataKey, - ).config; - } - - private decryptConfig( - config: string, - userId: string, - recordId: number | string, - ): string { - const userDataKey = this.userDataKey(userId); - if (!userDataKey) return config; - try { - return DataCrypto.decryptRecord( - "notification_channels", - { id: recordId, config }, - userId, - userDataKey, - ).config; - } catch { - // Rows written before channel configs were encrypted are still plaintext. - return config; - } - } - - async listNotificationChannels( - userId: string, - ): Promise { - const rows = await this.context.drizzle - .select() - .from(notificationChannels) - .where(eq(notificationChannels.userId, userId)) - .orderBy(notificationChannels.id); - - return rows.map((row) => { - const mapped = mapChannelRow(row); - mapped.config = this.decryptConfig(mapped.config, userId, mapped.id); - return mapped; - }); - } - - async findNotificationChannelForUser( - id: number, - userId: string, - ): Promise { - const rows = await this.context.drizzle - .select() - .from(notificationChannels) - .where( - and( - eq(notificationChannels.id, id), - eq(notificationChannels.userId, userId), - ), - ) - .limit(1); - - if (!rows[0]) return null; - const mapped = mapChannelRow(rows[0]); - mapped.config = this.decryptConfig(mapped.config, userId, mapped.id); - return mapped; - } - - async createNotificationChannel(input: { - userId: string; - name: string; - type: string; - config: string; - enabled: boolean; - }): Promise { - const [created] = await insertReturning( - this.context, - notificationChannels, - { - userId: input.userId, - name: input.name, - type: input.type, - config: input.config, - enabled: input.enabled, - }, - ); - - const encrypted = this.encryptConfig( - input.config, - input.userId, - created.id, - ); - if (encrypted !== input.config) { - await this.context.drizzle - .update(notificationChannels) - .set({ config: encrypted }) - .where(eq(notificationChannels.id, created.id)); - } - - await this.afterWrite(); - const mapped = mapChannelRow(created); - mapped.config = input.config; - return mapped; - } - - async updateNotificationChannel( - id: number, - userId: string, - input: { - name?: string; - type?: string; - config?: string; - enabled?: boolean; - }, - ): Promise { - if (Object.keys(input).length === 0) { - return this.findNotificationChannelForUser(id, userId); - } - - const values = - input.config !== undefined - ? { ...input, config: this.encryptConfig(input.config, userId, id) } - : input; - - const [updated] = await updateReturning( - this.context, - notificationChannels, - values, - and( - eq(notificationChannels.id, id), - eq(notificationChannels.userId, userId), - ), - ); - - if (!updated) return null; - await this.afterWrite(); - const mapped = mapChannelRow(updated); - mapped.config = this.decryptConfig(mapped.config, userId, mapped.id); - return mapped; - } - - async deleteNotificationChannel( - id: number, - userId: string, - ): Promise { - const result = await this.context.drizzle - .delete(notificationChannels) - .where( - and( - eq(notificationChannels.id, id), - eq(notificationChannels.userId, userId), - ), - ); - - if (rowsAffected(result) === 0) return false; - await this.afterWrite(); - return true; - } - - async listAlertRules(userId: string): Promise { - const rules = await this.context.drizzle - .select() - .from(alertRules) - .where(eq(alertRules.userId, userId)) - .orderBy(alertRules.id); - - const result: AlertRuleWithChannelsRow[] = []; - for (const rule of rules) { - result.push({ - ...mapRuleRow(rule), - channels: await this.listChannelIdsForRule(rule.id), - }); - } - return result; - } - - async createAlertRule(input: { - userId: string; - hostId: number | null; - name: string; - enabled: boolean; - triggerType: string; - thresholdValue: number | null; - thresholdDurationSeconds: number | null; - cooldownMinutes: number; - channels: number[]; - now: string; - }): Promise { - const [created] = await insertReturning(this.context, alertRules, { - userId: input.userId, - hostId: input.hostId, - name: input.name, - enabled: input.enabled, - triggerType: input.triggerType, - thresholdValue: input.thresholdValue, - thresholdDurationSeconds: input.thresholdDurationSeconds, - cooldownMinutes: input.cooldownMinutes, - createdAt: input.now, - updatedAt: input.now, - }); - - const channels = await this.replaceRuleChannels( - created.id, - input.userId, - input.channels, - ); - await this.afterWrite(); - return { ...mapRuleRow(created), channels }; - } - - async findAlertRuleForUser( - id: number, - userId: string, - ): Promise { - const rows = await this.context.drizzle - .select() - .from(alertRules) - .where(and(eq(alertRules.id, id), eq(alertRules.userId, userId))) - .limit(1); - - return rows[0] ? mapRuleRow(rows[0]) : null; - } - - async updateAlertRule( - id: number, - userId: string, - input: { - name?: string; - hostId?: number | null; - enabled?: boolean; - triggerType?: string; - thresholdValue?: number | null; - thresholdDurationSeconds?: number | null; - cooldownMinutes?: number; - channels?: number[]; - now: string; - }, - ): Promise { - const [updated] = await updateReturning( - this.context, - alertRules, - { - ...(input.name !== undefined ? { name: input.name } : {}), - ...(input.hostId !== undefined ? { hostId: input.hostId } : {}), - ...(input.enabled !== undefined ? { enabled: input.enabled } : {}), - ...(input.triggerType !== undefined - ? { triggerType: input.triggerType } - : {}), - ...(input.thresholdValue !== undefined - ? { thresholdValue: input.thresholdValue } - : {}), - ...(input.thresholdDurationSeconds !== undefined - ? { thresholdDurationSeconds: input.thresholdDurationSeconds } - : {}), - ...(input.cooldownMinutes !== undefined - ? { cooldownMinutes: input.cooldownMinutes } - : {}), - updatedAt: input.now, - }, - and(eq(alertRules.id, id), eq(alertRules.userId, userId)), - ); - - if (!updated) return null; - - const channels = - input.channels === undefined - ? await this.listChannelIdsForRule(id) - : await this.replaceRuleChannels(id, userId, input.channels); - - await this.afterWrite(); - return { ...mapRuleRow(updated), channels }; - } - - async deleteAlertRule(id: number, userId: string): Promise { - const result = await this.context.drizzle - .delete(alertRules) - .where(and(eq(alertRules.id, id), eq(alertRules.userId, userId))); - - if (rowsAffected(result) === 0) return false; - await this.afterWrite(); - return true; - } - - async listAlertFirings(input: { - userId: string; - acknowledged?: boolean; - limit: number; - offset: number; - }): Promise<{ firings: AlertFiringRow[]; total: number }> { - const filters = [eq(alertFirings.userId, input.userId)]; - if (input.acknowledged !== undefined) { - filters.push(eq(alertFirings.acknowledged, input.acknowledged)); - } - - const where = and(...filters); - const rows = await this.context.drizzle - .select({ - firing: alertFirings, - ruleName: alertRules.name, - }) - .from(alertFirings) - .leftJoin(alertRules, eq(alertRules.id, alertFirings.ruleId)) - .where(where) - .orderBy(desc(alertFirings.firedAt)) - .limit(input.limit) - .offset(input.offset); - - const totalRows = await this.context.drizzle - .select({ total: count() }) - .from(alertFirings) - .where(where); - - return { - firings: rows.map((row) => mapFiringRow(row.firing, row.ruleName)), - total: totalRows[0]?.total ?? 0, - }; - } - - async acknowledgeFiring(id: number, userId: string): Promise { - await this.context.drizzle - .update(alertFirings) - .set({ acknowledged: true }) - .where(and(eq(alertFirings.id, id), eq(alertFirings.userId, userId))); - await this.afterWrite(); - } - - async acknowledgeAllFirings(userId: string): Promise { - await this.context.drizzle - .update(alertFirings) - .set({ acknowledged: true }) - .where(eq(alertFirings.userId, userId)); - await this.afterWrite(); - } - - // A rule with host_id IS NULL means "all my hosts", not "all hosts on the - // server". Without joining the host back to its owner, every user's wildcard - // rule fired for every polled host and leaked other users' host names into - // their alerts. - async listEnabledRulesForHost(hostId: number): Promise { - const rows = await this.context.drizzle - .select({ rule: alertRules }) - .from(alertRules) - .innerJoin(hosts, eq(hosts.id, hostId)) - .where( - and( - eq(alertRules.enabled, true), - or( - eq(alertRules.hostId, hostId), - and(isNull(alertRules.hostId), eq(alertRules.userId, hosts.userId)), - ), - ), - ); - return rows.map((row) => mapEngineRule(row.rule)); - } - - async listEnabledRulesForHostUser( - hostId: number, - userId: string, - ): Promise { - const rows = await this.context.drizzle - .select() - .from(alertRules) - .where( - and( - eq(alertRules.enabled, true), - eq(alertRules.userId, userId), - or(eq(alertRules.hostId, hostId), isNull(alertRules.hostId)), - ), - ); - return rows.map(mapEngineRule); - } - - async findRuleById(id: number): Promise { - const rows = await this.context.drizzle - .select() - .from(alertRules) - .where(eq(alertRules.id, id)) - .limit(1); - return rows[0] ? mapEngineRule(rows[0]) : null; - } - - async createFiring(input: { - userId: string; - ruleId: number; - hostId: number; - hostName: string; - value: number | null; - message: string; - severity: string; - }): Promise { - await this.context.drizzle.insert(alertFirings).values(input); - await this.afterWrite(); - } - - async pruneFiringsOlderThan(userId: string, days: number): Promise { - await this.context.drizzle - .delete(alertFirings) - .where( - and( - eq(alertFirings.userId, userId), - lt(alertFirings.firedAt, sqlTimestampDaysAgo(days)), - ), - ); - } - - async deleteByUserId(userId: string): Promise<{ - firingsDeleted: number; - ruleLinksDeleted: number; - rulesDeleted: number; - channelsDeleted: number; - }> { - const ruleIds = ( - await this.context.drizzle - .select({ id: alertRules.id }) - .from(alertRules) - .where(eq(alertRules.userId, userId)) - ).map((row) => row.id); - const channelIds = ( - await this.context.drizzle - .select({ id: notificationChannels.id }) - .from(notificationChannels) - .where(eq(notificationChannels.userId, userId)) - ).map((row) => row.id); - - const firingResult = await this.context.drizzle - .delete(alertFirings) - .where(eq(alertFirings.userId, userId)); - - const linkFilters = [ - ...(ruleIds.length > 0 - ? [inArray(alertRuleChannels.ruleId, ruleIds)] - : []), - ...(channelIds.length > 0 - ? [inArray(alertRuleChannels.channelId, channelIds)] - : []), - ]; - const linkResult = - linkFilters.length === 0 - ? null - : await this.context.drizzle - .delete(alertRuleChannels) - .where(or(...linkFilters)); - - const ruleResult = await this.context.drizzle - .delete(alertRules) - .where(eq(alertRules.userId, userId)); - const result = await this.context.drizzle - .delete(notificationChannels) - .where(eq(notificationChannels.userId, userId)); - - if ( - rowsAffected(firingResult) > 0 || - rowsAffected(linkResult) > 0 || - rowsAffected(ruleResult) > 0 || - rowsAffected(result) > 0 - ) { - await this.afterWrite(); - } - - return { - firingsDeleted: rowsAffected(firingResult), - ruleLinksDeleted: rowsAffected(linkResult), - rulesDeleted: rowsAffected(ruleResult), - channelsDeleted: rowsAffected(result), - }; - } - - async listEnabledChannelsForRule( - ruleId: number, - ): Promise { - const rows = await this.context.drizzle - .select({ - id: notificationChannels.id, - userId: notificationChannels.userId, - type: notificationChannels.type, - config: notificationChannels.config, - enabled: notificationChannels.enabled, - }) - .from(notificationChannels) - .innerJoin( - alertRuleChannels, - eq(alertRuleChannels.channelId, notificationChannels.id), - ) - .where( - and( - eq(alertRuleChannels.ruleId, ruleId), - eq(notificationChannels.enabled, true), - ), - ); - - // The engine sends without a user in scope, so decrypt against the owner. - return rows.map(({ userId, ...channel }) => ({ - ...channel, - config: this.decryptConfig(channel.config, userId, channel.id), - })); - } - - async getHostDisplayName(hostId: number): Promise { - const rows = await this.context.drizzle - .select({ name: hosts.name, ip: hosts.ip }) - .from(hosts) - .where(eq(hosts.id, hostId)) - .limit(1); - - const row = rows[0]; - return row ? row.name || row.ip : null; - } - - private async replaceRuleChannels( - ruleId: number, - userId: string, - channelIds: number[], - ): Promise { - await this.context.drizzle - .delete(alertRuleChannels) - .where(eq(alertRuleChannels.ruleId, ruleId)); - - const linked: number[] = []; - for (const channelId of channelIds) { - const channel = await this.findNotificationChannelForUser( - channelId, - userId, - ); - if (!channel) continue; - await this.context.drizzle - .insert(alertRuleChannels) - .values({ ruleId, channelId }); - linked.push(channelId); - } - return linked; - } - - private async listChannelIdsForRule(ruleId: number): Promise { - const rows = await this.context.drizzle - .select({ channelId: alertRuleChannels.channelId }) - .from(alertRuleChannels) - .where(eq(alertRuleChannels.ruleId, ruleId)); - - return rows.map((row) => row.channelId); - } - - private async afterWrite(): Promise { - await this.onWrite?.(); - } -} - -function mapChannelRow(row: NotificationChannelRecord): NotificationChannelRow { - return { - id: row.id, - user_id: row.userId, - name: row.name, - type: row.type, - config: row.config, - enabled: row.enabled ? 1 : 0, - created_at: row.createdAt, - }; -} - -function mapRuleRow(row: AlertRuleRecord): AlertRuleRow { - return { - id: row.id, - user_id: row.userId, - host_id: row.hostId, - name: row.name, - enabled: row.enabled ? 1 : 0, - trigger_type: row.triggerType, - threshold_value: row.thresholdValue, - threshold_duration_seconds: row.thresholdDurationSeconds, - cooldown_minutes: row.cooldownMinutes, - created_at: row.createdAt, - updated_at: row.updatedAt, - }; -} - -function mapFiringRow( - row: AlertFiringRecord, - ruleName: string | null, -): AlertFiringRow { - return { - id: row.id, - user_id: row.userId, - rule_id: row.ruleId, - host_id: row.hostId, - host_name: row.hostName, - fired_at: row.firedAt, - resolved_at: row.resolvedAt, - value: row.value, - message: row.message, - severity: row.severity, - acknowledged: row.acknowledged ? 1 : 0, - rule_name: ruleName, - }; -} - -function mapEngineRule(row: AlertRuleRecord): AlertEngineRule { - return { - id: row.id, - userId: row.userId, - hostId: row.hostId, - name: row.name, - enabled: row.enabled, - triggerType: row.triggerType, - thresholdValue: row.thresholdValue, - thresholdDurationSeconds: row.thresholdDurationSeconds, - cooldownMinutes: row.cooldownMinutes, - }; -} diff --git a/src/backend/database/repositories/factory.ts b/src/backend/database/repositories/factory.ts index 2a8f93fe8..c715657c4 100644 --- a/src/backend/database/repositories/factory.ts +++ b/src/backend/database/repositories/factory.ts @@ -5,7 +5,7 @@ import { primeSettingsCache, readCachedSetting } from "./settings-cache.js"; import type { DatabaseContext } from "./database-context.js"; import { WebauthnCredentialRepository } from "./webauthn-credential-repository.js"; import { AiRepository } from "./ai-repository.js"; -import { AlertRepository } from "./alert-repository.js"; +import { NotificationChannelRepository } from "./notification-channel-repository.js"; import { AutomationRepository } from "./automation-repository.js"; import { ApiKeyRepository } from "./api-key-repository.js"; import { AuditLogRepository } from "./audit-log-repository.js"; @@ -161,10 +161,10 @@ export function createCurrentAiRepository(): AiRepository { ); } -export function createCurrentAlertRepository(): AlertRepository { - return new AlertRepository( +export function createCurrentNotificationChannelRepository(): NotificationChannelRepository { + return new NotificationChannelRepository( createCurrentRepositoryContext(), - createCurrentRepositoryWriteHook("alert_repository_write"), + createCurrentRepositoryWriteHook("notification_channel_repository_write"), ); } diff --git a/src/backend/database/repositories/notification-channel-repository.ts b/src/backend/database/repositories/notification-channel-repository.ts new file mode 100644 index 000000000..af2d24e5d --- /dev/null +++ b/src/backend/database/repositories/notification-channel-repository.ts @@ -0,0 +1,231 @@ +import { and, eq } from "drizzle-orm"; +import { notificationChannels } from "../db/schema.js"; +import { DataCrypto } from "../../utils/data-crypto.js"; +import type { DatabaseContext } from "./database-context.js"; +import { rowsAffected } from "./mutation-result.js"; +import { insertReturning, updateReturning } from "./returning.js"; + +type NotificationChannelRecord = typeof notificationChannels.$inferSelect; + +export interface NotificationChannelRow { + id: number; + user_id: string; + name: string; + type: string; + config: string; + enabled: number; + created_at: string; +} + +export class NotificationChannelRepository { + constructor( + private readonly context: DatabaseContext, + private readonly onWrite?: () => void | Promise, + ) {} + + /** + * Channel configs carry ntfy tokens and webhook auth headers, so they are + * field-encrypted like any other secret. The key is derived from the row id, + * which does not exist until after the insert, so a new channel is written + * once and then re-encrypted in place with its real id. + */ + private userDataKey(userId: string): Buffer | null { + try { + return DataCrypto.getUserDataKey(userId); + } catch { + // Crypto is not initialized (tests, early boot); leave the value as is. + return null; + } + } + + private encryptConfig( + config: string, + userId: string, + recordId: number | string, + ): string { + const userDataKey = this.userDataKey(userId); + if (!userDataKey) return config; + return DataCrypto.encryptRecord( + "notification_channels", + { id: recordId, config }, + userId, + userDataKey, + ).config; + } + + private decryptConfig( + config: string, + userId: string, + recordId: number | string, + ): string { + const userDataKey = this.userDataKey(userId); + if (!userDataKey) return config; + try { + return DataCrypto.decryptRecord( + "notification_channels", + { id: recordId, config }, + userId, + userDataKey, + ).config; + } catch { + // Rows written before channel configs were encrypted are still plaintext. + return config; + } + } + + async listNotificationChannels( + userId: string, + ): Promise { + const rows = await this.context.drizzle + .select() + .from(notificationChannels) + .where(eq(notificationChannels.userId, userId)) + .orderBy(notificationChannels.id); + + return rows.map((row) => { + const mapped = mapChannelRow(row); + mapped.config = this.decryptConfig(mapped.config, userId, mapped.id); + return mapped; + }); + } + + async findNotificationChannelForUser( + id: number, + userId: string, + ): Promise { + const rows = await this.context.drizzle + .select() + .from(notificationChannels) + .where( + and( + eq(notificationChannels.id, id), + eq(notificationChannels.userId, userId), + ), + ) + .limit(1); + + if (!rows[0]) return null; + const mapped = mapChannelRow(rows[0]); + mapped.config = this.decryptConfig(mapped.config, userId, mapped.id); + return mapped; + } + + async createNotificationChannel(input: { + userId: string; + name: string; + type: string; + config: string; + enabled: boolean; + }): Promise { + const [created] = await insertReturning( + this.context, + notificationChannels, + { + userId: input.userId, + name: input.name, + type: input.type, + config: input.config, + enabled: input.enabled, + }, + ); + + const encrypted = this.encryptConfig( + input.config, + input.userId, + created.id, + ); + if (encrypted !== input.config) { + await this.context.drizzle + .update(notificationChannels) + .set({ config: encrypted }) + .where(eq(notificationChannels.id, created.id)); + } + + await this.afterWrite(); + const mapped = mapChannelRow(created); + mapped.config = input.config; + return mapped; + } + + async updateNotificationChannel( + id: number, + userId: string, + input: { + name?: string; + type?: string; + config?: string; + enabled?: boolean; + }, + ): Promise { + if (Object.keys(input).length === 0) { + return this.findNotificationChannelForUser(id, userId); + } + + const values = + input.config !== undefined + ? { ...input, config: this.encryptConfig(input.config, userId, id) } + : input; + + const [updated] = await updateReturning( + this.context, + notificationChannels, + values, + and( + eq(notificationChannels.id, id), + eq(notificationChannels.userId, userId), + ), + ); + + if (!updated) return null; + await this.afterWrite(); + const mapped = mapChannelRow(updated); + mapped.config = this.decryptConfig(mapped.config, userId, mapped.id); + return mapped; + } + + async deleteNotificationChannel( + id: number, + userId: string, + ): Promise { + const result = await this.context.drizzle + .delete(notificationChannels) + .where( + and( + eq(notificationChannels.id, id), + eq(notificationChannels.userId, userId), + ), + ); + + if (rowsAffected(result) === 0) return false; + await this.afterWrite(); + return true; + } + + async deleteByUserId(userId: string): Promise<{ channelsDeleted: number }> { + const result = await this.context.drizzle + .delete(notificationChannels) + .where(eq(notificationChannels.userId, userId)); + + if (rowsAffected(result) > 0) { + await this.afterWrite(); + } + + return { channelsDeleted: rowsAffected(result) }; + } + + private async afterWrite(): Promise { + await this.onWrite?.(); + } +} + +function mapChannelRow(row: NotificationChannelRecord): NotificationChannelRow { + return { + id: row.id, + user_id: row.userId, + name: row.name, + type: row.type, + config: row.config, + enabled: row.enabled ? 1 : 0, + created_at: row.createdAt, + }; +} diff --git a/src/backend/database/routes/alert-rules-routes.ts b/src/backend/database/routes/alert-rules-routes.ts deleted file mode 100644 index 6bfdbba4f..000000000 --- a/src/backend/database/routes/alert-rules-routes.ts +++ /dev/null @@ -1,534 +0,0 @@ -import express, { type Request, type Response } from "express"; -import type { AuthenticatedRequest } from "../../../types/index.js"; -import { createCurrentAlertRepository } from "../repositories/factory.js"; -import { AuthManager } from "../../utils/auth-manager.js"; -import { databaseLogger } from "../../utils/logger.js"; -import { sendWebhook, sendNtfy } from "../../utils/notification-sender.js"; -import { sendDiscord } from "../../utils/discord-sender.js"; - -const router = express.Router(); -const authManager = AuthManager.getInstance(); -const authenticateJWT = authManager.createAuthMiddleware(); - -const VALID_TRIGGER_TYPES = new Set([ - "host_offline", - "host_online", - "cpu_threshold", - "memory_threshold", - "disk_threshold", - "health_check_failure", - "health_check_recovery", - "user_login", -]); - -router.use(authenticateJWT); - -// ---- Notification Channels ---- - -/** - * @openapi - * /notification-channels: - * get: - * summary: List notification channels for the current user - * tags: - * - Alerts - * responses: - * 200: - * description: List of notification channels. - */ -router.get("/notification-channels", async (req, res) => { - const userId = (req as AuthenticatedRequest).userId; - try { - const rows = - await createCurrentAlertRepository().listNotificationChannels(userId); - res.json(rows); - } catch (err) { - databaseLogger.error("Failed to list notification channels", { - operation: "list_channels", - error: err, - }); - res.status(500).json({ error: "Failed to list channels" }); - } -}); - -/** - * @openapi - * /notification-channels: - * post: - * summary: Create a notification channel - * tags: - * - Alerts - */ -router.post("/notification-channels", async (req, res) => { - const userId = (req as AuthenticatedRequest).userId; - const { name, type, config, enabled } = req.body as { - name: string; - type: string; - config: unknown; - enabled?: boolean; - }; - - if (!name || typeof name !== "string" || !name.trim()) { - return res.status(400).json({ error: "name is required" }); - } - if (type !== "webhook" && type !== "ntfy" && type !== "discord") { - return res - .status(400) - .json({ error: "type must be 'webhook', 'ntfy' or 'discord'" }); - } - if (!config || typeof config !== "object") { - return res.status(400).json({ error: "config is required" }); - } - if (type === "ntfy") { - const c = config as Record; - if (!c.url || typeof c.url !== "string") - return res.status(400).json({ error: "ntfy config requires url" }); - if (!c.topic || typeof c.topic !== "string") - return res.status(400).json({ error: "ntfy config requires topic" }); - } - if (type === "webhook") { - const c = config as Record; - if (!c.url || typeof c.url !== "string") - return res.status(400).json({ error: "webhook config requires url" }); - } - if (type === "discord") { - const c = config as Record; - if (!c.url || typeof c.url !== "string") - return res.status(400).json({ error: "discord config requires url" }); - if ( - !/^https:\/\/(?:canary\.|ptb\.)?(?:discord\.com|discordapp\.com)\/api\/webhooks\/.+/i.test( - c.url, - ) - ) { - return res.status(400).json({ - error: - "discord config requires a valid Discord webhook URL (https://discord.com/api/webhooks/...)", - }); - } - } - - try { - const row = await createCurrentAlertRepository().createNotificationChannel({ - userId, - name: name.trim(), - type, - config: JSON.stringify(config), - enabled: enabled !== false, - }); - res.status(201).json(row); - } catch (err) { - databaseLogger.error("Failed to create notification channel", { - operation: "create_channel", - error: err, - }); - res.status(500).json({ error: "Failed to create channel" }); - } -}); - -/** - * @openapi - * /notification-channels/{id}: - * put: - * summary: Update a notification channel - * tags: - * - Alerts - */ -router.put( - "/notification-channels/:id", - async (req: Request, res: Response) => { - const userId = (req as AuthenticatedRequest).userId; - const channelId = Number(req.params.id); - const { name, type, config, enabled } = req.body as { - name?: string; - type?: string; - config?: unknown; - enabled?: boolean; - }; - - const repository = createCurrentAlertRepository(); - const existing = await repository.findNotificationChannelForUser( - channelId, - userId, - ); - if (!existing) return res.status(404).json({ error: "Channel not found" }); - - if (type && type !== "webhook" && type !== "ntfy" && type !== "discord") { - return res - .status(400) - .json({ error: "type must be 'webhook', 'ntfy' or 'discord'" }); - } - if ( - name === undefined && - type === undefined && - config === undefined && - enabled === undefined - ) { - return res.json({ success: true }); - } - - try { - const row = await repository.updateNotificationChannel( - channelId, - userId, - { - ...(name !== undefined ? { name: name.trim() } : {}), - ...(type !== undefined ? { type } : {}), - ...(config !== undefined ? { config: JSON.stringify(config) } : {}), - ...(enabled !== undefined ? { enabled } : {}), - }, - ); - if (!row) return res.status(404).json({ error: "Channel not found" }); - res.json(row); - } catch (err) { - databaseLogger.error("Failed to update notification channel", { - operation: "update_channel", - error: err, - }); - res.status(500).json({ error: "Failed to update channel" }); - } - }, -); - -/** - * @openapi - * /notification-channels/{id}: - * delete: - * summary: Delete a notification channel - * tags: - * - Alerts - */ -router.delete( - "/notification-channels/:id", - async (req: Request, res: Response) => { - const userId = (req as AuthenticatedRequest).userId; - const channelId = Number(req.params.id); - const deleted = - await createCurrentAlertRepository().deleteNotificationChannel( - channelId, - userId, - ); - if (!deleted) return res.status(404).json({ error: "Channel not found" }); - res.json({ success: true }); - }, -); - -/** - * @openapi - * /notification-channels/{id}/test: - * post: - * summary: Send a test notification - * tags: - * - Alerts - */ -router.post( - "/notification-channels/:id/test", - async (req: Request, res: Response) => { - const userId = (req as AuthenticatedRequest).userId; - const channelId = Number(req.params.id); - const row = - await createCurrentAlertRepository().findNotificationChannelForUser( - channelId, - userId, - ); - if (!row) return res.status(404).json({ error: "Channel not found" }); - - const testPayload = { - hostName: "Test Host", - hostId: 0, - triggerType: "test", - message: "This is a test notification from Termix", - severity: "info" as const, - timestamp: new Date().toISOString(), - ruleId: 0, - ruleName: "Test", - }; - - try { - let config: Record; - try { - config = JSON.parse(row.config) as Record; - } catch { - return res - .status(400) - .json({ success: false, error: "Invalid channel config" }); - } - - if (row.type === "webhook") { - await sendWebhook( - config as unknown as Parameters[0], - testPayload, - ); - } else if (row.type === "ntfy") { - await sendNtfy( - config as unknown as Parameters[0], - testPayload, - ); - } else if (row.type === "discord") { - await sendDiscord( - config as unknown as Parameters[0], - testPayload, - ); - } - res.json({ success: true }); - } catch (err) { - res.json({ - success: false, - error: err instanceof Error ? err.message : String(err), - }); - } - }, -); - -// ---- Alert Rules ---- - -/** - * @openapi - * /alert-rules: - * get: - * summary: List alert rules for the current user - * tags: - * - Alerts - */ -router.get("/alert-rules", async (req, res) => { - const userId = (req as AuthenticatedRequest).userId; - try { - res.json(await createCurrentAlertRepository().listAlertRules(userId)); - } catch (err) { - databaseLogger.error("Failed to list alert rules", { - operation: "list_alert_rules", - error: err, - }); - res.status(500).json({ error: "Failed to list alert rules" }); - } -}); - -/** - * @openapi - * /alert-rules: - * post: - * summary: Create an alert rule - * tags: - * - Alerts - */ -router.post("/alert-rules", async (req, res) => { - const userId = (req as AuthenticatedRequest).userId; - const { - name, - hostId, - enabled, - triggerType, - thresholdValue, - thresholdDurationSeconds, - cooldownMinutes, - channels = [], - } = req.body as { - name: string; - hostId?: number | null; - enabled?: boolean; - triggerType: string; - thresholdValue?: number | null; - thresholdDurationSeconds?: number | null; - cooldownMinutes?: number; - channels?: number[]; - }; - - if (!name || typeof name !== "string" || !name.trim()) { - return res.status(400).json({ error: "name is required" }); - } - if (!VALID_TRIGGER_TYPES.has(triggerType)) { - return res.status(400).json({ error: "Invalid triggerType" }); - } - if (thresholdValue != null && (thresholdValue < 0 || thresholdValue > 100)) { - return res - .status(400) - .json({ error: "thresholdValue must be between 0 and 100" }); - } - if (thresholdDurationSeconds != null && thresholdDurationSeconds < 0) { - return res - .status(400) - .json({ error: "thresholdDurationSeconds must be >= 0" }); - } - - try { - const now = new Date().toISOString(); - const row = await createCurrentAlertRepository().createAlertRule({ - userId, - hostId: hostId ?? null, - name: name.trim(), - enabled: enabled !== false, - triggerType, - thresholdValue: thresholdValue ?? null, - thresholdDurationSeconds: thresholdDurationSeconds ?? null, - cooldownMinutes: cooldownMinutes ?? 15, - channels, - now, - }); - res.status(201).json({ ...row, channels }); - } catch (err) { - databaseLogger.error("Failed to create alert rule", { - operation: "create_alert_rule", - error: err, - }); - res.status(500).json({ error: "Failed to create alert rule" }); - } -}); - -/** - * @openapi - * /alert-rules/{id}: - * put: - * summary: Update an alert rule - * tags: - * - Alerts - */ -router.put("/alert-rules/:id", async (req: Request, res: Response) => { - const userId = (req as AuthenticatedRequest).userId; - const ruleId = Number(req.params.id); - - const repository = createCurrentAlertRepository(); - const existing = await repository.findAlertRuleForUser(ruleId, userId); - if (!existing) return res.status(404).json({ error: "Alert rule not found" }); - - const { - name, - hostId, - enabled, - triggerType, - thresholdValue, - thresholdDurationSeconds, - cooldownMinutes, - channels, - } = req.body as { - name?: string; - hostId?: number | null; - enabled?: boolean; - triggerType?: string; - thresholdValue?: number | null; - thresholdDurationSeconds?: number | null; - cooldownMinutes?: number; - channels?: number[]; - }; - - if (triggerType && !VALID_TRIGGER_TYPES.has(triggerType)) { - return res.status(400).json({ error: "Invalid triggerType" }); - } - - try { - const row = await repository.updateAlertRule(ruleId, userId, { - ...(name !== undefined ? { name: name.trim() } : {}), - ...(hostId !== undefined ? { hostId: hostId ?? null } : {}), - ...(enabled !== undefined ? { enabled } : {}), - ...(triggerType !== undefined ? { triggerType } : {}), - ...(thresholdValue !== undefined - ? { thresholdValue: thresholdValue ?? null } - : {}), - ...(thresholdDurationSeconds !== undefined - ? { thresholdDurationSeconds: thresholdDurationSeconds ?? null } - : {}), - ...(cooldownMinutes !== undefined ? { cooldownMinutes } : {}), - ...(channels !== undefined ? { channels } : {}), - now: new Date().toISOString(), - }); - if (!row) return res.status(404).json({ error: "Alert rule not found" }); - res.json(row); - } catch (err) { - databaseLogger.error("Failed to update alert rule", { - operation: "update_alert_rule", - error: err, - }); - res.status(500).json({ error: "Failed to update alert rule" }); - } -}); - -/** - * @openapi - * /alert-rules/{id}: - * delete: - * summary: Delete an alert rule - * tags: - * - Alerts - */ -router.delete("/alert-rules/:id", async (req: Request, res: Response) => { - const userId = (req as AuthenticatedRequest).userId; - const ruleId = Number(req.params.id); - const deleted = await createCurrentAlertRepository().deleteAlertRule( - ruleId, - userId, - ); - if (!deleted) return res.status(404).json({ error: "Alert rule not found" }); - res.json({ success: true }); -}); - -// ---- Alert Firings ---- - -/** - * @openapi - * /alert-firings: - * get: - * summary: List alert firings for the current user - * tags: - * - Alerts - */ -router.get("/alert-firings", async (req, res) => { - const userId = (req as AuthenticatedRequest).userId; - const limit = Math.min(Number(req.query.limit) || 50, 200); - const offset = Number(req.query.offset) || 0; - const acknowledgedParam = req.query.acknowledged; - - try { - const acknowledged = - acknowledgedParam === "true" - ? true - : acknowledgedParam === "false" - ? false - : undefined; - res.json( - await createCurrentAlertRepository().listAlertFirings({ - userId, - acknowledged, - limit, - offset, - }), - ); - } catch (err) { - databaseLogger.error("Failed to list alert firings", { - operation: "list_alert_firings", - error: err, - }); - res.status(500).json({ error: "Failed to list alert firings" }); - } -}); - -/** - * @openapi - * /alert-firings/{id}/acknowledge: - * post: - * summary: Acknowledge an alert firing - * tags: - * - Alerts - */ -router.post( - "/alert-firings/:id/acknowledge", - async (req: Request, res: Response) => { - const userId = (req as AuthenticatedRequest).userId; - const firingId = Number(req.params.id); - await createCurrentAlertRepository().acknowledgeFiring(firingId, userId); - res.json({ success: true }); - }, -); - -/** - * @openapi - * /alert-firings/acknowledge-all: - * post: - * summary: Acknowledge all alert firings for the current user - * tags: - * - Alerts - */ -router.post("/alert-firings/acknowledge-all", async (req, res) => { - const userId = (req as AuthenticatedRequest).userId; - await createCurrentAlertRepository().acknowledgeAllFirings(userId); - res.json({ success: true }); -}); - -export default router; diff --git a/src/backend/database/routes/delete-user-data.ts b/src/backend/database/routes/delete-user-data.ts index e92eadbba..3c23b3277 100644 --- a/src/backend/database/routes/delete-user-data.ts +++ b/src/backend/database/routes/delete-user-data.ts @@ -1,7 +1,7 @@ import { authLogger } from "../../utils/logger.js"; import { createCurrentAiRepository, - createCurrentAlertRepository, + createCurrentNotificationChannelRepository, createCurrentApiKeyRepository, createCurrentAuditLogRepository, createCurrentC2sTunnelPresetRepository, @@ -82,7 +82,7 @@ export async function deleteUserAndRelatedData( await createCurrentRoleRepository().removeAllRolesFromUser(userId); await createCurrentAiRepository().deleteByUserId(userId); - await createCurrentAlertRepository().deleteByUserId(userId); + await createCurrentNotificationChannelRepository().deleteByUserId(userId); await createCurrentAuditLogRepository().anonymizeByUserId(userId); await createCurrentSshCredentialUsageRepository().deleteByUserId(userId); diff --git a/src/backend/database/routes/notification-channels-routes.ts b/src/backend/database/routes/notification-channels-routes.ts new file mode 100644 index 000000000..1108d53a9 --- /dev/null +++ b/src/backend/database/routes/notification-channels-routes.ts @@ -0,0 +1,274 @@ +import express, { type Request, type Response } from "express"; +import type { AuthenticatedRequest } from "../../../types/index.js"; +import { createCurrentNotificationChannelRepository } from "../repositories/factory.js"; +import { AuthManager } from "../../utils/auth-manager.js"; +import { databaseLogger } from "../../utils/logger.js"; +import { sendWebhook, sendNtfy } from "../../utils/notification-sender.js"; +import { sendDiscord } from "../../utils/discord-sender.js"; + +const router = express.Router(); +const authManager = AuthManager.getInstance(); +const authenticateJWT = authManager.createAuthMiddleware(); + +router.use(authenticateJWT); + +/** + * @openapi + * /notification-channels: + * get: + * summary: List notification channels for the current user + * tags: + * - Notifications + * responses: + * 200: + * description: List of notification channels. + */ +router.get("/notification-channels", async (req, res) => { + const userId = (req as AuthenticatedRequest).userId; + try { + const rows = + await createCurrentNotificationChannelRepository().listNotificationChannels( + userId, + ); + res.json(rows); + } catch (err) { + databaseLogger.error("Failed to list notification channels", { + operation: "list_channels", + error: err, + }); + res.status(500).json({ error: "Failed to list channels" }); + } +}); + +/** + * @openapi + * /notification-channels: + * post: + * summary: Create a notification channel + * tags: + * - Notifications + */ +router.post("/notification-channels", async (req, res) => { + const userId = (req as AuthenticatedRequest).userId; + const { name, type, config, enabled } = req.body as { + name: string; + type: string; + config: unknown; + enabled?: boolean; + }; + + if (!name || typeof name !== "string" || !name.trim()) { + return res.status(400).json({ error: "name is required" }); + } + if (type !== "webhook" && type !== "ntfy" && type !== "discord") { + return res + .status(400) + .json({ error: "type must be 'webhook', 'ntfy' or 'discord'" }); + } + if (!config || typeof config !== "object") { + return res.status(400).json({ error: "config is required" }); + } + if (type === "ntfy") { + const c = config as Record; + if (!c.url || typeof c.url !== "string") + return res.status(400).json({ error: "ntfy config requires url" }); + if (!c.topic || typeof c.topic !== "string") + return res.status(400).json({ error: "ntfy config requires topic" }); + } + if (type === "webhook") { + const c = config as Record; + if (!c.url || typeof c.url !== "string") + return res.status(400).json({ error: "webhook config requires url" }); + } + if (type === "discord") { + const c = config as Record; + if (!c.url || typeof c.url !== "string") + return res.status(400).json({ error: "discord config requires url" }); + if ( + !/^https:\/\/(?:canary\.|ptb\.)?(?:discord\.com|discordapp\.com)\/api\/webhooks\/.+/i.test( + c.url, + ) + ) { + return res.status(400).json({ + error: + "discord config requires a valid Discord webhook URL (https://discord.com/api/webhooks/...)", + }); + } + } + + try { + const row = + await createCurrentNotificationChannelRepository().createNotificationChannel( + { + userId, + name: name.trim(), + type, + config: JSON.stringify(config), + enabled: enabled !== false, + }, + ); + res.status(201).json(row); + } catch (err) { + databaseLogger.error("Failed to create notification channel", { + operation: "create_channel", + error: err, + }); + res.status(500).json({ error: "Failed to create channel" }); + } +}); + +/** + * @openapi + * /notification-channels/{id}: + * put: + * summary: Update a notification channel + * tags: + * - Notifications + */ +router.put( + "/notification-channels/:id", + async (req: Request, res: Response) => { + const userId = (req as AuthenticatedRequest).userId; + const channelId = Number(req.params.id); + const { name, type, config, enabled } = req.body as { + name?: string; + type?: string; + config?: unknown; + enabled?: boolean; + }; + + const repository = createCurrentNotificationChannelRepository(); + const existing = await repository.findNotificationChannelForUser( + channelId, + userId, + ); + if (!existing) return res.status(404).json({ error: "Channel not found" }); + + if (type && type !== "webhook" && type !== "ntfy" && type !== "discord") { + return res + .status(400) + .json({ error: "type must be 'webhook', 'ntfy' or 'discord'" }); + } + if ( + name === undefined && + type === undefined && + config === undefined && + enabled === undefined + ) { + return res.json({ success: true }); + } + + try { + const row = await repository.updateNotificationChannel( + channelId, + userId, + { + ...(name !== undefined ? { name: name.trim() } : {}), + ...(type !== undefined ? { type } : {}), + ...(config !== undefined ? { config: JSON.stringify(config) } : {}), + ...(enabled !== undefined ? { enabled } : {}), + }, + ); + if (!row) return res.status(404).json({ error: "Channel not found" }); + res.json(row); + } catch (err) { + databaseLogger.error("Failed to update notification channel", { + operation: "update_channel", + error: err, + }); + res.status(500).json({ error: "Failed to update channel" }); + } + }, +); + +/** + * @openapi + * /notification-channels/{id}: + * delete: + * summary: Delete a notification channel + * tags: + * - Notifications + */ +router.delete( + "/notification-channels/:id", + async (req: Request, res: Response) => { + const userId = (req as AuthenticatedRequest).userId; + const channelId = Number(req.params.id); + const deleted = + await createCurrentNotificationChannelRepository().deleteNotificationChannel( + channelId, + userId, + ); + if (!deleted) return res.status(404).json({ error: "Channel not found" }); + res.json({ success: true }); + }, +); + +/** + * @openapi + * /notification-channels/{id}/test: + * post: + * summary: Send a test notification + * tags: + * - Notifications + */ +router.post( + "/notification-channels/:id/test", + async (req: Request, res: Response) => { + const userId = (req as AuthenticatedRequest).userId; + const channelId = Number(req.params.id); + const row = + await createCurrentNotificationChannelRepository().findNotificationChannelForUser( + channelId, + userId, + ); + if (!row) return res.status(404).json({ error: "Channel not found" }); + + const testPayload = { + hostName: "Test Host", + hostId: 0, + triggerType: "test", + message: "This is a test notification from Termix", + severity: "info" as const, + timestamp: new Date().toISOString(), + ruleId: 0, + ruleName: "Test", + }; + + try { + let config: Record; + try { + config = JSON.parse(row.config) as Record; + } catch { + return res + .status(400) + .json({ success: false, error: "Invalid channel config" }); + } + + if (row.type === "webhook") { + await sendWebhook( + config as unknown as Parameters[0], + testPayload, + ); + } else if (row.type === "ntfy") { + await sendNtfy( + config as unknown as Parameters[0], + testPayload, + ); + } else if (row.type === "discord") { + await sendDiscord( + config as unknown as Parameters[0], + testPayload, + ); + } + res.json({ success: true }); + } catch (err) { + res.json({ + success: false, + error: err instanceof Error ? err.message : String(err), + }); + } + }, +); + +export default router; diff --git a/src/backend/hosts/terminal/index.ts b/src/backend/hosts/terminal/index.ts index 6818346fb..8dad211ea 100644 --- a/src/backend/hosts/terminal/index.ts +++ b/src/backend/hosts/terminal/index.ts @@ -57,7 +57,7 @@ import { } from "../terminal-auth-helpers.js"; import { isWindowsSftpPath, sftpPathToLocalPath } from "../transfer-paths.js"; import { preparePrivateKeyForSSH2 } from "../../utils/ssh-key-utils.js"; -import { triggerLoginAlert } from "../../utils/alert-trigger.js"; +import { dispatchLoginEvent } from "../../utils/login-event-dispatch.js"; import { getClientIp } from "../../utils/request-origin.js"; import { isRetriableDnsError, resolveHostForSshConnect } from "../ssh-dns.js"; import { resolveSshKeepalive } from "../ssh-keepalive.js"; @@ -2483,7 +2483,7 @@ wss.on("connection", async (ws: WebSocket, req) => { ); if (id && hostConfig.userId) { - triggerLoginAlert( + dispatchLoginEvent( id, hostConfig.userId, username, diff --git a/src/backend/starter.ts b/src/backend/starter.ts index 4f877b598..c29ac95cc 100644 --- a/src/backend/starter.ts +++ b/src/backend/starter.ts @@ -265,10 +265,6 @@ async function provisionLocalDesktopUserIfNeeded(): Promise { await import("./utils/crypto-migration/channel-config-encryption.js"); await runChannelConfigEncryptionMigration(); - const { runAutomationsMigration } = - await import("./utils/crypto-migration/automations-migration.js"); - await runAutomationsMigration(); - if (process.env.ELECTRON_EMBEDDED === "true") { await provisionLocalDesktopUserIfNeeded(); } diff --git a/src/backend/tests/database/repositories/alert-repository.test.ts b/src/backend/tests/database/repositories/alert-repository.test.ts deleted file mode 100644 index 8987913f0..000000000 --- a/src/backend/tests/database/repositories/alert-repository.test.ts +++ /dev/null @@ -1,471 +0,0 @@ -import crypto from "node:crypto"; -import { sql } from "drizzle-orm"; -import { afterEach, describe, expect, it, vi } from "vitest"; -import { TestSqliteDatabase } from "./test-support.js"; -import { AlertRepository } from "../../../database/repositories/alert-repository.js"; -import { DataCrypto } from "../../../utils/data-crypto.js"; - -describe("AlertRepository", () => { - let adapter: TestSqliteDatabase | null = null; - - afterEach(async () => { - if (adapter) { - await adapter.close(); - adapter = null; - } - }); - - async function createRepository( - onWrite?: () => void | Promise, - ): Promise { - adapter = new TestSqliteDatabase(); - const context = await adapter.connect(); - await adapter.exec(` - INSERT INTO users (id, username, password_hash) - VALUES ('user-1', 'alice', 'hash'), ('user-2', 'bob', 'hash'); - INSERT INTO ssh_data (id, user_id, name, ip, port, username, auth_type) - VALUES (1, 'user-1', 'alpha', '127.0.0.1', 22, 'root', 'password'); - `); - - return new AlertRepository(context, onWrite); - } - - it("manages notification channels", async () => { - let writes = 0; - const repo = await createRepository(() => { - writes += 1; - }); - - const created = await repo.createNotificationChannel({ - userId: "user-1", - name: "Ops", - type: "webhook", - config: '{"url":"https://example.test"}', - enabled: true, - }); - - expect(created).toMatchObject({ - user_id: "user-1", - name: "Ops", - type: "webhook", - enabled: 1, - }); - - const updated = await repo.updateNotificationChannel(created.id, "user-1", { - name: "Ops disabled", - enabled: false, - }); - expect(updated).toMatchObject({ name: "Ops disabled", enabled: 0 }); - - expect(await repo.listNotificationChannels("user-1")).toHaveLength(1); - expect(await repo.deleteNotificationChannel(created.id, "user-2")).toBe( - false, - ); - expect(await repo.deleteNotificationChannel(created.id, "user-1")).toBe( - true, - ); - expect(await repo.listNotificationChannels("user-1")).toHaveLength(0); - expect(writes).toBe(3); - }); - - it("manages alert rules and linked channels", async () => { - const repo = await createRepository(); - const ownedChannel = await repo.createNotificationChannel({ - userId: "user-1", - name: "Owned", - type: "ntfy", - config: '{"url":"https://ntfy.test","topic":"termix"}', - enabled: true, - }); - const foreignChannel = await repo.createNotificationChannel({ - userId: "user-2", - name: "Foreign", - type: "webhook", - config: '{"url":"https://example.test"}', - enabled: true, - }); - - const created = await repo.createAlertRule({ - userId: "user-1", - hostId: null, - name: "CPU high", - enabled: true, - triggerType: "cpu_threshold", - thresholdValue: 80, - thresholdDurationSeconds: 30, - cooldownMinutes: 5, - channels: [ownedChannel.id, foreignChannel.id], - now: "2026-01-01T00:00:00.000Z", - }); - - expect(created).toMatchObject({ - user_id: "user-1", - host_id: null, - name: "CPU high", - trigger_type: "cpu_threshold", - threshold_value: 80, - channels: [ownedChannel.id], - }); - - const updated = await repo.updateAlertRule(created.id, "user-1", { - name: "CPU very high", - hostId: 1, - channels: [], - now: "2026-01-02T00:00:00.000Z", - }); - expect(updated).toMatchObject({ - name: "CPU very high", - host_id: 1, - channels: [], - updated_at: "2026-01-02T00:00:00.000Z", - }); - - const rules = await repo.listAlertRules("user-1"); - expect(rules).toHaveLength(1); - expect(rules[0].channels).toEqual([]); - expect(await repo.deleteAlertRule(created.id, "user-2")).toBe(false); - expect(await repo.deleteAlertRule(created.id, "user-1")).toBe(true); - }); - - it("lists, acknowledges, and prunes firings", async () => { - const repo = await createRepository(); - const rule = await repo.createAlertRule({ - userId: "user-1", - hostId: 1, - name: "Host offline", - enabled: true, - triggerType: "host_offline", - thresholdValue: null, - thresholdDurationSeconds: null, - cooldownMinutes: 15, - channels: [], - now: "2026-01-01T00:00:00.000Z", - }); - - await repo.createFiring({ - userId: "user-1", - ruleId: rule.id, - hostId: 1, - hostName: "alpha", - value: null, - message: "down", - severity: "critical", - }); - - const listed = await repo.listAlertFirings({ - userId: "user-1", - limit: 10, - offset: 0, - }); - expect(listed.total).toBe(1); - expect(listed.firings[0]).toMatchObject({ - rule_id: rule.id, - host_name: "alpha", - acknowledged: 0, - rule_name: "Host offline", - }); - - await repo.acknowledgeFiring(listed.firings[0].id, "user-1"); - const unacknowledged = await repo.listAlertFirings({ - userId: "user-1", - acknowledged: false, - limit: 10, - offset: 0, - }); - expect(unacknowledged.total).toBe(0); - - await repo.acknowledgeAllFirings("user-1"); - await repo.pruneFiringsOlderThan("user-1", 0); - }); - - it("loads enabled rules and notification channels for the alert engine", async () => { - const repo = await createRepository(); - const channel = await repo.createNotificationChannel({ - userId: "user-1", - name: "Ops", - type: "webhook", - config: '{"url":"https://example.test"}', - enabled: true, - }); - const disabledChannel = await repo.createNotificationChannel({ - userId: "user-1", - name: "Disabled", - type: "webhook", - config: '{"url":"https://disabled.test"}', - enabled: false, - }); - const rule = await repo.createAlertRule({ - userId: "user-1", - hostId: null, - name: "CPU high", - enabled: true, - triggerType: "cpu_threshold", - thresholdValue: 90, - thresholdDurationSeconds: 0, - cooldownMinutes: 15, - channels: [channel.id, disabledChannel.id], - now: "2026-01-01T00:00:00.000Z", - }); - - expect(await repo.listEnabledRulesForHost(1)).toMatchObject([ - { - id: rule.id, - userId: "user-1", - triggerType: "cpu_threshold", - enabled: true, - }, - ]); - expect(await repo.findRuleById(rule.id)).toMatchObject({ - id: rule.id, - cooldownMinutes: 15, - }); - expect(await repo.listEnabledChannelsForRule(rule.id)).toEqual([ - { - id: channel.id, - type: "webhook", - config: '{"url":"https://example.test"}', - enabled: true, - }, - ]); - }); - - it("keeps another user's wildcard rules off a host they do not own", async () => { - const repo = await createRepository(); - await adapter!.exec(` - INSERT INTO ssh_data (id, user_id, name, ip, port, username, auth_type) - VALUES (2, 'user-2', 'bravo', '127.0.0.2', 22, 'root', 'password'); - `); - - const ownerRule = await repo.createAlertRule({ - userId: "user-1", - hostId: null, - name: "Owner wildcard", - enabled: true, - triggerType: "cpu_threshold", - thresholdValue: 90, - thresholdDurationSeconds: 0, - cooldownMinutes: 15, - channels: [], - now: "2026-01-01T00:00:00.000Z", - }); - const otherRule = await repo.createAlertRule({ - userId: "user-2", - hostId: null, - name: "Other wildcard", - enabled: true, - triggerType: "cpu_threshold", - thresholdValue: 90, - thresholdDurationSeconds: 0, - cooldownMinutes: 15, - channels: [], - now: "2026-01-01T00:00:00.000Z", - }); - - // Host 1 belongs to user-1, so only user-1's wildcard rule may fire. - const forHostOne = await repo.listEnabledRulesForHost(1); - expect(forHostOne.map((rule) => rule.id)).toEqual([ownerRule.id]); - - const forHostTwo = await repo.listEnabledRulesForHost(2); - expect(forHostTwo.map((rule) => rule.id)).toEqual([otherRule.id]); - }); - - it("still matches a rule pinned to a specific host", async () => { - const repo = await createRepository(); - const pinned = await repo.createAlertRule({ - userId: "user-1", - hostId: 1, - name: "Pinned", - enabled: true, - triggerType: "disk_threshold", - thresholdValue: 90, - thresholdDurationSeconds: 0, - cooldownMinutes: 15, - channels: [], - now: "2026-01-01T00:00:00.000Z", - }); - - expect((await repo.listEnabledRulesForHost(1)).map((r) => r.id)).toEqual([ - pinned.id, - ]); - }); - - it("encrypts channel configs at rest and returns them decrypted", async () => { - const key = crypto.randomBytes(32); - const spy = vi - .spyOn(DataCrypto, "getUserDataKey") - .mockImplementation(() => key); - - try { - const repo = await createRepository(); - const secret = '{"url":"https://ntfy.test","token":"super-secret"}'; - - const created = await repo.createNotificationChannel({ - userId: "user-1", - name: "Ntfy", - type: "ntfy", - config: secret, - enabled: true, - }); - expect(created.config).toBe(secret); - - // The stored bytes must not contain the token in the clear. - const stored = await adapter!.query<{ config: string }>( - sql`SELECT config FROM notification_channels WHERE id = ${created.id}`, - ); - expect(stored[0].config).not.toContain("super-secret"); - - // Every read path hands back plaintext. - const listed = await repo.listNotificationChannels("user-1"); - expect(listed[0].config).toBe(secret); - expect( - (await repo.findNotificationChannelForUser(created.id, "user-1")) - ?.config, - ).toBe(secret); - - const rule = await repo.createAlertRule({ - userId: "user-1", - hostId: null, - name: "CPU", - enabled: true, - triggerType: "cpu_threshold", - thresholdValue: 90, - thresholdDurationSeconds: 0, - cooldownMinutes: 15, - channels: [created.id], - now: "2026-01-01T00:00:00.000Z", - }); - const engineChannels = await repo.listEnabledChannelsForRule(rule.id); - expect(engineChannels[0].config).toBe(secret); - - const rotated = '{"url":"https://ntfy.test","token":"rotated"}'; - const updated = await repo.updateNotificationChannel( - created.id, - "user-1", - { config: rotated }, - ); - expect(updated?.config).toBe(rotated); - } finally { - spy.mockRestore(); - } - }); - - it("still reads channel configs written before encryption", async () => { - const repo = await createRepository(); - const plaintext = '{"url":"https://legacy.test"}'; - const created = await repo.createNotificationChannel({ - userId: "user-1", - name: "Legacy", - type: "webhook", - config: plaintext, - enabled: true, - }); - - const key = crypto.randomBytes(32); - const spy = vi - .spyOn(DataCrypto, "getUserDataKey") - .mockImplementation(() => key); - try { - const found = await repo.findNotificationChannelForUser( - created.id, - "user-1", - ); - expect(found?.config).toBe(plaintext); - } finally { - spy.mockRestore(); - } - }); - - it("loads host display names for alert payloads", async () => { - const repo = await createRepository(); - - expect(await repo.getHostDisplayName(1)).toBe("alpha"); - expect(await repo.getHostDisplayName(999)).toBeNull(); - }); - - it("deletes all alert data for a user", async () => { - let writes = 0; - const repo = await createRepository(() => { - writes += 1; - }); - - const userChannel = await repo.createNotificationChannel({ - userId: "user-1", - name: "Ops", - type: "webhook", - config: '{"url":"https://example.test"}', - enabled: true, - }); - const otherChannel = await repo.createNotificationChannel({ - userId: "user-2", - name: "Other", - type: "webhook", - config: '{"url":"https://other.test"}', - enabled: true, - }); - const userRule = await repo.createAlertRule({ - userId: "user-1", - hostId: 1, - name: "CPU high", - enabled: true, - triggerType: "cpu_threshold", - thresholdValue: 80, - thresholdDurationSeconds: 30, - cooldownMinutes: 5, - channels: [userChannel.id], - now: "2026-01-01T00:00:00.000Z", - }); - const otherRule = await repo.createAlertRule({ - userId: "user-2", - hostId: null, - name: "Memory high", - enabled: true, - triggerType: "memory_threshold", - thresholdValue: 90, - thresholdDurationSeconds: 60, - cooldownMinutes: 10, - channels: [otherChannel.id], - now: "2026-01-01T00:00:00.000Z", - }); - await repo.createFiring({ - userId: "user-1", - ruleId: userRule.id, - hostId: 1, - hostName: "alpha", - value: 95, - message: "high", - severity: "warning", - }); - await repo.createFiring({ - userId: "user-2", - ruleId: otherRule.id, - hostId: 1, - hostName: "alpha", - value: 91, - message: "other", - severity: "warning", - }); - - await expect(repo.deleteByUserId("user-1")).resolves.toEqual({ - firingsDeleted: 1, - ruleLinksDeleted: 1, - rulesDeleted: 1, - channelsDeleted: 1, - }); - await expect(repo.deleteByUserId("missing")).resolves.toEqual({ - firingsDeleted: 0, - ruleLinksDeleted: 0, - rulesDeleted: 0, - channelsDeleted: 0, - }); - - expect(await repo.listNotificationChannels("user-1")).toEqual([]); - expect(await repo.listAlertRules("user-1")).toEqual([]); - expect( - await repo.listAlertFirings({ userId: "user-1", limit: 10, offset: 0 }), - ).toEqual({ firings: [], total: 0 }); - expect(await repo.listNotificationChannels("user-2")).toHaveLength(1); - expect(await repo.listAlertRules("user-2")).toHaveLength(1); - expect(await repo.listEnabledChannelsForRule(otherRule.id)).toHaveLength(1); - expect(writes).toBe(7); - }); -}); diff --git a/src/backend/tests/plugins/ai/context.test.ts b/src/backend/tests/plugins/ai/context.test.ts index 35310ae0e..c10bd409c 100644 --- a/src/backend/tests/plugins/ai/context.test.ts +++ b/src/backend/tests/plugins/ai/context.test.ts @@ -6,12 +6,12 @@ const BASE = { hostCount: 3, allowReadOnlyCommands: false }; describe("buildSystemPrompt", () => { it("tells the assistant to stay inside what was asked", () => { // Without these the assistant answered "what is running on this server" - // by also proposing a monitoring script and an alert rule nobody wanted. + // by also proposing a monitoring script and an automation nobody wanted. const prompt = buildSystemPrompt(BASE); expect(prompt).toContain("nothing beyond it"); expect(prompt).toMatch(/Read, then report\. Do not propose anything\./); - expect(prompt).toMatch(/no monitoring, no alert rules, no scripts/); + expect(prompt).toMatch(/no monitoring automations, no scripts/); expect(prompt).toMatch(/One request means one proposal at most/); }); diff --git a/src/backend/tests/plugins/ai/tools/proposal-executor.test.ts b/src/backend/tests/plugins/ai/tools/proposal-executor.test.ts index 166fef74e..3c6ba6131 100644 --- a/src/backend/tests/plugins/ai/tools/proposal-executor.test.ts +++ b/src/backend/tests/plugins/ai/tools/proposal-executor.test.ts @@ -13,14 +13,12 @@ const snippetRepository = { deleteSnippet: vi.fn(), }; const fleetRepository = { create: vi.fn(), addMember: vi.fn() }; -const alertRepository = { createAlertRule: vi.fn() }; const automationRepository = { create: vi.fn() }; vi.mock("../../../../database/repositories/factory.js", () => ({ createCurrentHostRepository: () => hostRepository, createCurrentSnippetRepository: () => snippetRepository, createCurrentFleetRepository: () => fleetRepository, - createCurrentAlertRepository: () => alertRepository, createCurrentAutomationRepository: () => automationRepository, })); diff --git a/src/backend/tests/plugins/host-metrics/alert-engine-superseded.test.ts b/src/backend/tests/plugins/host-metrics/alert-engine-superseded.test.ts deleted file mode 100644 index 01079c40f..000000000 --- a/src/backend/tests/plugins/host-metrics/alert-engine-superseded.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; - -/** - * Once the alert rules have been migrated into automations, both systems hold - * a copy of every rule. If the old engine kept evaluating, every alert would - * be delivered twice. - */ - -const listEnabledRulesForHost = vi.fn(); -const listEnabledRulesForHostUser = vi.fn(); -const createFiring = vi.fn(); - -vi.mock("../../../database/repositories/factory.js", () => ({ - createCurrentAlertRepository: () => ({ - listEnabledRulesForHost, - listEnabledRulesForHostUser, - createFiring, - pruneFiringsOlderThan: vi.fn(), - listEnabledChannelsForRule: vi.fn(async () => []), - findRuleById: vi.fn(async () => null), - getHostDisplayName: vi.fn(async () => "host"), - }), -})); - -vi.mock("../../../utils/logger.js", () => ({ - statsLogger: { warn: vi.fn(), info: vi.fn(), error: vi.fn() }, -})); - -vi.mock("../../../utils/notification-sender.js", () => ({ - sendNotification: vi.fn(async () => undefined), -})); - -vi.mock("../../../utils/discord-sender.js", () => ({ - sendDiscord: vi.fn(async () => undefined), -})); - -const alertEngineModule = - await import("../../../../../plugins/host-metrics/backend/alert-engine.js"); - -const cpuRule = { - id: 1, - userId: "user-1", - hostId: null, - name: "CPU", - enabled: true, - triggerType: "cpu_threshold", - thresholdValue: 50, - thresholdDurationSeconds: 0, - cooldownMinutes: 0, -}; - -beforeEach(() => { - vi.clearAllMocks(); - listEnabledRulesForHost.mockResolvedValue([cpuRule]); - listEnabledRulesForHostUser.mockResolvedValue([cpuRule]); -}); - -describe("AlertEngine before migration", () => { - it("still evaluates rules", async () => { - expect(alertEngineModule.isAlertEngineSuperseded()).toBe(false); - - await alertEngineModule.AlertEngine.getInstance().evaluateMetrics(7, { - cpu: { percent: 90 }, - }); - - expect(listEnabledRulesForHost).toHaveBeenCalled(); - }); -}); - -describe("AlertEngine after migration", () => { - it("stops evaluating every trigger type", async () => { - alertEngineModule.markAlertEngineSuperseded(); - expect(alertEngineModule.isAlertEngineSuperseded()).toBe(true); - - const engine = alertEngineModule.AlertEngine.getInstance(); - await engine.evaluateMetrics(7, { cpu: { percent: 99 } }); - await engine.evaluateStatus(7, false); - await engine.evaluateHealthCheck(7, "user-1", "web", false); - await engine.evaluateUserLogin(7, "user-1", "root", "10.0.0.1"); - - // Nothing is even loaded, so nothing can be delivered a second time. - expect(listEnabledRulesForHost).not.toHaveBeenCalled(); - expect(listEnabledRulesForHostUser).not.toHaveBeenCalled(); - expect(createFiring).not.toHaveBeenCalled(); - }); -}); diff --git a/src/backend/tests/plugins/host-metrics/login-alert-dispatch.test.ts b/src/backend/tests/plugins/host-metrics/login-alert-dispatch.test.ts index 039e1c56a..e860512e4 100644 --- a/src/backend/tests/plugins/host-metrics/login-alert-dispatch.test.ts +++ b/src/backend/tests/plugins/host-metrics/login-alert-dispatch.test.ts @@ -26,7 +26,6 @@ const route = ast.statements.find( ); if (!route) throw new Error("Login event route is missing"); const notify = vi.fn(); -const legacy = vi.fn().mockResolvedValue(undefined); let handler: (req: unknown, res: unknown) => Promise; runInNewContext( ts.transpileModule(route.getText(ast), { @@ -49,7 +48,6 @@ runInNewContext( }, }), notifyAutomationInternalEvent: notify, - AlertEngine: { getInstance: () => ({ evaluateUserLogin: legacy }) }, }, ); const body = { @@ -61,7 +59,7 @@ const body = { const response = () => ({ status: vi.fn().mockReturnThis(), json: vi.fn() }); beforeEach(() => vi.clearAllMocks()); -it("delivers successful SSH login details to automations while retaining the legacy hook", async () => { +it("delivers successful SSH login details to automations", async () => { const res = response(); await handler( { @@ -75,12 +73,6 @@ it("delivers successful SSH login details to automations while retaining the leg sshUser: "alice", fromIp: "192.0.2.4", }); - expect(legacy).toHaveBeenCalledExactlyOnceWith( - 42, - "owner", - "alice", - "192.0.2.4", - ); expect(res.json).toHaveBeenCalledWith({ ok: true }); }); @@ -101,6 +93,5 @@ it.each([ ); expect(res.status).toHaveBeenCalledWith(403); expect(notify).not.toHaveBeenCalled(); - expect(legacy).not.toHaveBeenCalled(); }, ); diff --git a/src/backend/tests/utils/alert-trigger.test.ts b/src/backend/tests/utils/login-event-dispatch.test.ts similarity index 84% rename from src/backend/tests/utils/alert-trigger.test.ts rename to src/backend/tests/utils/login-event-dispatch.test.ts index 1edf42dba..a15023108 100644 --- a/src/backend/tests/utils/alert-trigger.test.ts +++ b/src/backend/tests/utils/login-event-dispatch.test.ts @@ -1,9 +1,9 @@ import { afterEach, describe, expect, it, vi } from "vitest"; -import { triggerLoginAlert } from "../../utils/alert-trigger.js"; +import { dispatchLoginEvent } from "../../utils/login-event-dispatch.js"; import { SystemCrypto } from "../../utils/system-crypto.js"; import { sshLogger } from "../../utils/logger.js"; -describe("triggerLoginAlert", () => { +describe("dispatchLoginEvent", () => { afterEach(() => { vi.restoreAllMocks(); }); @@ -19,12 +19,12 @@ describe("triggerLoginAlert", () => { ); const warn = vi.spyOn(sshLogger, "warn").mockImplementation(() => {}); - await triggerLoginAlert(7, "user-1", "root", "192.0.2.1"); + await dispatchLoginEvent(7, "user-1", "root", "192.0.2.1"); expect(warn).toHaveBeenCalledWith( - "Failed to trigger login alert", + "Failed to dispatch login event", expect.objectContaining({ - operation: "login_alert_trigger_error", + operation: "login_event_dispatch_error", hostId: 7, error: 'Metrics service returned 401: {"error":"Missing authentication token"}', @@ -41,7 +41,7 @@ describe("triggerLoginAlert", () => { ); const warn = vi.spyOn(sshLogger, "warn").mockImplementation(() => {}); - await triggerLoginAlert(7, "user-1", "root", "192.0.2.1"); + await dispatchLoginEvent(7, "user-1", "root", "192.0.2.1"); expect(warn).not.toHaveBeenCalled(); }); @@ -54,7 +54,7 @@ describe("triggerLoginAlert", () => { .spyOn(globalThis, "fetch") .mockResolvedValue(new Response('{"ok":true}', { status: 200 })); - await triggerLoginAlert(42, "user-1", "root", "10.0.0.5"); + await dispatchLoginEvent(42, "user-1", "root", "10.0.0.5"); expect(fetchSpy).toHaveBeenCalledWith( "http://localhost:30005/internal/login-alert", @@ -83,11 +83,11 @@ describe("triggerLoginAlert", () => { const warn = vi.spyOn(sshLogger, "warn").mockImplementation(() => {}); await expect( - triggerLoginAlert(1, "user-1", "root", "127.0.0.1"), + dispatchLoginEvent(1, "user-1", "root", "127.0.0.1"), ).resolves.toBeUndefined(); expect(warn).toHaveBeenCalledWith( - "Failed to trigger login alert", + "Failed to dispatch login event", expect.objectContaining({ hostId: 1 }), ); }); diff --git a/src/backend/utils/crypto-migration/automations-migration.ts b/src/backend/utils/crypto-migration/automations-migration.ts deleted file mode 100644 index b80718a98..000000000 --- a/src/backend/utils/crypto-migration/automations-migration.ts +++ /dev/null @@ -1,234 +0,0 @@ -import type { - AutomationDefinition, - Step, - Trigger, -} from "../../../types/automations.js"; -import { AUTOMATION_DEFINITION_VERSION } from "../../../types/automations.js"; -import { databaseLogger } from "../logger.js"; -import { - createCurrentAutomationRepository, - createCurrentRepositoryContext, - createCurrentSettingsRepository, -} from "../../database/repositories/factory.js"; -import { alertRuleChannels, alertRules } from "../../database/db/schema.js"; -import { eq } from "drizzle-orm"; - -const MIGRATION_FLAG = "alert_rules_to_automations_v1"; - -export interface AutomationsMigrationResult { - migrated: number; - skipped: number; -} - -/** - * Carries existing alert rules over into automations. - * - * Each rule becomes an automation whose trigger is the rule's threshold or - * state change and whose only step notifies the channels that rule was linked - * to, which is exactly what the alert engine did with it. - * - * The alert_* tables are deliberately left in place. They are the rollback - * path, and alert_firings is user-visible history; nothing writes to them once - * the automations engine takes over. - */ -export async function runAutomationsMigration(): Promise { - const settingsRepository = createCurrentSettingsRepository(); - - try { - if ((await settingsRepository.get(MIGRATION_FLAG)) === "done") { - // Already migrated on an earlier boot; the automations engine owns - // evaluation from here, so the old one must stay quiet. - await standDownAlertEngine(); - return null; - } - - const { drizzle } = createCurrentRepositoryContext(); - const rules = await drizzle.select().from(alertRules); - - if (rules.length === 0) { - await settingsRepository.set(MIGRATION_FLAG, "done"); - await standDownAlertEngine(); - return { migrated: 0, skipped: 0 }; - } - - const repository = createCurrentAutomationRepository(); - let migrated = 0; - let skipped = 0; - - for (const rule of rules) { - const trigger = triggerForRule(rule); - if (!trigger) { - skipped++; - continue; - } - - const links = await drizzle - .select({ channelId: alertRuleChannels.channelId }) - .from(alertRuleChannels) - .where(eq(alertRuleChannels.ruleId, rule.id)); - const channelIds = links.map((link) => link.channelId); - - const steps: Step[] = [ - { - id: "notify", - type: "notify", - channelIds, - title: `${rule.name}`, - body: messageTemplateFor(rule.triggerType), - severity: "warning", - }, - ]; - - const definition: AutomationDefinition = { - version: AUTOMATION_DEFINITION_VERSION, - trigger, - steps, - }; - - await repository.create({ - userId: rule.userId, - name: rule.name, - description: "Migrated from an alert rule", - enabled: !!rule.enabled, - definition: JSON.stringify(definition), - channels: channelIds, - }); - migrated++; - } - - await settingsRepository.set(MIGRATION_FLAG, "done"); - await standDownAlertEngine(); - - if (migrated > 0) { - databaseLogger.info(`Migrated ${migrated} alert rule(s) to automations`, { - operation: "automations_migration", - migrated, - skipped, - }); - } - - return { migrated, skipped }; - } catch (error) { - databaseLogger.warn("Alert rule migration failed", { - operation: "automations_migration_error", - error: error instanceof Error ? error.message : String(error), - }); - return null; - } -} - -/** - * Imported lazily: this migration runs before the metrics subsystem is loaded, - * and pulling that module in early would drag its timers in with it. - * - * alert-engine now lives in the host-metrics plugin rather than core, so it is - * resolved through getBundledPluginsDir() the same way the plugin loader finds - * any other bundled plugin file, instead of a relative import into a module - * this file no longer sits next to. - */ -async function standDownAlertEngine(): Promise { - try { - const { getBundledPluginsDir } = await import("../../plugins/paths.js"); - const path = await import("node:path"); - const { pathToFileURL } = await import("node:url"); - - const entry = path.join( - getBundledPluginsDir(), - "host-metrics", - "backend", - "alert-engine.js", - ); - const { markAlertEngineSuperseded } = await import( - pathToFileURL(entry).href - ); - markAlertEngineSuperseded(); - } catch { - // If it cannot be loaded there is nothing running to stand down. - } -} - -type AlertRuleRecord = typeof alertRules.$inferSelect; - -function triggerForRule(rule: AlertRuleRecord): Trigger | null { - const hostSelector = - rule.hostId === null - ? ({ kind: "all" } as const) - : ({ kind: "host", hostId: rule.hostId } as const); - const cooldownMinutes = rule.cooldownMinutes ?? 15; - - switch (rule.triggerType) { - case "cpu_threshold": - case "memory_threshold": - case "disk_threshold": { - const path = - rule.triggerType === "cpu_threshold" - ? "cpu.percent" - : rule.triggerType === "memory_threshold" - ? "memory.percent" - : "disk.percent"; - return { - kind: "metric_threshold", - hostSelector, - metric: { path } as Extract< - Trigger, - { kind: "metric_threshold" } - >["metric"], - // The old engine only ever compared with >=. - operator: ">=", - value: rule.thresholdValue ?? 0, - forSeconds: rule.thresholdDurationSeconds ?? undefined, - cooldownMinutes, - }; - } - case "host_offline": - return { - kind: "host_status", - hostSelector, - to: "offline", - cooldownMinutes, - }; - case "host_online": - return { - kind: "host_status", - hostSelector, - to: "online", - cooldownMinutes, - }; - case "health_check_failure": - return { - kind: "health_check", - hostSelector, - to: "failing", - cooldownMinutes, - }; - case "health_check_recovery": - return { - kind: "health_check", - hostSelector, - to: "recovered", - cooldownMinutes, - }; - case "user_login": - return { - kind: "internal_event", - event: "user_login", - hostSelector, - cooldownMinutes, - }; - default: - return null; - } -} - -function messageTemplateFor(triggerType: string): string { - if (triggerType.endsWith("_threshold")) { - return "{{trigger.metric}} on host {{trigger.hostId}} is at {{trigger.value}} (threshold {{trigger.threshold}})"; - } - if (triggerType.startsWith("host_")) { - return "Host {{trigger.hostId}} is {{trigger.status}}"; - } - if (triggerType.startsWith("health_check")) { - return "Health check {{trigger.checkId}} on host {{trigger.hostId}} is {{trigger.state}}"; - } - return "Triggered on host {{trigger.hostId}}"; -} diff --git a/src/backend/utils/alert-trigger.ts b/src/backend/utils/login-event-dispatch.ts similarity index 86% rename from src/backend/utils/alert-trigger.ts rename to src/backend/utils/login-event-dispatch.ts index 2098bec0a..cd3ec4ea3 100644 --- a/src/backend/utils/alert-trigger.ts +++ b/src/backend/utils/login-event-dispatch.ts @@ -3,7 +3,7 @@ import { sshLogger } from "./logger.js"; const METRICS_SERVICE_URL = "http://localhost:30005"; -export async function triggerLoginAlert( +export async function dispatchLoginEvent( hostId: number, userId: string, sshUser: string, @@ -29,8 +29,8 @@ export async function triggerLoginAlert( ); } } catch (err) { - sshLogger.warn("Failed to trigger login alert", { - operation: "login_alert_trigger_error", + sshLogger.warn("Failed to dispatch login event", { + operation: "login_event_dispatch_error", hostId, error: err instanceof Error ? err.message : String(err), }); diff --git a/src/types/homepage-types.ts b/src/types/homepage-types.ts index bbd2288e2..834a7dd7b 100644 --- a/src/types/homepage-types.ts +++ b/src/types/homepage-types.ts @@ -15,7 +15,6 @@ export type WidgetTypeId = | "rss_feed" | "metrics_chart" | "host_grid" - | "alert_feed" | "ping_status" | "recent_activity" | "termix_uptime" @@ -167,11 +166,6 @@ export interface HostGridConfig { columns: 2 | 3 | 4; } -export interface AlertFeedConfig { - maxItems: number; - showAcknowledged: boolean; -} - export interface PingUrl { label: string; url: string; diff --git a/src/types/ui-preferences.ts b/src/types/ui-preferences.ts index a9ce40f6b..7244d8f78 100644 --- a/src/types/ui-preferences.ts +++ b/src/types/ui-preferences.ts @@ -157,7 +157,6 @@ const ALL_HIDEABLE_RAIL_VIEWS = [ "split-screen", "connections", "session-logs", - "alerts", "fleets", "workspaces", "network_graph", diff --git a/src/types/ui-types.ts b/src/types/ui-types.ts index eed5084f4..cfda45d52 100644 --- a/src/types/ui-types.ts +++ b/src/types/ui-types.ts @@ -271,7 +271,6 @@ export type KnownTabType = | "fleet-inventory" // Rail panels that can also open full-width in the main area. | "termix-id" - | "alerts" | "session-logs" | "snippets" | "macros" diff --git a/src/ui/AppShell.tsx b/src/ui/AppShell.tsx index 7c3c11a9a..38e8d672f 100644 --- a/src/ui/AppShell.tsx +++ b/src/ui/AppShell.tsx @@ -129,9 +129,6 @@ const AdminSettingsPanel = lazy(() => default: m.AdminSettingsPanel, })), ); -const AlertsPanel = lazy(() => - import("@/sidebar/AlertsPanel").then((m) => ({ default: m.AlertsPanel })), -); const CredentialsPanel = lazy(() => import("@/sidebar/CredentialsPanel").then((m) => ({ default: m.CredentialsPanel, @@ -2898,12 +2895,6 @@ export function AppShell({ /> )} - - {railView === "alerts" && ( -
- -
- )} ); diff --git a/src/ui/api/alerts-api.ts b/src/ui/api/alerts-api.ts deleted file mode 100644 index 6a5bfe964..000000000 --- a/src/ui/api/alerts-api.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { rbacApi } from "@/main-axios"; - -export interface NotificationChannel { - id: number; - userId: string; - name: string; - type: "webhook" | "ntfy" | "discord"; - config: string; - enabled: boolean; - createdAt: string; -} - -export interface AlertRule { - id: number; - userId: string; - hostId: number | null; - name: string; - enabled: boolean; - triggerType: string; - thresholdValue: number | null; - thresholdDurationSeconds: number | null; - cooldownMinutes: number; - createdAt: string; - updatedAt: string; - channelIds: number[]; -} - -export interface AlertFiring { - id: number; - userId: string; - ruleId: number; - hostId: number; - hostName: string; - firedAt: string; - resolvedAt: string | null; - value: number | null; - message: string; - severity: "info" | "warning" | "critical"; - acknowledged: boolean; - ruleName?: string; -} - -function stringValue(value: unknown, fallback = ""): string { - return typeof value === "string" ? value : fallback; -} - -function numberValue(value: unknown, fallback = 0): number { - return typeof value === "number" && Number.isFinite(value) ? value : fallback; -} - -function nullableNumberValue(value: unknown): number | null { - return typeof value === "number" && Number.isFinite(value) ? value : null; -} - -function boolValue(value: unknown): boolean { - return value === true || value === 1 || value === "1"; -} - -function severityValue(value: unknown): AlertFiring["severity"] { - return value === "info" || value === "critical" || value === "warning" - ? value - : "warning"; -} - -export async function getNotificationChannels(): Promise< - NotificationChannel[] -> { - const res = await rbacApi.get("/notification-channels"); - return res.data; -} - -export type NotificationChannelPayload = Partial< - Omit -> & { - // When creating/updating the channel the UI may pass a parsed object - // for `config` (e.g., { url, username }) — the backend stores it as - // a JSON string. Accept either a string or any structured object here. - // Use `unknown` to allow the component-local config types to be passed - // without importing them into this module. - config: string | unknown; -}; - -export async function createNotificationChannel( - data: NotificationChannelPayload, -): Promise { - const res = await rbacApi.post("/notification-channels", data); - return res.data; -} - -export async function updateNotificationChannel( - id: number, - data: NotificationChannelPayload, -): Promise { - const res = await rbacApi.put(`/notification-channels/${id}`, data); - return res.data; -} - -export async function deleteNotificationChannel(id: number): Promise { - await rbacApi.delete(`/notification-channels/${id}`); -} - -export async function testNotificationChannel(id: number): Promise { - const res = await rbacApi.post(`/notification-channels/${id}/test`); - const data = res.data as { success?: boolean; error?: string }; - if (data && data.success === false) { - throw new Error(data.error || "Test notification failed"); - } -} - -function mapRule(r: Record): AlertRule { - return { - id: r.id as number, - userId: (r.user_id ?? r.userId) as string, - hostId: (r.host_id ?? r.hostId ?? null) as number | null, - name: r.name as string, - enabled: Boolean(r.enabled), - triggerType: (r.trigger_type ?? r.triggerType) as string, - thresholdValue: (r.threshold_value ?? r.thresholdValue ?? null) as - number | null, - thresholdDurationSeconds: (r.threshold_duration_seconds ?? - r.thresholdDurationSeconds ?? - null) as number | null, - cooldownMinutes: (r.cooldown_minutes ?? r.cooldownMinutes) as number, - createdAt: (r.created_at ?? r.createdAt) as string, - updatedAt: (r.updated_at ?? r.updatedAt) as string, - channelIds: Array.isArray(r.channels) ? (r.channels as number[]) : [], - }; -} - -export function mapAlertFiring(r: Record): AlertFiring { - return { - id: numberValue(r.id), - userId: stringValue(r.userId ?? r.user_id), - ruleId: numberValue(r.ruleId ?? r.rule_id), - hostId: numberValue(r.hostId ?? r.host_id), - hostName: stringValue(r.hostName ?? r.host_name), - firedAt: stringValue(r.firedAt ?? r.fired_at, new Date(0).toISOString()), - resolvedAt: stringValue(r.resolvedAt ?? r.resolved_at) || null, - value: nullableNumberValue(r.value), - message: stringValue(r.message), - severity: severityValue(r.severity), - acknowledged: boolValue(r.acknowledged), - ruleName: stringValue(r.ruleName ?? r.rule_name) || undefined, - }; -} - -export async function getAlertRules(): Promise { - const res = await rbacApi.get("/alert-rules"); - return (res.data as Record[]).map(mapRule); -} - -export async function createAlertRule( - data: Partial & { channels?: number[] }, -): Promise { - const res = await rbacApi.post("/alert-rules", data); - return mapRule(res.data as Record); -} - -export async function updateAlertRule( - id: number, - data: Partial & { channels?: number[] }, -): Promise { - const res = await rbacApi.put(`/alert-rules/${id}`, data); - return mapRule(res.data as Record); -} - -export async function deleteAlertRule(id: number): Promise { - await rbacApi.delete(`/alert-rules/${id}`); -} - -export async function getAlertFirings(opts?: { - limit?: number; - offset?: number; - acknowledged?: boolean; -}): Promise { - const res = await rbacApi.get("/alert-firings", { params: opts }); - const data = res.data as { firings?: unknown } | unknown[]; - const rows = Array.isArray(data) - ? data - : Array.isArray(data.firings) - ? data.firings - : []; - return rows.map((row) => mapAlertFiring(row as Record)); -} - -export async function acknowledgeAlertFiring(id: number): Promise { - await rbacApi.post(`/alert-firings/${id}/acknowledge`); -} - -export async function acknowledgeAllAlertFirings(): Promise { - await rbacApi.post("/alert-firings/acknowledge-all"); -} diff --git a/src/ui/api/notification-channels-api.ts b/src/ui/api/notification-channels-api.ts new file mode 100644 index 000000000..9cdab0cb2 --- /dev/null +++ b/src/ui/api/notification-channels-api.ts @@ -0,0 +1,56 @@ +import { rbacApi } from "@/main-axios"; + +export interface NotificationChannel { + id: number; + userId: string; + name: string; + type: "webhook" | "ntfy" | "discord"; + config: string; + enabled: boolean; + createdAt: string; +} + +export async function getNotificationChannels(): Promise< + NotificationChannel[] +> { + const res = await rbacApi.get("/notification-channels"); + return res.data; +} + +export type NotificationChannelPayload = Partial< + Omit +> & { + // When creating/updating the channel the UI may pass a parsed object + // for `config` (e.g., { url, username }) — the backend stores it as + // a JSON string. Accept either a string or any structured object here. + // Use `unknown` to allow the component-local config types to be passed + // without importing them into this module. + config: string | unknown; +}; + +export async function createNotificationChannel( + data: NotificationChannelPayload, +): Promise { + const res = await rbacApi.post("/notification-channels", data); + return res.data; +} + +export async function updateNotificationChannel( + id: number, + data: NotificationChannelPayload, +): Promise { + const res = await rbacApi.put(`/notification-channels/${id}`, data); + return res.data; +} + +export async function deleteNotificationChannel(id: number): Promise { + await rbacApi.delete(`/notification-channels/${id}`); +} + +export async function testNotificationChannel(id: number): Promise { + const res = await rbacApi.post(`/notification-channels/${id}/test`); + const data = res.data as { success?: boolean; error?: string }; + if (data && data.success === false) { + throw new Error(data.error || "Test notification failed"); + } +} diff --git a/src/ui/features/ai/labels.ts b/src/ui/features/ai/labels.ts index d4c0f7a05..9dd0838de 100644 --- a/src/ui/features/ai/labels.ts +++ b/src/ui/features/ai/labels.ts @@ -1,7 +1,7 @@ /** * Turns the internal identifiers the assistant works in into text a user can * read. Tool names, proposal kinds and payload keys all surface in the panel, - * and raw ids like "propose_create_alert_rule" or "thresholddurationseconds" + * and raw ids like "propose_create_automation" or "thresholddurationseconds" * are not something to show anyone. */ @@ -14,9 +14,7 @@ const TOOL_LABELS: Record = { list_automations: "Reading automations", get_automation: "Reading automation", list_workspaces: "Reading workspaces", - list_alert_rules: "Reading alert rules", list_notification_channels: "Reading notification channels", - get_alert_firings: "Reading recent alerts", list_homepage_items: "Reading homepage items", get_command_history: "Reading command history", get_network_topology: "Reading network topology", @@ -28,7 +26,6 @@ const TOOL_LABELS: Record = { propose_delete_snippet: "Delete snippet", propose_create_automation: "Create automation", propose_create_fleet: "Create fleet", - propose_create_alert_rule: "Create alert rule", propose_run_command: "Run command", }; diff --git a/src/ui/features/homepage/HomepageCanvas.tsx b/src/ui/features/homepage/HomepageCanvas.tsx index 2edacd5c6..c6070add6 100644 --- a/src/ui/features/homepage/HomepageCanvas.tsx +++ b/src/ui/features/homepage/HomepageCanvas.tsx @@ -39,7 +39,6 @@ import "./widgets/IframeWidget"; import "./widgets/RssFeedWidget"; import "./widgets/MetricsChartWidget"; import "./widgets/HostGridWidget"; -import "./widgets/AlertFeedWidget"; import "./widgets/PingStatusWidget"; import "./widgets/RecentActivityWidget"; import "./widgets/TermixUptimeWidget"; diff --git a/src/ui/features/homepage/dialogs/AlertFeedEditForm.tsx b/src/ui/features/homepage/dialogs/AlertFeedEditForm.tsx deleted file mode 100644 index a3d5cb570..000000000 --- a/src/ui/features/homepage/dialogs/AlertFeedEditForm.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { useTranslation } from "react-i18next"; -import type { - AlertFeedConfig, - WidgetEditFormProps, -} from "@/types/homepage-types"; -import { Input } from "@/components/input"; - -export function AlertFeedEditForm({ - config, - onChange, -}: WidgetEditFormProps) { - const { t } = useTranslation(); - return ( -
-
- - - onChange({ - ...config, - maxItems: Math.max(1, Number(e.target.value)), - }) - } - className="h-8 text-xs" - /> -
- -
- ); -} diff --git a/src/ui/features/homepage/dialogs/WidgetEditDialog.tsx b/src/ui/features/homepage/dialogs/WidgetEditDialog.tsx index 8ccba8d8a..826558379 100644 --- a/src/ui/features/homepage/dialogs/WidgetEditDialog.tsx +++ b/src/ui/features/homepage/dialogs/WidgetEditDialog.tsx @@ -22,7 +22,6 @@ import type { RssFeedConfig, MetricsChartConfig, HostGridConfig, - AlertFeedConfig, PingStatusConfig, RecentActivityConfig, TermixUptimeConfig, @@ -55,7 +54,6 @@ import { IframeEditForm } from "./IframeEditForm"; import { RssFeedEditForm } from "./RssFeedEditForm"; import { MetricsChartEditForm } from "./MetricsChartEditForm"; import { HostGridEditForm } from "./HostGridEditForm"; -import { AlertFeedEditForm } from "./AlertFeedEditForm"; import { PingStatusEditForm } from "./PingStatusEditForm"; import { RecentActivityEditForm } from "./RecentActivityEditForm"; import { TermixUptimeEditForm } from "./TermixUptimeEditForm"; @@ -197,13 +195,6 @@ export function WidgetEditDialog({ onChange={(c) => setConfig(c as unknown as Record)} /> ); - case "alert_feed": - return ( - setConfig(c as unknown as Record)} - /> - ); case "ping_status": return ( ; - if (severity === "warning") - return ; - return ; -} - -function AlertFeedWidget({ - widget, - config, -}: WidgetComponentProps) { - const { t } = useTranslation(); - const { maxItems, showAcknowledged } = config; - const [firings, setFirings] = useState([]); - const [loading, setLoading] = useState(true); - - const fetchData = async () => { - try { - const data = await getAlertFirings({ limit: maxItems * 2 }); - const filtered = showAcknowledged - ? data - : data.filter((f) => !f.acknowledged); - setFirings(filtered.slice(0, maxItems)); - } catch { - /* ignore */ - } finally { - setLoading(false); - } - }; - - useEffect(() => { - fetchData(); - - let intervalId: ReturnType | null = null; - const start = () => { - if (intervalId !== null) return; - intervalId = setInterval(() => { - if (document.visibilityState === "hidden") return; - void fetchData(); - }, 30_000); - }; - const stop = () => { - if (intervalId === null) return; - clearInterval(intervalId); - intervalId = null; - }; - const onVisibility = () => { - if (document.visibilityState === "hidden") { - stop(); - return; - } - void fetchData(); - start(); - }; - - if (document.visibilityState !== "hidden") start(); - document.addEventListener("visibilitychange", onVisibility); - return () => { - stop(); - document.removeEventListener("visibilitychange", onVisibility); - }; - }, [maxItems, showAcknowledged]); - - const handleAck = async (id: number) => { - try { - await acknowledgeAlertFiring(id); - setFirings((prev) => - prev.map((f) => (f.id === id ? { ...f, acknowledged: true } : f)), - ); - } catch { - /* ignore */ - } - }; - - if (loading) { - return ( -
- {t("homepage.loading")} -
- ); - } - - if (firings.length === 0) { - return ( -
- - - {t("homepage.allClear")} - -
- ); - } - - return ( -
- } - /> -
- {firings.map((f) => ( -
- -
- - {f.ruleName ?? f.message} - - - {f.hostName} · {relativeTime(f.firedAt)} - -
- {!f.acknowledged && ( - - )} -
- ))} -
-
- ); -} - -registerWidget({ - id: "alert_feed", - name: "Alert Feed", - description: "Live feed of active alert firings", - category: "monitoring", - icon: , - defaultConfig: { maxItems: 10, showAcknowledged: false }, - defaultSize: { w: GRID_SIZE * 10, h: GRID_SIZE * 8 }, - minSize: { w: GRID_SIZE * 4, h: GRID_SIZE * 3 }, - component: AlertFeedWidget, -}); - -export { AlertFeedWidget }; diff --git a/src/ui/locales/en.json b/src/ui/locales/en.json index 3ff22f778..b9ffe1d67 100644 --- a/src/ui/locales/en.json +++ b/src/ui/locales/en.json @@ -287,7 +287,6 @@ "loading": "Loading...", "noData": "No data available", "allClear": "All clear", - "acknowledgeAlert": "Acknowledge", "noPingUrls": "No URLs configured", "pingLabel": "Label", "addPingUrl": "Add URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Historical CPU, memory, disk or network chart for a host", "widgetHostGridName": "Host Grid", "widgetHostGridDesc": "Grid view of SSH host statuses", - "widgetAlertFeedName": "Alert Feed", - "widgetAlertFeedDesc": "Live alert firings with acknowledge support", "widgetPingStatusName": "Ping Status", "widgetPingStatusDesc": "HTTP ping status for one or more URLs", "widgetRecentActivityName": "Recent Activity", @@ -747,7 +744,6 @@ "portForwarding": "Forwarding", "sftp": "SFTP", "connections": "Connections", - "alerts": "Alerts", "serial": "Serial", "keepSideMenuOpen": "Keep Menu Open", "collapseSideMenu": "Collapse Menu", @@ -4950,21 +4946,6 @@ "viewHistory": "View History" }, "alerts": { - "tabFirings": "Alerts", - "tabRules": "Rules", - "tabChannels": "Channels", - "noFirings": "No unacknowledged alerts", - "noRules": "No alert rules configured", - "noChannels": "No notification channels configured", - "rulesDesc": "Alert rules trigger notifications", - "channelsDesc": "Where alert notifications are sent", - "acknowledge": "Acknowledge", - "ackAll": "Ack All", - "allAcknowledged": "All alerts acknowledged", - "ackFailed": "Failed to acknowledge alert", - "ackAllFailed": "Failed to acknowledge all alerts", - "showAcknowledged": "Show All", - "hideAcknowledged": "Hide Acked", "addChannel": "Add Channel", "editChannel": "Edit Channel", "channelName": "Name", @@ -4978,21 +4959,10 @@ "ntfyTopicRequired": "Topic is required", "ntfyToken": "Access Token (optional)", "channelSaveFailed": "Failed to save channel", - "test": "Test", - "testSent": "Test notification sent", - "testFailed": "Test notification failed", - "testFailedWithReason": "Test notification failed: {{reason}}", - "addRule": "Add Alert Rule", - "editRule": "Edit Alert Rule", - "ruleName": "Rule Name", - "ruleNameRequired": "Name is required", - "triggerType": "Trigger", - "thresholdValue": "Threshold (%)", - "durationSeconds": "Duration (seconds, 0 = fire immediately)", - "cooldownMinutes": "Cooldown (minutes)", - "channels": "Notification Channels", - "noChannelsHint": "Add channels in the Channels tab first", - "ruleSaveFailed": "Failed to save rule" + "discordUrlInvalid": "Discord URL must be a valid Discord webhook URL", + "discordWebhookDesc": "POST a Discord embed to this webhook URL on each alert firing", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)" }, "ai": { "title": "Assistant", diff --git a/src/ui/locales/translated/af_ZA.json b/src/ui/locales/translated/af_ZA.json index 5938f43e6..8a3970658 100644 --- a/src/ui/locales/translated/af_ZA.json +++ b/src/ui/locales/translated/af_ZA.json @@ -287,7 +287,6 @@ "loading": "Laai tans...", "noData": "Geen data beskikbaar nie", "allClear": "Alles duidelik", - "acknowledgeAlert": "Erken", "noPingUrls": "Geen URL'e gekonfigureer nie", "pingLabel": "Etiket", "addPingUrl": "Voeg URL by", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Historiese SVE-, geheue-, skyf- of netwerkgrafiek vir 'n gasheer", "widgetHostGridName": "Gasheerrooster", "widgetHostGridDesc": "Roosteraansig van SSH-gasheerstatusse", - "widgetAlertFeedName": "Waarskuwingsvoer", - "widgetAlertFeedDesc": "Regstreekse waarskuwingsvuurwerke met erkenningsondersteuning", "widgetPingStatusName": "Ping-status", "widgetPingStatusDesc": "HTTP-pingstatus vir een of meer URL'e", "widgetRecentActivityName": "Onlangse Aktiwiteit", @@ -747,7 +744,6 @@ "portForwarding": "Aanstuur", "sftp": "SFTP", "connections": "Verbindings", - "alerts": "Waarskuwings", "serial": "Reeks", "keepSideMenuOpen": "Hou Kieslys Oop", "collapseSideMenu": "Vou Kieslys in", @@ -4890,21 +4886,6 @@ "viewHistory": "Bekyk Geskiedenis" }, "alerts": { - "tabFirings": "Waarskuwings", - "tabRules": "Reëls", - "tabChannels": "Kanale", - "noFirings": "Geen onerkende waarskuwings nie", - "noRules": "Geen waarskuwingsreëls opgestel nie", - "noChannels": "Geen kennisgewingkanale gekonfigureer nie", - "rulesDesc": "Waarskuwingsreëls aktiveer kennisgewings", - "channelsDesc": "Waar waarskuwingskennisgewings gestuur word", - "acknowledge": "Erken", - "ackAll": "Bevestig alles", - "allAcknowledged": "Alle waarskuwings erken", - "ackFailed": "Kon nie waarskuwing erken nie", - "ackAllFailed": "Kon nie alle waarskuwings erken nie", - "showAcknowledged": "Wys alles", - "hideAcknowledged": "Versteek Goedgekeur", "addChannel": "Voeg kanaal by", "editChannel": "Wysig kanaal", "channelName": "Naam", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Onderwerp", "ntfyTopicRequired": "Onderwerp is vereis", "ntfyToken": "Toegangstoken (opsioneel)", - "channelSaveFailed": "Kon nie kanaal stoor nie", - "test": "Toets", - "testSent": "Toetskennisgewing gestuur", - "testFailed": "Toetskennisgewing het misluk", - "testFailedWithReason": "Toetskennisgewing het misluk: {{reason}}", - "addRule": "Voeg waarskuwingsreël by", - "editRule": "Wysig waarskuwingsreël", - "ruleName": "Reëlnaam", - "ruleNameRequired": "Naam word vereis", - "triggerType": "Sneller", - "thresholdValue": "Drempel (%)", - "durationSeconds": "Duur (sekondes, 0 = onmiddellike vuur)", - "cooldownMinutes": "Afkoeltyd (minute)", - "channels": "Kennisgewingskanale", - "noChannelsHint": "Voeg eers kanale by die Kanale-oortjie", - "ruleSaveFailed": "Kon nie reël stoor nie" + "channelSaveFailed": "Kon nie kanaal stoor nie" }, "ai": { "title": "Assistent", diff --git a/src/ui/locales/translated/ar_SA.json b/src/ui/locales/translated/ar_SA.json index a01a67816..7393fbf75 100644 --- a/src/ui/locales/translated/ar_SA.json +++ b/src/ui/locales/translated/ar_SA.json @@ -287,7 +287,6 @@ "loading": "جار التحميل...", "noData": "لا توجد بيانات", "allClear": "كل شيء طبيعي", - "acknowledgeAlert": "إقرار", "noPingUrls": "لم يتم تكوين عناوين URL", "pingLabel": "التسمية", "addPingUrl": "إضافة URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "مخطط تاريخي لوحدة المعالجة المركزية أو الذاكرة أو القرص أو الشبكة لمضيف", "widgetHostGridName": "شبكة المضيفات", "widgetHostGridDesc": "عرض شبكي لحالات مضيفات SSH", - "widgetAlertFeedName": "موجز التنبيهات", - "widgetAlertFeedDesc": "تنبيهات حية مع دعم الإقرار", "widgetPingStatusName": "حالة Ping", "widgetPingStatusDesc": "حالة ping HTTP لعنوان URL واحد أو أكثر", "widgetRecentActivityName": "النشاط الأخير", @@ -747,7 +744,6 @@ "portForwarding": "إعادة التوجيه", "sftp": "SFTP", "connections": "الاتصالات", - "alerts": "التنبيهات", "serial": "تسلسلي", "keepSideMenuOpen": "أبقِ قائمة الطعام مفتوحة", "collapseSideMenu": "قائمة قابلة للطي", @@ -4890,21 +4886,6 @@ "viewHistory": "عرض السجل" }, "alerts": { - "tabFirings": "التنبيهات", - "tabRules": "القواعد", - "tabChannels": "القنوات", - "noFirings": "لا توجد تنبيهات غير مُقَرَّة", - "noRules": "لم يتم تكوين قواعد تنبيه", - "noChannels": "لم يتم تكوين قنوات إشعار", - "rulesDesc": "تقوم قواعد التنبيه بتشغيل الإشعارات", - "channelsDesc": "مكان إرسال إشعارات التنبيه", - "acknowledge": "إقرار", - "ackAll": "إقرار الكل", - "allAcknowledged": "تم إقرار جميع التنبيهات", - "ackFailed": "فشل في إقرار التنبيه", - "ackAllFailed": "فشل في إقرار جميع التنبيهات", - "showAcknowledged": "إظهار الكل", - "hideAcknowledged": "إخفاء المُقَرَّة", "addChannel": "إضافة قناة", "editChannel": "تعديل القناة", "channelName": "الاسم", @@ -4917,22 +4898,7 @@ "ntfyTopic": "الموضوع", "ntfyTopicRequired": "الموضوع مطلوب", "ntfyToken": "رمز الوصول (اختياري)", - "channelSaveFailed": "فشل حفظ القناة", - "test": "اختبار", - "testSent": "تم إرسال إشعار الاختبار", - "testFailed": "فشل إشعار الاختبار", - "testFailedWithReason": "فشل إشعار الاختبار: {{reason}}", - "addRule": "إضافة قاعدة تنبيه", - "editRule": "تعديل قاعدة تنبيه", - "ruleName": "اسم القاعدة", - "ruleNameRequired": "الاسم مطلوب", - "triggerType": "المشغّل", - "thresholdValue": "الحد (%)", - "durationSeconds": "المدة (بالثواني، 0 = إطلاق فوري)", - "cooldownMinutes": "فترة التهدئة (بالدقائق)", - "channels": "قنوات الإشعارات", - "noChannelsHint": "أضف قنوات في تبويب القنوات أولاً", - "ruleSaveFailed": "فشل حفظ القاعدة" + "channelSaveFailed": "فشل حفظ القناة" }, "ai": { "title": "مساعد", diff --git a/src/ui/locales/translated/bg_BG.json b/src/ui/locales/translated/bg_BG.json index 91df984bb..96a592cce 100644 --- a/src/ui/locales/translated/bg_BG.json +++ b/src/ui/locales/translated/bg_BG.json @@ -287,7 +287,6 @@ "loading": "Зареждане...", "noData": "Няма налични данни", "allClear": "Всичко е чисто", - "acknowledgeAlert": "Потвърждаване", "noPingUrls": "Няма конфигурирани URL адреси", "pingLabel": "Етикет", "addPingUrl": "Добавяне на URL адрес", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Историческа диаграма на процесора, паметта, диска или мрежата за хост", "widgetHostGridName": "Хост мрежа", "widgetHostGridDesc": "Табелен изглед на състоянията на SSH хоста", - "widgetAlertFeedName": "Канал за предупреждения", - "widgetAlertFeedDesc": "Активиране на аларми в реално време с поддръжка на потвърждение", "widgetPingStatusName": "Състояние на пинг", "widgetPingStatusDesc": "HTTP ping статус за един или повече URL адреси", "widgetRecentActivityName": "Последна активност", @@ -747,7 +744,6 @@ "portForwarding": "Препращане", "sftp": "SFTP", "connections": "Връзки", - "alerts": "Сигнали", "serial": "Сериен", "keepSideMenuOpen": "Запази менюто отворено", "collapseSideMenu": "Свиване на менюто", @@ -4890,21 +4886,6 @@ "viewHistory": "Преглед на историята" }, "alerts": { - "tabFirings": "Сигнали", - "tabRules": "Правила", - "tabChannels": "Канали", - "noFirings": "Няма непотвърдени сигнали", - "noRules": "Няма конфигурирани правила за предупреждения", - "noChannels": "Няма конфигурирани канали за известия", - "rulesDesc": "Правилата за известия задействат известия", - "channelsDesc": "Къде се изпращат известия за предупреждения", - "acknowledge": "Потвърждаване", - "ackAll": "Потвърждение на всички", - "allAcknowledged": "Всички сигнали са потвърдени", - "ackFailed": "Неуспешно потвърждаване на предупреждението", - "ackAllFailed": "Неуспешно потвърждаване на всички сигнали", - "showAcknowledged": "Покажи всички", - "hideAcknowledged": "Скриване на одобрено", "addChannel": "Добавяне на канал", "editChannel": "Редактиране на канал", "channelName": "Име", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Тема", "ntfyTopicRequired": "Темата е задължителна", "ntfyToken": "Токен за достъп (по избор)", - "channelSaveFailed": "Запазването на канала не бе успешно", - "test": "Тест", - "testSent": "Тестово известие е изпратено", - "testFailed": "Тестовото известие не беше успешно", - "testFailedWithReason": "Тестовото известие не беше успешно: {{reason}}", - "addRule": "Добавяне на правило за предупреждение", - "editRule": "Редактиране на правило за предупреждение", - "ruleName": "Име на правилото", - "ruleNameRequired": "Името е задължително", - "triggerType": "Спусък", - "thresholdValue": "Праг (%)", - "durationSeconds": "Продължителност (секунди, 0 = незабавно задействане)", - "cooldownMinutes": "Охлаждане (минути)", - "channels": "Канали за известия", - "noChannelsHint": "Първо добавете канали в раздела „Канали“", - "ruleSaveFailed": "Запазването на правилото не бе успешно" + "channelSaveFailed": "Запазването на канала не бе успешно" }, "ai": { "title": "Асистент", diff --git a/src/ui/locales/translated/bn_BD.json b/src/ui/locales/translated/bn_BD.json index f2b3ca19b..3678d5341 100644 --- a/src/ui/locales/translated/bn_BD.json +++ b/src/ui/locales/translated/bn_BD.json @@ -287,7 +287,6 @@ "loading": "লোড হচ্ছে...", "noData": "কোন ডেটা উপলব্ধ নেই", "allClear": "সব পরিষ্কার", - "acknowledgeAlert": "স্বীকার করুন", "noPingUrls": "কোন URL কনফিগার করা নেই", "pingLabel": "লেবেল", "addPingUrl": "URL যোগ করুন", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "একটি হোস্টের ঐতিহাসিক সিপিইউ, মেমরি, ডিস্ক বা নেটওয়ার্ক চার্ট", "widgetHostGridName": "হোস্ট গ্রিড", "widgetHostGridDesc": "SSH হোস্ট স্ট্যাটাসের গ্রিড ভিউ", - "widgetAlertFeedName": "সতর্কতা ফিড", - "widgetAlertFeedDesc": "স্বীকৃতি সমর্থন সহ লাইভ অ্যালার্ট চালু", "widgetPingStatusName": "পিং স্ট্যাটাস", "widgetPingStatusDesc": "এক বা একাধিক URL-এর জন্য HTTP পিং স্ট্যাটাস", "widgetRecentActivityName": "সাম্প্রতিক কার্যকলাপ", @@ -747,7 +744,6 @@ "portForwarding": "ফরোয়ার্ডিং", "sftp": "এসএফটিপি", "connections": "সংযোগ", - "alerts": "সতর্কতা", "serial": "সিরিয়াল", "keepSideMenuOpen": "মেনু খোলা রাখুন", "collapseSideMenu": "মেনু সংকুচিত করুন", @@ -4890,21 +4886,6 @@ "viewHistory": "ইতিহাস দেখুন" }, "alerts": { - "tabFirings": "সতর্কতা", - "tabRules": "নিয়ম", - "tabChannels": "চ্যানেল", - "noFirings": "কোনো অস্বীকৃত সতর্কতা নেই", - "noRules": "কোনো সতর্কতা নিয়ম কনফিগার করা নেই", - "noChannels": "কোন বিজ্ঞপ্তি চ্যানেল কনফিগার করা নেই", - "rulesDesc": "সতর্কতা নিয়মগুলি বিজ্ঞপ্তি ট্রিগার করে", - "channelsDesc": "যেখানে সতর্কবার্তা পাঠানো হয়", - "acknowledge": "স্বীকার করুন", - "ackAll": "সবাইকে ধন্যবাদ", - "allAcknowledged": "সকল সতর্কতা স্বীকার করা হয়েছে", - "ackFailed": "সতর্কতা স্বীকার করতে ব্যর্থ হয়েছে", - "ackAllFailed": "সমস্ত সতর্কতা স্বীকার করতে ব্যর্থ হয়েছে", - "showAcknowledged": "সব দেখান", - "hideAcknowledged": "লুকান অ্যাকড", "addChannel": "চ্যানেল যোগ করুন", "editChannel": "চ্যানেল সম্পাদনা করুন", "channelName": "নাম", @@ -4917,22 +4898,7 @@ "ntfyTopic": "বিষয়", "ntfyTopicRequired": "বিষয় আবশ্যক", "ntfyToken": "অ্যাক্সেস টোকেন (ঐচ্ছিক)", - "channelSaveFailed": "চ্যানেল সংরক্ষণ করতে ব্যর্থ হয়েছে", - "test": "পরীক্ষা", - "testSent": "পরীক্ষার বিজ্ঞপ্তি পাঠানো হয়েছে", - "testFailed": "পরীক্ষার বিজ্ঞপ্তি ব্যর্থ হয়েছে", - "testFailedWithReason": "পরীক্ষার বিজ্ঞপ্তি ব্যর্থ হয়েছে: {{reason}}", - "addRule": "সতর্কতা নিয়ম যোগ করুন", - "editRule": "সতর্কতা নিয়ম সম্পাদনা করুন", - "ruleName": "নিয়মের নাম", - "ruleNameRequired": "নাম আবশ্যক", - "triggerType": "ট্রিগার", - "thresholdValue": "থ্রেশহোল্ড (%)", - "durationSeconds": "সময়কাল (সেকেন্ড, ০ = অবিলম্বে চালু হবে)", - "cooldownMinutes": "কুলডাউন (মিনিট)", - "channels": "বিজ্ঞপ্তি চ্যানেল", - "noChannelsHint": "প্রথমে চ্যানেল ট্যাবে চ্যানেল যোগ করুন।", - "ruleSaveFailed": "নিয়ম সংরক্ষণ করতে ব্যর্থ হয়েছে" + "channelSaveFailed": "চ্যানেল সংরক্ষণ করতে ব্যর্থ হয়েছে" }, "ai": { "title": "সহকারী", diff --git a/src/ui/locales/translated/ca_ES.json b/src/ui/locales/translated/ca_ES.json index 152c3ea00..2504d45f5 100644 --- a/src/ui/locales/translated/ca_ES.json +++ b/src/ui/locales/translated/ca_ES.json @@ -287,7 +287,6 @@ "loading": "S'està carregant...", "noData": "No hi ha dades disponibles", "allClear": "Tot clar", - "acknowledgeAlert": "Reconeix", "noPingUrls": "No s'han configurat URL", "pingLabel": "Etiqueta", "addPingUrl": "Afegeix URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Gràfic històric de CPU, memòria, disc o xarxa per a un host", "widgetHostGridName": "Graella d'amfitrió", "widgetHostGridDesc": "Vista de quadrícula dels estats dels hosts SSH", - "widgetAlertFeedName": "Canal d'alertes", - "widgetAlertFeedDesc": "Trets d'alerta en directe amb suport de confirmació", "widgetPingStatusName": "Estat del ping", "widgetPingStatusDesc": "Estat del ping HTTP per a una o més URL", "widgetRecentActivityName": "Activitat recent", @@ -747,7 +744,6 @@ "portForwarding": "Reenviament", "sftp": "SFTP", "connections": "Connexions", - "alerts": "Alertes", "serial": "Sèrie", "keepSideMenuOpen": "Mantenir el menú obert", "collapseSideMenu": "Menú replegable", @@ -4890,21 +4886,6 @@ "viewHistory": "Veure l'historial" }, "alerts": { - "tabFirings": "Alertes", - "tabRules": "Regles", - "tabChannels": "Canals", - "noFirings": "Sense alertes no confirmades", - "noRules": "No hi ha cap regla d'alerta configurada", - "noChannels": "No hi ha canals de notificació configurats", - "rulesDesc": "Les regles d'alerta activen les notificacions", - "channelsDesc": "On s'envien les notificacions d'alerta", - "acknowledge": "Reconeix", - "ackAll": "Ack Tot", - "allAcknowledged": "Totes les alertes han estat reconegudes", - "ackFailed": "No s'ha pogut confirmar l'alerta", - "ackAllFailed": "No s'han pogut reconèixer totes les alertes", - "showAcknowledged": "Mostra-ho tot", - "hideAcknowledged": "Amaga l'acusat", "addChannel": "Afegeix un canal", "editChannel": "Edita el canal", "channelName": "Nom", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Tema", "ntfyTopicRequired": "El tema és obligatori", "ntfyToken": "Token d'accés (opcional)", - "channelSaveFailed": "No s'ha pogut desar el canal", - "test": "Prova", - "testSent": "Notificació de prova enviada", - "testFailed": "La notificació de prova ha fallat", - "testFailedWithReason": "La notificació de prova ha fallat: {{reason}}", - "addRule": "Afegeix una regla d'alerta", - "editRule": "Edita la regla d'alerta", - "ruleName": "Nom de la regla", - "ruleNameRequired": "El nom és obligatori", - "triggerType": "Disparador", - "thresholdValue": "Llindar (%)", - "durationSeconds": "Durada (segons, 0 = dispara immediatament)", - "cooldownMinutes": "Refredament (minuts)", - "channels": "Canals de notificació", - "noChannelsHint": "Afegiu primer els canals a la pestanya Canals", - "ruleSaveFailed": "No s'ha pogut desar la regla" + "channelSaveFailed": "No s'ha pogut desar el canal" }, "ai": { "title": "Assistent", diff --git a/src/ui/locales/translated/cs_CZ.json b/src/ui/locales/translated/cs_CZ.json index adc288921..cb90d1c18 100644 --- a/src/ui/locales/translated/cs_CZ.json +++ b/src/ui/locales/translated/cs_CZ.json @@ -287,7 +287,6 @@ "loading": "Načítání...", "noData": "Nejsou k dispozici žádná data", "allClear": "Všechno čisté", - "acknowledgeAlert": "Potvrdit", "noPingUrls": "Žádné adresy URL nejsou nakonfigurovány", "pingLabel": "Označení", "addPingUrl": "Přidat URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Historický graf CPU, paměti, disku nebo sítě pro hostitele", "widgetHostGridName": "Hostitelská mřížka", "widgetHostGridDesc": "Mřížkové zobrazení stavů hostitelů SSH", - "widgetAlertFeedName": "Zdroj upozornění", - "widgetAlertFeedDesc": "Živé výstrahy s podporou potvrzení", "widgetPingStatusName": "Stav pingu", "widgetPingStatusDesc": "Stav HTTP pingu pro jednu nebo více URL adres", "widgetRecentActivityName": "Nedávná aktivita", @@ -747,7 +744,6 @@ "portForwarding": "Přeposílání", "sftp": "SFTP", "connections": "Připojení", - "alerts": "Upozornění", "serial": "Seriál", "keepSideMenuOpen": "Ponechat nabídku otevřenou", "collapseSideMenu": "Sbalit nabídku", @@ -4890,21 +4886,6 @@ "viewHistory": "Zobrazit historii" }, "alerts": { - "tabFirings": "Upozornění", - "tabRules": "Pravidla", - "tabChannels": "Kanály", - "noFirings": "Žádná nepotvrzená upozornění", - "noRules": "Nejsou nakonfigurována žádná pravidla upozornění", - "noChannels": "Žádné nakonfigurované kanály oznámení", - "rulesDesc": "Pravidla upozornění spouštějí oznámení", - "channelsDesc": "Kam se odesílají upozornění", - "acknowledge": "Potvrdit", - "ackAll": "Potvrzení všeho", - "allAcknowledged": "Všechna upozornění potvrzena", - "ackFailed": "Nepodařilo se potvrdit upozornění", - "ackAllFailed": "Nepodařilo se potvrdit všechna upozornění", - "showAcknowledged": "Zobrazit vše", - "hideAcknowledged": "Skrýt potvrzeno", "addChannel": "Přidat kanál", "editChannel": "Upravit kanál", "channelName": "Jméno", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Téma", "ntfyTopicRequired": "Téma je povinné", "ntfyToken": "Přístupový token (volitelné)", - "channelSaveFailed": "Uložení kanálu se nezdařilo", - "test": "Test", - "testSent": "Testovací oznámení odesláno", - "testFailed": "Testovací oznámení selhalo", - "testFailedWithReason": "Testovací oznámení selhalo: {{reason}}", - "addRule": "Přidat pravidlo upozornění", - "editRule": "Upravit pravidlo upozornění", - "ruleName": "Název pravidla", - "ruleNameRequired": "Jméno je povinné", - "triggerType": "Spoušť", - "thresholdValue": "Prahová hodnota (%)", - "durationSeconds": "Trvání (sekundy, 0 = okamžitá výstřel)", - "cooldownMinutes": "Doba ochlazování (minuty)", - "channels": "Oznamovací kanály", - "noChannelsHint": "Nejprve přidejte kanály na kartě Kanály", - "ruleSaveFailed": "Uložení pravidla se nezdařilo" + "channelSaveFailed": "Uložení kanálu se nezdařilo" }, "ai": { "title": "Asistent", diff --git a/src/ui/locales/translated/da_DK.json b/src/ui/locales/translated/da_DK.json index e0e6f74a9..5f2677d7d 100644 --- a/src/ui/locales/translated/da_DK.json +++ b/src/ui/locales/translated/da_DK.json @@ -287,7 +287,6 @@ "loading": "Indlæser...", "noData": "Ingen data tilgængelige", "allClear": "Alt klart", - "acknowledgeAlert": "Anerkende", "noPingUrls": "Ingen URL'er konfigureret", "pingLabel": "Mærke", "addPingUrl": "Tilføj URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Historisk CPU-, hukommelses-, disk- eller netværksdiagram for en vært", "widgetHostGridName": "Værtgitter", "widgetHostGridDesc": "Gittervisning af SSH-værtsstatusser", - "widgetAlertFeedName": "Alarmfeed", - "widgetAlertFeedDesc": "Live alarmudløsninger med bekræftelsesstøtte", "widgetPingStatusName": "Ping-status", "widgetPingStatusDesc": "HTTP-pingstatus for en eller flere URL'er", "widgetRecentActivityName": "Seneste aktivitet", @@ -747,7 +744,6 @@ "portForwarding": "Videresendelse", "sftp": "SFTP", "connections": "Forbindelser", - "alerts": "Advarsler", "serial": "Seriel", "keepSideMenuOpen": "Hold menuen åben", "collapseSideMenu": "Skjul menu", @@ -4890,21 +4886,6 @@ "viewHistory": "Vis historik" }, "alerts": { - "tabFirings": "Advarsler", - "tabRules": "Regler", - "tabChannels": "Kanaler", - "noFirings": "Ingen ubekræftede advarsler", - "noRules": "Ingen alarmregler konfigureret", - "noChannels": "Ingen notifikationskanaler konfigureret", - "rulesDesc": "Alarmregler udløser notifikationer", - "channelsDesc": "Hvor alarmmeddelelser sendes", - "acknowledge": "Anerkende", - "ackAll": "Bekræft alle", - "allAcknowledged": "Alle alarmer bekræftet", - "ackFailed": "Kunne ikke bekræfte advarslen", - "ackAllFailed": "Kunne ikke bekræfte alle advarsler", - "showAcknowledged": "Vis alle", - "hideAcknowledged": "Skjul bekræftet", "addChannel": "Tilføj kanal", "editChannel": "Rediger kanal", "channelName": "Navn", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Emne", "ntfyTopicRequired": "Emne er påkrævet", "ntfyToken": "Adgangstoken (valgfrit)", - "channelSaveFailed": "Kanalen kunne ikke gemmes", - "test": "Prøve", - "testSent": "Testnotifikation sendt", - "testFailed": "Testnotifikation mislykkedes", - "testFailedWithReason": "Testnotifikation mislykkedes: {{reason}}", - "addRule": "Tilføj alarmregel", - "editRule": "Rediger alarmregel", - "ruleName": "Regelnavn", - "ruleNameRequired": "Navn er påkrævet", - "triggerType": "Udløser", - "thresholdValue": "Tærskel (%)", - "durationSeconds": "Varighed (sekunder, 0 = affyres øjeblikkeligt)", - "cooldownMinutes": "Nedkølingstid (minutter)", - "channels": "Meddelelseskanaler", - "noChannelsHint": "Tilføj kanaler i fanen Kanaler først", - "ruleSaveFailed": "Reglen kunne ikke gemmes" + "channelSaveFailed": "Kanalen kunne ikke gemmes" }, "ai": { "title": "Assistent", diff --git a/src/ui/locales/translated/de_DE.json b/src/ui/locales/translated/de_DE.json index 400cc4439..ab7d2b71e 100644 --- a/src/ui/locales/translated/de_DE.json +++ b/src/ui/locales/translated/de_DE.json @@ -287,7 +287,6 @@ "loading": "Wird geladen...", "noData": "Keine Daten verfügbar", "allClear": "Alles in Ordnung", - "acknowledgeAlert": "Bestätigen", "noPingUrls": "Keine URLs konfiguriert", "pingLabel": "Bezeichnung", "addPingUrl": "URL hinzufügen", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Historisches CPU-, Arbeitsspeicher-, Festplatten- oder Netzwerkdiagramm für einen Host", "widgetHostGridName": "Host-Raster", "widgetHostGridDesc": "Rasteransicht der SSH-Host-Status", - "widgetAlertFeedName": "Alarm-Feed", - "widgetAlertFeedDesc": "Live-Alarmauslösungen mit Bestätigungsfunktion", "widgetPingStatusName": "Ping-Status", "widgetPingStatusDesc": "HTTP-Ping-Status für eine oder mehrere URLs", "widgetRecentActivityName": "Letzte Aktivität", @@ -747,7 +744,6 @@ "portForwarding": "Weiterleitung", "sftp": "SFTP", "connections": "Verbindungen", - "alerts": "Benachrichtigungen", "serial": "Seriell", "keepSideMenuOpen": "Menü geöffnet lassen", "collapseSideMenu": "Menü ausklappen", @@ -4890,21 +4886,6 @@ "viewHistory": "Verlauf anzeigen" }, "alerts": { - "tabFirings": "Alarme", - "tabRules": "Regeln", - "tabChannels": "Kanäle", - "noFirings": "Keine unbestätigten Alarme", - "noRules": "Keine Alarmregeln konfiguriert", - "noChannels": "Keine Benachrichtigungskanäle konfiguriert", - "rulesDesc": "Alarmregeln lösen Benachrichtigungen aus", - "channelsDesc": "Wohin Alarmbenachrichtigungen gesendet werden", - "acknowledge": "Quittieren", - "ackAll": "Alle quittieren", - "allAcknowledged": "Alle Alarme quittiert", - "ackFailed": "Quittieren des Alarms fehlgeschlagen", - "ackAllFailed": "Quittieren aller Alarme fehlgeschlagen", - "showAcknowledged": "Alle anzeigen", - "hideAcknowledged": "Quittierte ausblenden", "addChannel": "Kanal hinzufügen", "editChannel": "Kanal bearbeiten", "channelName": "Name", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Topic", "ntfyTopicRequired": "Topic ist erforderlich", "ntfyToken": "Zugriffstoken (optional)", - "channelSaveFailed": "Kanal konnte nicht gespeichert werden", - "test": "Test", - "testSent": "Testbenachrichtigung gesendet", - "testFailed": "Testbenachrichtigung fehlgeschlagen", - "testFailedWithReason": "Testbenachrichtigung fehlgeschlagen: {{reason}}", - "addRule": "Alarmregel hinzufügen", - "editRule": "Alarmregel bearbeiten", - "ruleName": "Regelname", - "ruleNameRequired": "Name ist erforderlich", - "triggerType": "Auslöser", - "thresholdValue": "Schwellenwert (%)", - "durationSeconds": "Dauer (Sekunden, 0 = sofort auslösen)", - "cooldownMinutes": "Abklingzeit (Minuten)", - "channels": "Benachrichtigungskanäle", - "noChannelsHint": "Fügen Sie zuerst Kanäle im Tab 'Kanäle' hinzu", - "ruleSaveFailed": "Regel konnte nicht gespeichert werden" + "channelSaveFailed": "Kanal konnte nicht gespeichert werden" }, "ai": { "title": "Assistent", diff --git a/src/ui/locales/translated/el_GR.json b/src/ui/locales/translated/el_GR.json index f7b4561ee..a93621082 100644 --- a/src/ui/locales/translated/el_GR.json +++ b/src/ui/locales/translated/el_GR.json @@ -287,7 +287,6 @@ "loading": "Φόρτωση...", "noData": "Δεν υπάρχουν διαθέσιμα δεδομένα", "allClear": "Ορίζοντας είναι σαφής", - "acknowledgeAlert": "Αναγνωρίζω", "noPingUrls": "Δεν έχουν ρυθμιστεί διευθύνσεις URL", "pingLabel": "Επιγραφή", "addPingUrl": "Προσθήκη διεύθυνσης URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Ιστορικό διάγραμμα CPU, μνήμης, δίσκου ή δικτύου για έναν κεντρικό υπολογιστή", "widgetHostGridName": "Πλέγμα κεντρικού υπολογιστή", "widgetHostGridDesc": "Προβολή πλέγματος των καταστάσεων κεντρικού υπολογιστή SSH", - "widgetAlertFeedName": "Ροή ειδοποιήσεων", - "widgetAlertFeedDesc": "Ενεργοποιήσεις ζωντανών ειδοποιήσεων με υποστήριξη αναγνώρισης", "widgetPingStatusName": "Κατάσταση Ping", "widgetPingStatusDesc": "Κατάσταση ping HTTP για μία ή περισσότερες διευθύνσεις URL", "widgetRecentActivityName": "Πρόσφατη δραστηριότητα", @@ -747,7 +744,6 @@ "portForwarding": "Προώθηση", "sftp": "SFTP", "connections": "Συνδέσεις", - "alerts": "Ειδοποιήσεις", "serial": "Σειράς", "keepSideMenuOpen": "Διατήρηση μενού ανοιχτού", "collapseSideMenu": "Σύμπτυξη μενού", @@ -4890,21 +4886,6 @@ "viewHistory": "Προβολή ιστορικού" }, "alerts": { - "tabFirings": "Ειδοποιήσεις", - "tabRules": "Κανόνες", - "tabChannels": "Κανάλια", - "noFirings": "Δεν υπάρχουν μη επιβεβαιωμένες ειδοποιήσεις", - "noRules": "Δεν έχουν ρυθμιστεί κανόνες ειδοποίησης", - "noChannels": "Δεν έχουν ρυθμιστεί κανάλια ειδοποιήσεων", - "rulesDesc": "Οι κανόνες ειδοποίησης ενεργοποιούν ειδοποιήσεις", - "channelsDesc": "Πού αποστέλλονται ειδοποιήσεις", - "acknowledge": "Αναγνωρίζω", - "ackAll": "Επιβεβαίωση όλων", - "allAcknowledged": "Όλες οι ειδοποιήσεις επιβεβαιώθηκαν", - "ackFailed": "Αποτυχία επιβεβαίωσης ειδοποίησης", - "ackAllFailed": "Αποτυχία επιβεβαίωσης όλων των ειδοποιήσεων", - "showAcknowledged": "Εμφάνιση όλων", - "hideAcknowledged": "Απόκρυψη επικυρωμένων", "addChannel": "Προσθήκη καναλιού", "editChannel": "Επεξεργασία καναλιού", "channelName": "Ονομα", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Θέμα", "ntfyTopicRequired": "Το θέμα είναι υποχρεωτικό", "ntfyToken": "Διακριτικό πρόσβασης (προαιρετικό)", - "channelSaveFailed": "Η αποθήκευση του καναλιού απέτυχε", - "test": "Δοκιμή", - "testSent": "Αποστολή ειδοποίησης δοκιμής", - "testFailed": "Η ειδοποίηση δοκιμής απέτυχε.", - "testFailedWithReason": "Η ειδοποίηση δοκιμής απέτυχε: {{reason}}", - "addRule": "Προσθήκη κανόνα ειδοποίησης", - "editRule": "Επεξεργασία κανόνα ειδοποίησης", - "ruleName": "Όνομα κανόνα", - "ruleNameRequired": "Απαιτείται όνομα", - "triggerType": "Σκανδάλη", - "thresholdValue": "Όριο (%)", - "durationSeconds": "Διάρκεια (δευτερόλεπτα, 0 = άμεση πυροδότηση)", - "cooldownMinutes": "Χρόνος αναμονής (λεπτά)", - "channels": "Κανάλια ειδοποιήσεων", - "noChannelsHint": "Προσθέστε πρώτα κανάλια στην καρτέλα Κανάλια", - "ruleSaveFailed": "Η αποθήκευση του κανόνα απέτυχε" + "channelSaveFailed": "Η αποθήκευση του καναλιού απέτυχε" }, "ai": { "title": "Βοηθός", diff --git a/src/ui/locales/translated/es_ES.json b/src/ui/locales/translated/es_ES.json index f795c4b42..847b5c125 100644 --- a/src/ui/locales/translated/es_ES.json +++ b/src/ui/locales/translated/es_ES.json @@ -287,7 +287,6 @@ "loading": "Cargando...", "noData": "Sin datos disponibles", "allClear": "Todo correcto", - "acknowledgeAlert": "Reconocer", "noPingUrls": "No hay URLs configuradas", "pingLabel": "Etiqueta", "addPingUrl": "Añadir URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Gráfico histórico de CPU, memoria, disco o red para un host", "widgetHostGridName": "Cuadrícula de hosts", "widgetHostGridDesc": "Vista en cuadrícula de los estados de los hosts SSH", - "widgetAlertFeedName": "Feed de alertas", - "widgetAlertFeedDesc": "Alertas en tiempo real con soporte para reconocimiento", "widgetPingStatusName": "Estado de ping", "widgetPingStatusDesc": "Estado de ping HTTP para una o más URLs", "widgetRecentActivityName": "Actividad reciente", @@ -747,7 +744,6 @@ "portForwarding": "Reenvío", "sftp": "SFTP", "connections": "Conexiones", - "alerts": "Alertas", "serial": "Serial", "keepSideMenuOpen": "Mantener el menú abierto", "collapseSideMenu": "Contraer menú", @@ -4890,21 +4886,6 @@ "viewHistory": "Ver Historial" }, "alerts": { - "tabFirings": "Alertas", - "tabRules": "Reglas", - "tabChannels": "Canales", - "noFirings": "No hay alertas sin reconocer", - "noRules": "No hay reglas de alerta configuradas", - "noChannels": "No hay canales de notificación configurados", - "rulesDesc": "Las reglas de alerta disparan notificaciones", - "channelsDesc": "Dónde se envían las notificaciones de alerta", - "acknowledge": "Reconocer", - "ackAll": "Reconocer todo", - "allAcknowledged": "Todas las alertas reconocidas", - "ackFailed": "Error al reconocer la alerta", - "ackAllFailed": "Error al reconocer todas las alertas", - "showAcknowledged": "Mostrar todas", - "hideAcknowledged": "Ocultar reconocidas", "addChannel": "Añadir canal", "editChannel": "Editar canal", "channelName": "Nombre", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Tema", "ntfyTopicRequired": "El tema es obligatorio", "ntfyToken": "Token de acceso (opcional)", - "channelSaveFailed": "No se pudo guardar el canal", - "test": "Probar", - "testSent": "Notificación de prueba enviada", - "testFailed": "La notificación de prueba falló", - "testFailedWithReason": "La notificación de prueba falló: {{reason}}", - "addRule": "Añadir regla de alerta", - "editRule": "Editar regla de alerta", - "ruleName": "Nombre de la regla", - "ruleNameRequired": "El nombre es obligatorio", - "triggerType": "Disparador", - "thresholdValue": "Umbral (%)", - "durationSeconds": "Duración (segundos, 0 = disparar inmediatamente)", - "cooldownMinutes": "Tiempo de espera (minutos)", - "channels": "Canales de notificación", - "noChannelsHint": "Añade primero canales en la pestaña Canales", - "ruleSaveFailed": "No se pudo guardar la regla" + "channelSaveFailed": "No se pudo guardar el canal" }, "ai": { "title": "Asistente", diff --git a/src/ui/locales/translated/fi_FI.json b/src/ui/locales/translated/fi_FI.json index 171bcf9e0..35614f24f 100644 --- a/src/ui/locales/translated/fi_FI.json +++ b/src/ui/locales/translated/fi_FI.json @@ -287,7 +287,6 @@ "loading": "Ladataan...", "noData": "Ei tietoja saatavilla", "allClear": "Kaikki selvää", - "acknowledgeAlert": "Kuittaa", "noPingUrls": "Ei määritettyjä URL-osoitteita", "pingLabel": "Tarra", "addPingUrl": "Lisää URL-osoite", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Isännän historiallinen suorittimen, muistin, levyn tai verkon kaavio", "widgetHostGridName": "Isäntäverkko", "widgetHostGridDesc": "SSH-isäntätilojen ruudukkonäkymä", - "widgetAlertFeedName": "Hälytyssyöte", - "widgetAlertFeedDesc": "Reaaliaikaiset hälytyslaukaisut kuittaustuella", "widgetPingStatusName": "Ping-tila", "widgetPingStatusDesc": "Yhden tai useamman URL-osoitteen HTTP-ping-tila", "widgetRecentActivityName": "Viimeaikaiset toiminnot", @@ -747,7 +744,6 @@ "portForwarding": "Edelleenlähetys", "sftp": "SFTP", "connections": "Yhteydet", - "alerts": "Hälytykset", "serial": "Sarjanumero", "keepSideMenuOpen": "Pidä valikko auki", "collapseSideMenu": "Pienennä valikko", @@ -4890,21 +4886,6 @@ "viewHistory": "Näytä historia" }, "alerts": { - "tabFirings": "Hälytykset", - "tabRules": "Säännöt", - "tabChannels": "Kanavat", - "noFirings": "Ei kuittaamattomia hälytyksiä", - "noRules": "Ei määritettyjä hälytyssääntöjä", - "noChannels": "Ei määritettyjä ilmoituskanavia", - "rulesDesc": "Hälytyssäännöt käynnistävät ilmoituksia", - "channelsDesc": "Minne hälytysilmoitukset lähetetään", - "acknowledge": "Kuittaa", - "ackAll": "Ack All", - "allAcknowledged": "Kaikki hälytykset kuitattu", - "ackFailed": "Hälytyksen kuittaus epäonnistui", - "ackAllFailed": "Kaikkien hälytysten kuittaus epäonnistui", - "showAcknowledged": "Näytä kaikki", - "hideAcknowledged": "Piilota kuitattu", "addChannel": "Lisää kanava", "editChannel": "Muokkaa kanavaa", "channelName": "Nimi", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Aihe", "ntfyTopicRequired": "Aihe on pakollinen", "ntfyToken": "Käyttöoikeustunnus (valinnainen)", - "channelSaveFailed": "Kanavan tallentaminen epäonnistui", - "test": "Testata", - "testSent": "Testi-ilmoitus lähetetty", - "testFailed": "Testi-ilmoitus epäonnistui", - "testFailedWithReason": "Testi-ilmoitus epäonnistui: {{reason}}", - "addRule": "Lisää hälytyssääntö", - "editRule": "Muokkaa hälytyssääntöä", - "ruleName": "Säännön nimi", - "ruleNameRequired": "Nimi on pakollinen", - "triggerType": "Laukaista", - "thresholdValue": "Kynnysarvo (%)", - "durationSeconds": "Kesto (sekuntia, 0 = käynnistyy välittömästi)", - "cooldownMinutes": "Jäähdyttelyaika (minuuttia)", - "channels": "Ilmoituskanavat", - "noChannelsHint": "Lisää kanavat ensin Kanavat-välilehdellä", - "ruleSaveFailed": "Säännön tallentaminen epäonnistui" + "channelSaveFailed": "Kanavan tallentaminen epäonnistui" }, "ai": { "title": "Assistentti", diff --git a/src/ui/locales/translated/fr_FR.json b/src/ui/locales/translated/fr_FR.json index cae0e6bda..7b4edda39 100644 --- a/src/ui/locales/translated/fr_FR.json +++ b/src/ui/locales/translated/fr_FR.json @@ -287,7 +287,6 @@ "loading": "Chargement…", "noData": "Aucune donnée disponible", "allClear": "Aucune alerte", - "acknowledgeAlert": "Acquitter", "noPingUrls": "Aucune URL configurée", "pingLabel": "Libellé", "addPingUrl": "Ajouter une URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Graphique historique CPU, mémoire, disque ou réseau pour un hôte", "widgetHostGridName": "Grille d'hôtes", "widgetHostGridDesc": "Vue en grille des statuts des hôtes SSH", - "widgetAlertFeedName": "Flux d'alertes", - "widgetAlertFeedDesc": "Déclenchements d'alertes en direct avec acquittement", "widgetPingStatusName": "Statut du ping", "widgetPingStatusDesc": "Statut du ping HTTP pour une ou plusieurs URL", "widgetRecentActivityName": "Activité récente", @@ -747,7 +744,6 @@ "portForwarding": "Expéditeur", "sftp": "SFTP", "connections": "Connexions", - "alerts": "Alertes", "serial": "Série", "keepSideMenuOpen": "Garder le menu ouvert", "collapseSideMenu": "Réduire le menu", @@ -4890,21 +4886,6 @@ "viewHistory": "Voir l'historique" }, "alerts": { - "tabFirings": "Alertes", - "tabRules": "Règles", - "tabChannels": "Canaux", - "noFirings": "Aucune alerte non acquittée", - "noRules": "Aucune règle d'alerte configurée", - "noChannels": "Aucun canal de notification configuré", - "rulesDesc": "Les règles d'alerte déclenchent des notifications", - "channelsDesc": "Où les notifications d'alerte sont envoyées", - "acknowledge": "Acquitter", - "ackAll": "Tout acquitter", - "allAcknowledged": "Toutes les alertes acquittées", - "ackFailed": "Échec de l'acquittement de l'alerte", - "ackAllFailed": "Échec de l'acquittement de toutes les alertes", - "showAcknowledged": "Tout afficher", - "hideAcknowledged": "Masquer les acquittées", "addChannel": "Ajouter un canal", "editChannel": "Modifier le canal", "channelName": "Nom", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Sujet", "ntfyTopicRequired": "Le sujet est obligatoire", "ntfyToken": "Jeton d'accès (facultatif)", - "channelSaveFailed": "Échec de l'enregistrement du canal", - "test": "Tester", - "testSent": "Notification de test envoyée", - "testFailed": "Échec de la notification de test", - "testFailedWithReason": "Échec de la notification de test : {{reason}}", - "addRule": "Ajouter une règle d'alerte", - "editRule": "Modifier la règle d'alerte", - "ruleName": "Nom de la règle", - "ruleNameRequired": "Le nom est obligatoire", - "triggerType": "Déclencheur", - "thresholdValue": "Seuil (%)", - "durationSeconds": "Durée (secondes, 0 = déclenchement immédiat)", - "cooldownMinutes": "Temporisation (minutes)", - "channels": "Canaux de notification", - "noChannelsHint": "Ajoutez d'abord des canaux dans l'onglet Canaux", - "ruleSaveFailed": "Échec de l'enregistrement de la règle" + "channelSaveFailed": "Échec de l'enregistrement du canal" }, "ai": { "title": "Assistant", diff --git a/src/ui/locales/translated/he_IL.json b/src/ui/locales/translated/he_IL.json index d41789d7d..e44f77f7b 100644 --- a/src/ui/locales/translated/he_IL.json +++ b/src/ui/locales/translated/he_IL.json @@ -287,7 +287,6 @@ "loading": "טְעִינָה...", "noData": "אין נתונים זמינים", "allClear": "הכל ברור", - "acknowledgeAlert": "לְהוֹדוֹת", "noPingUrls": "לא הוגדרו כתובות URL", "pingLabel": "מַדבֵּקָה", "addPingUrl": "הוסף כתובת URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "תרשים היסטורי של מעבד, זיכרון, דיסק או רשת עבור מחשב מארח", "widgetHostGridName": "רשת מארחים", "widgetHostGridDesc": "תצוגת רשת של סטטוסי מארח SSH", - "widgetAlertFeedName": "הזנת התראות", - "widgetAlertFeedDesc": "ירי התרעה בזמן אמת עם תמיכה באישור", "widgetPingStatusName": "סטטוס פינג", "widgetPingStatusDesc": "סטטוס פינג HTTP עבור כתובת URL אחת או יותר", "widgetRecentActivityName": "פעילות אחרונה", @@ -747,7 +744,6 @@ "portForwarding": "העברה", "sftp": "SFTP", "connections": "חיבורים", - "alerts": "התראות", "serial": "סִדרָתִי", "keepSideMenuOpen": "שמור את התפריט פתוח", "collapseSideMenu": "כווץ תפריט", @@ -4890,21 +4886,6 @@ "viewHistory": "הצג היסטוריה" }, "alerts": { - "tabFirings": "התראות", - "tabRules": "כללים", - "tabChannels": "ערוצים", - "noFirings": "אין התראות שלא אושרו", - "noRules": "לא הוגדרו כללי התראות", - "noChannels": "לא הוגדרו ערוצי התראות", - "rulesDesc": "כללי התראות מפעילים התראות", - "channelsDesc": "לאן נשלחות התראות", - "acknowledge": "לְהוֹדוֹת", - "ackAll": "אשר הכל", - "allAcknowledged": "כל ההתראות אושרו", - "ackFailed": "נכשל אישור ההתראה", - "ackAllFailed": "נכשל אישור כל ההתראות", - "showAcknowledged": "הצג הכל", - "hideAcknowledged": "הסתר אישור", "addChannel": "הוסף ערוץ", "editChannel": "עריכת ערוץ", "channelName": "שֵׁם", @@ -4917,22 +4898,7 @@ "ntfyTopic": "נוֹשֵׂא", "ntfyTopicRequired": "נושא נדרש", "ntfyToken": "אסימון גישה (אופציונלי)", - "channelSaveFailed": "שמירת הערוץ נכשלה", - "test": "מִבְחָן", - "testSent": "הודעת בדיקה נשלחה", - "testFailed": "הודעת הבדיקה נכשלה", - "testFailedWithReason": "הודעת הבדיקה נכשלה: {{reason}}", - "addRule": "הוסף כלל התראה", - "editRule": "עריכת כלל התראה", - "ruleName": "שם הכלל", - "ruleNameRequired": "שם נדרש", - "triggerType": "לְהַפְעִיל", - "thresholdValue": "סף (%)", - "durationSeconds": "משך (שניות, 0 = ירי מיידי)", - "cooldownMinutes": "זמן קירור (דקות)", - "channels": "ערוצי התראות", - "noChannelsHint": "הוסף תחילה ערוצים בכרטיסייה ערוצים", - "ruleSaveFailed": "שמירת הכלל נכשלה" + "channelSaveFailed": "שמירת הערוץ נכשלה" }, "ai": { "title": "עוֹזֵר", diff --git a/src/ui/locales/translated/hi_IN.json b/src/ui/locales/translated/hi_IN.json index 67a948c9a..a77231e62 100644 --- a/src/ui/locales/translated/hi_IN.json +++ b/src/ui/locales/translated/hi_IN.json @@ -287,7 +287,6 @@ "loading": "लोड हो रहा है...", "noData": "कोई डेटा उपलब्ध नहीं", "allClear": "सब ठीक है", - "acknowledgeAlert": "स्वीकार करें", "noPingUrls": "कोई URL कॉन्फ़िगर नहीं किया गया", "pingLabel": "लेबल", "addPingUrl": "URL जोड़ें", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "होस्ट के लिए ऐतिहासिक CPU, मेमोरी, डिस्क या नेटवर्क चार्ट", "widgetHostGridName": "होस्ट ग्रिड", "widgetHostGridDesc": "SSH होस्ट की स्थितियों का ग्रिड दृश्य", - "widgetAlertFeedName": "अलर्ट फीड", - "widgetAlertFeedDesc": "स्वीकृति सहित लाइव अलर्ट फायरिंग", "widgetPingStatusName": "पिंग स्थिति", "widgetPingStatusDesc": "एक या अधिक URLs के लिए HTTP पिंग स्थिति", "widgetRecentActivityName": "हाल की गतिविधि", @@ -747,7 +744,6 @@ "portForwarding": "अग्रेषित करना", "sftp": "एसएफटीपी", "connections": "कनेक्शन्स", - "alerts": "अलर्ट्स", "serial": "सीरियल", "keepSideMenuOpen": "मेनू खुला रखें", "collapseSideMenu": "मेनू को छोटा करें", @@ -4890,21 +4886,6 @@ "viewHistory": "इतिहास देखें" }, "alerts": { - "tabFirings": "अलर्ट", - "tabRules": "नियम", - "tabChannels": "चैनल", - "noFirings": "कोई अपुष्ट अलर्ट नहीं", - "noRules": "कोई अलर्ट नियम कॉन्फ़िगर नहीं", - "noChannels": "कोई सूचना चैनल कॉन्फ़िगर नहीं", - "rulesDesc": "अलर्ट नियम सूचनाएं ट्रिगर करते हैं", - "channelsDesc": "जहां अलर्ट सूचनाएं भेजी जाती हैं", - "acknowledge": "पुष्टि करें", - "ackAll": "सभी की पुष्टि करें", - "allAcknowledged": "सभी अलर्ट की पुष्टि हो गई", - "ackFailed": "अलर्ट की पुष्टि करने में विफल", - "ackAllFailed": "सभी अलर्ट की पुष्टि करने में विफल", - "showAcknowledged": "सभी दिखाएं", - "hideAcknowledged": "पुष्टि किए गए छिपाएं", "addChannel": "चैनल जोड़ें", "editChannel": "चैनल संपादित करें", "channelName": "नाम", @@ -4917,22 +4898,7 @@ "ntfyTopic": "विषय", "ntfyTopicRequired": "विषय आवश्यक है", "ntfyToken": "एक्सेस टोकन (वैकल्पिक)", - "channelSaveFailed": "चैनल सहेजने में विफल", - "test": "परीक्षण", - "testSent": "परीक्षण सूचना भेजी गई", - "testFailed": "परीक्षण सूचना विफल", - "testFailedWithReason": "परीक्षण अधिसूचना विफल: {{reason}}", - "addRule": "अलर्ट नियम जोड़ें", - "editRule": "अलर्ट नियम संपादित करें", - "ruleName": "नियम नाम", - "ruleNameRequired": "नाम आवश्यक है", - "triggerType": "ट्रिगर", - "thresholdValue": "सीमा (%)", - "durationSeconds": "अवधि (सेकंड, 0 = तुरंत सक्रिय करें)", - "cooldownMinutes": "कूलडाउन (मिनट)", - "channels": "अधिसूचना चैनल", - "noChannelsHint": "पहले चैनल टैब में चैनल जोड़ें", - "ruleSaveFailed": "नियम सहेजने में विफल" + "channelSaveFailed": "चैनल सहेजने में विफल" }, "ai": { "title": "सहायक", diff --git a/src/ui/locales/translated/hu_HU.json b/src/ui/locales/translated/hu_HU.json index 043a2fde4..7d75377dc 100644 --- a/src/ui/locales/translated/hu_HU.json +++ b/src/ui/locales/translated/hu_HU.json @@ -287,7 +287,6 @@ "loading": "Terhelés...", "noData": "Nincsenek elérhető adatok", "allClear": "Minden tiszta", - "acknowledgeAlert": "Elismerés", "noPingUrls": "Nincsenek konfigurált URL-ek", "pingLabel": "Címke", "addPingUrl": "URL hozzáadása", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Egy gazdagép CPU-, memória-, lemez- vagy hálózati előzménydiagramja", "widgetHostGridName": "Host Grid", "widgetHostGridDesc": "SSH-gazdagépek állapotainak rácsnézete", - "widgetAlertFeedName": "Értesítési hírcsatorna", - "widgetAlertFeedDesc": "Élő riasztási tüzelések nyugtázási támogatással", "widgetPingStatusName": "Ping állapot", "widgetPingStatusDesc": "HTTP ping állapot egy vagy több URL-hez", "widgetRecentActivityName": "Legutóbbi tevékenységek", @@ -747,7 +744,6 @@ "portForwarding": "Szállítmányozás", "sftp": "SFTP", "connections": "Kapcsolatok", - "alerts": "Riasztások", "serial": "Sorozatszám", "keepSideMenuOpen": "Menü nyitva tartása", "collapseSideMenu": "Menü összecsukása", @@ -4890,21 +4886,6 @@ "viewHistory": "Előzmények megtekintése" }, "alerts": { - "tabFirings": "Riasztások", - "tabRules": "Szabályok", - "tabChannels": "Csatornák", - "noFirings": "Nincsenek nyugtázatlan riasztások", - "noRules": "Nincsenek riasztási szabályok konfigurálva", - "noChannels": "Nincsenek értesítési csatornák konfigurálva", - "rulesDesc": "Riasztási szabályok aktiválják az értesítéseket", - "channelsDesc": "Hová küldik a riasztási értesítéseket", - "acknowledge": "Elismerés", - "ackAll": "Mindent elfogad", - "allAcknowledged": "Minden riasztás nyugtázva", - "ackFailed": "Nem sikerült visszaigazolni a riasztást", - "ackAllFailed": "Nem sikerült nyugtázni az összes riasztást", - "showAcknowledged": "Összes megjelenítése", - "hideAcknowledged": "Elrejtés Elfogadva", "addChannel": "Csatorna hozzáadása", "editChannel": "Csatorna szerkesztése", "channelName": "Név", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Téma", "ntfyTopicRequired": "A téma megadása kötelező", "ntfyToken": "Hozzáférési token (opcionális)", - "channelSaveFailed": "Nem sikerült menteni a csatornát", - "test": "Teszt", - "testSent": "Tesztértesítés elküldve", - "testFailed": "Tesztértesítés sikertelen", - "testFailedWithReason": "Tesztértesítés sikertelen: {{reason}}", - "addRule": "Riasztási szabály hozzáadása", - "editRule": "Riasztási szabály szerkesztése", - "ruleName": "Szabály neve", - "ruleNameRequired": "Név megadása kötelező", - "triggerType": "Trigger", - "thresholdValue": "Küszöbérték (%)", - "durationSeconds": "Időtartam (másodperc, 0 = azonnali aktiválás)", - "cooldownMinutes": "Lehűlési idő (perc)", - "channels": "Értesítési csatornák", - "noChannelsHint": "Először adj hozzá csatornákat a Csatornák lapon", - "ruleSaveFailed": "Nem sikerült menteni a szabályt" + "channelSaveFailed": "Nem sikerült menteni a csatornát" }, "ai": { "title": "Helyettes", diff --git a/src/ui/locales/translated/id_ID.json b/src/ui/locales/translated/id_ID.json index cdb7f6056..63a065d5f 100644 --- a/src/ui/locales/translated/id_ID.json +++ b/src/ui/locales/translated/id_ID.json @@ -287,7 +287,6 @@ "loading": "Memuat...", "noData": "Tidak ada data yang tersedia", "allClear": "Semuanya aman.", - "acknowledgeAlert": "Mengakui", "noPingUrls": "Tidak ada URL yang dikonfigurasi", "pingLabel": "Label", "addPingUrl": "Tambahkan URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Grafik historis CPU, memori, disk, atau jaringan untuk sebuah host.", "widgetHostGridName": "Jaringan Host", "widgetHostGridDesc": "Tampilan grid status host SSH", - "widgetAlertFeedName": "Umpan Peringatan", - "widgetAlertFeedDesc": "Peringatan penembakan langsung dengan dukungan konfirmasi.", "widgetPingStatusName": "Status Ping", "widgetPingStatusDesc": "Status ping HTTP untuk satu atau lebih URL", "widgetRecentActivityName": "Aktivitas Terkini", @@ -747,7 +744,6 @@ "portForwarding": "Meneruskan", "sftp": "SFTP", "connections": "Koneksi", - "alerts": "Peringatan", "serial": "Serial", "keepSideMenuOpen": "Biarkan Menu Tetap Terbuka", "collapseSideMenu": "Ciutkan Menu", @@ -4890,21 +4886,6 @@ "viewHistory": "Lihat Riwayat" }, "alerts": { - "tabFirings": "Peringatan", - "tabRules": "Aturan", - "tabChannels": "Saluran", - "noFirings": "Tidak ada peringatan yang belum diakui", - "noRules": "Tidak ada aturan peringatan yang dikonfigurasi.", - "noChannels": "Tidak ada saluran notifikasi yang dikonfigurasi.", - "rulesDesc": "Aturan peringatan memicu notifikasi.", - "channelsDesc": "Di mana notifikasi peringatan dikirim", - "acknowledge": "Mengakui", - "ackAll": "Akui semuanya", - "allAcknowledged": "Semua peringatan telah diterima.", - "ackFailed": "Gagal menanggapi peringatan", - "ackAllFailed": "Gagal menanggapi semua peringatan", - "showAcknowledged": "Tampilkan Semua", - "hideAcknowledged": "Sembunyikan Terakui", "addChannel": "Tambahkan Saluran", "editChannel": "Edit Saluran", "channelName": "Nama", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Topik", "ntfyTopicRequired": "Topik wajib diisi", "ntfyToken": "Token Akses (opsional)", - "channelSaveFailed": "Gagal menyimpan saluran", - "test": "Tes", - "testSent": "Notifikasi pengujian telah dikirim.", - "testFailed": "Notifikasi pengujian gagal", - "testFailedWithReason": "Notifikasi pengujian gagal: {{reason}}", - "addRule": "Tambahkan Aturan Peringatan", - "editRule": "Edit Aturan Peringatan", - "ruleName": "Nama Aturan", - "ruleNameRequired": "Nama wajib diisi.", - "triggerType": "Pemicu", - "thresholdValue": "Ambang batas (%)", - "durationSeconds": "Durasi (detik, 0 = tembak segera)", - "cooldownMinutes": "Waktu pendinginan (menit)", - "channels": "Saluran Pemberitahuan", - "noChannelsHint": "Tambahkan saluran di tab Saluran terlebih dahulu.", - "ruleSaveFailed": "Gagal menyimpan aturan" + "channelSaveFailed": "Gagal menyimpan saluran" }, "ai": { "title": "Asisten", diff --git a/src/ui/locales/translated/it_IT.json b/src/ui/locales/translated/it_IT.json index 879dfd3ae..91778c2dc 100644 --- a/src/ui/locales/translated/it_IT.json +++ b/src/ui/locales/translated/it_IT.json @@ -287,7 +287,6 @@ "loading": "Caricamento...", "noData": "Nessun dato disponibile", "allClear": "Tutto a posto", - "acknowledgeAlert": "Riconosci", "noPingUrls": "Nessun URL configurato", "pingLabel": "Etichetta", "addPingUrl": "Aggiungi URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Grafico storico di CPU, memoria, disco o rete per un host", "widgetHostGridName": "Griglia host", "widgetHostGridDesc": "Vista a griglia degli stati degli host SSH", - "widgetAlertFeedName": "Feed degli avvisi", - "widgetAlertFeedDesc": "Avvisi in tempo reale con supporto di riconoscimento", "widgetPingStatusName": "Stato ping", "widgetPingStatusDesc": "Stato del ping HTTP per uno o più URL", "widgetRecentActivityName": "Attività recente", @@ -747,7 +744,6 @@ "portForwarding": "Inoltro", "sftp": "SFTP", "connections": "Connessioni", - "alerts": "Avvisi", "serial": "Seriale", "keepSideMenuOpen": "Mantieni il menu aperto", "collapseSideMenu": "Comprimi menu", @@ -4890,21 +4886,6 @@ "viewHistory": "Visualizza cronologia" }, "alerts": { - "tabFirings": "Avvisi", - "tabRules": "Regole", - "tabChannels": "Canali", - "noFirings": "Nessun avviso non confermato", - "noRules": "Nessuna regola di avviso configurata", - "noChannels": "Nessun canale di notifica configurato", - "rulesDesc": "Le regole di avviso attivano le notifiche", - "channelsDesc": "Dove vengono inviate le notifiche di avviso", - "acknowledge": "Conferma", - "ackAll": "Conferma tutto", - "allAcknowledged": "Tutti gli avvisi confermati", - "ackFailed": "Conferma dell'avviso non riuscita", - "ackAllFailed": "Conferma di tutti gli avvisi non riuscita", - "showAcknowledged": "Mostra tutti", - "hideAcknowledged": "Nascondi confermati", "addChannel": "Aggiungi canale", "editChannel": "Modifica canale", "channelName": "Nome", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Argomento", "ntfyTopicRequired": "Argomento obbligatorio", "ntfyToken": "Token di accesso (facoltativo)", - "channelSaveFailed": "Salvataggio del canale non riuscito", - "test": "Test", - "testSent": "Notifica di test inviata", - "testFailed": "Notifica di test fallita", - "testFailedWithReason": "Notifica di prova non riuscita: {{reason}}", - "addRule": "Aggiungi regola di avviso", - "editRule": "Modifica regola di avviso", - "ruleName": "Nome regola", - "ruleNameRequired": "Nome obbligatorio", - "triggerType": "Trigger", - "thresholdValue": "Soglia (%)", - "durationSeconds": "Durata (secondi, 0 = attiva immediatamente)", - "cooldownMinutes": "Cooldown (minuti)", - "channels": "Canali di notifica", - "noChannelsHint": "Aggiungi prima i canali nella scheda Canali", - "ruleSaveFailed": "Salvataggio della regola non riuscito" + "channelSaveFailed": "Salvataggio del canale non riuscito" }, "ai": { "title": "Assistente", diff --git a/src/ui/locales/translated/ja_JP.json b/src/ui/locales/translated/ja_JP.json index 599f85c99..abcf6d7b4 100644 --- a/src/ui/locales/translated/ja_JP.json +++ b/src/ui/locales/translated/ja_JP.json @@ -287,7 +287,6 @@ "loading": "読み込み中...", "noData": "利用可能なデータはありません", "allClear": "すべて正常", - "acknowledgeAlert": "確認", "noPingUrls": "URLが設定されていません", "pingLabel": "ラベル", "addPingUrl": "URLを追加", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "ホストのCPU、メモリ、ディスク、またはネットワークの履歴チャート", "widgetHostGridName": "ホストグリッド", "widgetHostGridDesc": "SSHホストステータスのグリッドビュー", - "widgetAlertFeedName": "アラートフィード", - "widgetAlertFeedDesc": "確認機能付きのライブアラート通知", "widgetPingStatusName": "Pingステータス", "widgetPingStatusDesc": "1つ以上のURLのHTTP pingステータス", "widgetRecentActivityName": "最近のアクティビティ", @@ -747,7 +744,6 @@ "portForwarding": "転送", "sftp": "SFTP", "connections": "接続", - "alerts": "アラート", "serial": "シリアル", "keepSideMenuOpen": "メニューを開いたままにする", "collapseSideMenu": "メニューを折りたたむ", @@ -4890,21 +4886,6 @@ "viewHistory": "履歴を表示" }, "alerts": { - "tabFirings": "アラート", - "tabRules": "ルール", - "tabChannels": "チャンネル", - "noFirings": "未確認のアラートはありません", - "noRules": "アラートルールが設定されていません", - "noChannels": "通知チャンネルが設定されていません", - "rulesDesc": "アラートルールは通知をトリガーします", - "channelsDesc": "アラート通知の送信先です", - "acknowledge": "確認", - "ackAll": "すべて確認", - "allAcknowledged": "すべてのアラートが確認済みです", - "ackFailed": "アラートの確認に失敗しました", - "ackAllFailed": "すべてのアラートの確認に失敗しました", - "showAcknowledged": "すべて表示", - "hideAcknowledged": "確認済みを非表示", "addChannel": "チャンネルを追加", "editChannel": "チャンネルを編集", "channelName": "名前", @@ -4917,22 +4898,7 @@ "ntfyTopic": "トピック", "ntfyTopicRequired": "トピックは必須です", "ntfyToken": "アクセストークン(任意)", - "channelSaveFailed": "チャンネルの保存に失敗しました", - "test": "テスト", - "testSent": "テスト通知を送信しました", - "testFailed": "テスト通知に失敗しました", - "testFailedWithReason": "テスト通知が失敗しました: {{reason}}", - "addRule": "アラートルールを追加", - "editRule": "アラートルールを編集", - "ruleName": "ルール名", - "ruleNameRequired": "ルール名は必須です", - "triggerType": "トリガー", - "thresholdValue": "しきい値 (%)", - "durationSeconds": "継続時間(秒、0は即時発火)", - "cooldownMinutes": "クールダウン(分)", - "channels": "通知チャンネル", - "noChannelsHint": "先にチャンネルタブでチャンネルを追加してください", - "ruleSaveFailed": "ルールの保存に失敗しました" + "channelSaveFailed": "チャンネルの保存に失敗しました" }, "ai": { "title": "アシスタント", diff --git a/src/ui/locales/translated/ko_KR.json b/src/ui/locales/translated/ko_KR.json index 71bc8271f..aca06c380 100644 --- a/src/ui/locales/translated/ko_KR.json +++ b/src/ui/locales/translated/ko_KR.json @@ -287,7 +287,6 @@ "loading": "로딩 중...", "noData": "데이터 없음", "allClear": "모두 정상", - "acknowledgeAlert": "확인", "noPingUrls": "구성된 URL 없음", "pingLabel": "레이블", "addPingUrl": "URL 추가", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "호스트의 CPU, 메모리, 디스크, 네트워크 기록 차트", "widgetHostGridName": "호스트 그리드", "widgetHostGridDesc": "SSH 호스트 상태 그리드 뷰", - "widgetAlertFeedName": "알림 피드", - "widgetAlertFeedDesc": "실시간 알림 및 확인 지원", "widgetPingStatusName": "Ping 상태", "widgetPingStatusDesc": "하나 이상의 URL에 대한 HTTP 핑 상태", "widgetRecentActivityName": "최근 활동", @@ -747,7 +744,6 @@ "portForwarding": "전송", "sftp": "SFTP", "connections": "연결", - "alerts": "알림", "serial": "시리얼", "keepSideMenuOpen": "메뉴를 열어 두세요", "collapseSideMenu": "메뉴 접기", @@ -4890,21 +4886,6 @@ "viewHistory": "기록 보기" }, "alerts": { - "tabFirings": "알림", - "tabRules": "규칙", - "tabChannels": "채널", - "noFirings": "미확인 알림 없음", - "noRules": "구성된 알림 규칙 없음", - "noChannels": "구성된 알림 채널 없음", - "rulesDesc": "알림 규칙은 알림을 트리거합니다", - "channelsDesc": "알림이 전송되는 위치", - "acknowledge": "확인", - "ackAll": "모두 확인", - "allAcknowledged": "모든 알림 확인됨", - "ackFailed": "알림 확인 실패", - "ackAllFailed": "모든 알림 확인 실패", - "showAcknowledged": "모두 표시", - "hideAcknowledged": "확인된 항목 숨기기", "addChannel": "채널 추가", "editChannel": "채널 편집", "channelName": "이름", @@ -4917,22 +4898,7 @@ "ntfyTopic": "토픽", "ntfyTopicRequired": "토픽은 필수입니다", "ntfyToken": "액세스 토큰 (선택 사항)", - "channelSaveFailed": "채널 저장에 실패했습니다", - "test": "테스트", - "testSent": "테스트 알림이 전송되었습니다", - "testFailed": "테스트 알림 전송에 실패했습니다", - "testFailedWithReason": "테스트 알림 실패: {{reason}}", - "addRule": "알람 규칙 추가", - "editRule": "알람 규칙 편집", - "ruleName": "규칙 이름", - "ruleNameRequired": "이름은 필수입니다", - "triggerType": "트리거", - "thresholdValue": "임계값 (%)", - "durationSeconds": "지속 시간 (초, 0 = 즉시 발생)", - "cooldownMinutes": "쿨다운 (분)", - "channels": "알림 채널", - "noChannelsHint": "먼저 채널 탭에서 채널을 추가하세요", - "ruleSaveFailed": "규칙 저장에 실패했습니다" + "channelSaveFailed": "채널 저장에 실패했습니다" }, "ai": { "title": "어시스턴트", diff --git a/src/ui/locales/translated/nl_NL.json b/src/ui/locales/translated/nl_NL.json index d457cd916..570424f95 100644 --- a/src/ui/locales/translated/nl_NL.json +++ b/src/ui/locales/translated/nl_NL.json @@ -287,7 +287,6 @@ "loading": "Laden...", "noData": "Geen gegevens beschikbaar", "allClear": "Alles in orde", - "acknowledgeAlert": "Erkennen", "noPingUrls": "Geen URL's geconfigureerd", "pingLabel": "Label", "addPingUrl": "URL toevoegen", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Historische grafiek van CPU, geheugen, schijf of netwerk voor een host.", "widgetHostGridName": "Host Grid", "widgetHostGridDesc": "Rasterweergave van de status van SSH-hosts", - "widgetAlertFeedName": "Waarschuwingsfeed", - "widgetAlertFeedDesc": "Live waarschuwingen met bevestigingsondersteuning", "widgetPingStatusName": "Pingstatus", "widgetPingStatusDesc": "HTTP-pingstatus voor een of meer URL's", "widgetRecentActivityName": "Recente activiteit", @@ -747,7 +744,6 @@ "portForwarding": "Doorsturen", "sftp": "SFTP", "connections": "Verbindingen", - "alerts": "Waarschuwingen", "serial": "Serieel", "keepSideMenuOpen": "Menu open houden", "collapseSideMenu": "Menu inklappen", @@ -4890,21 +4886,6 @@ "viewHistory": "Geschiedenis bekijken" }, "alerts": { - "tabFirings": "Waarschuwingen", - "tabRules": "Regels", - "tabChannels": "Kanalen", - "noFirings": "Geen niet-bevestigde meldingen", - "noRules": "Er zijn geen waarschuwingsregels geconfigureerd.", - "noChannels": "Er zijn geen notificatiekanalen geconfigureerd.", - "rulesDesc": "Waarschuwingsregels activeren meldingen.", - "channelsDesc": "Waar waarschuwingsmeldingen worden verzonden", - "acknowledge": "Erkennen", - "ackAll": "Bevestig alles", - "allAcknowledged": "Alle meldingen bevestigd", - "ackFailed": "Melding niet ontvangen", - "ackAllFailed": "Niet alle meldingen zijn bevestigd.", - "showAcknowledged": "Alles weergeven", - "hideAcknowledged": "Verberg Acked", "addChannel": "Kanaal toevoegen", "editChannel": "Bewerk kanaal", "channelName": "Naam", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Onderwerp", "ntfyTopicRequired": "Onderwerp is verplicht", "ntfyToken": "Toegangstoken (optioneel)", - "channelSaveFailed": "Het opslaan van het kanaal is mislukt.", - "test": "Test", - "testSent": "Testmelding verzonden", - "testFailed": "Testmelding mislukt", - "testFailedWithReason": "Testmelding mislukt: {{reason}}", - "addRule": "Voeg een waarschuwingsregel toe", - "editRule": "Regel voor waarschuwing bewerken", - "ruleName": "Regelnaam", - "ruleNameRequired": "Naam is verplicht", - "triggerType": "Trekker", - "thresholdValue": "Drempelwaarde (%)", - "durationSeconds": "Duur (seconden, 0 = direct vuren)", - "cooldownMinutes": "Afkoeltijd (minuten)", - "channels": "Meldingskanalen", - "noChannelsHint": "Voeg eerst kanalen toe via het tabblad Kanalen.", - "ruleSaveFailed": "Het opslaan van de regel is mislukt." + "channelSaveFailed": "Het opslaan van het kanaal is mislukt." }, "ai": { "title": "Assistent", diff --git a/src/ui/locales/translated/no_NO.json b/src/ui/locales/translated/no_NO.json index 2606047ce..40d3608b4 100644 --- a/src/ui/locales/translated/no_NO.json +++ b/src/ui/locales/translated/no_NO.json @@ -287,7 +287,6 @@ "loading": "Laster inn...", "noData": "Ingen data tilgjengelig", "allClear": "Alt klart", - "acknowledgeAlert": "Bekrefte", "noPingUrls": "Ingen nettadresser konfigurert", "pingLabel": "Merkelapp", "addPingUrl": "Legg til nettadresse", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Historisk CPU-, minne-, disk- eller nettverksdiagram for en vert", "widgetHostGridName": "Vertsnett", "widgetHostGridDesc": "Rutenettvisning av SSH-vertstatuser", - "widgetAlertFeedName": "Varselstrøm", - "widgetAlertFeedDesc": "Live-varslingsutløsninger med bekreftelsesstøtte", "widgetPingStatusName": "Ping-status", "widgetPingStatusDesc": "HTTP-pingstatus for én eller flere URL-er", "widgetRecentActivityName": "Nylig aktivitet", @@ -747,7 +744,6 @@ "portForwarding": "Videresending", "sftp": "SFTP", "connections": "Tilkoblinger", - "alerts": "Varsler", "serial": "Seriell", "keepSideMenuOpen": "Hold menyen åpen", "collapseSideMenu": "Skjul menyen", @@ -4890,21 +4886,6 @@ "viewHistory": "Vis historikk" }, "alerts": { - "tabFirings": "Varsler", - "tabRules": "Regler", - "tabChannels": "Kanaler", - "noFirings": "Ingen ubekreftede varsler", - "noRules": "Ingen varslingsregler konfigurert", - "noChannels": "Ingen varslingskanaler konfigurert", - "rulesDesc": "Varslingsregler utløser varsler", - "channelsDesc": "Hvor varsler sendes", - "acknowledge": "Bekrefte", - "ackAll": "Bekreft alle", - "allAcknowledged": "Alle varsler bekreftet", - "ackFailed": "Kunne ikke bekrefte varselet", - "ackAllFailed": "Kunne ikke bekrefte alle varsler", - "showAcknowledged": "Vis alle", - "hideAcknowledged": "Skjul bekreftet", "addChannel": "Legg til kanal", "editChannel": "Rediger kanal", "channelName": "Navn", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Emne", "ntfyTopicRequired": "Emne er obligatorisk", "ntfyToken": "Tilgangstoken (valgfritt)", - "channelSaveFailed": "Kunne ikke lagre kanalen", - "test": "Test", - "testSent": "Testvarsel sendt", - "testFailed": "Testvarsel mislyktes", - "testFailedWithReason": "Testvarsling mislyktes: {{reason}}", - "addRule": "Legg til varslingsregel", - "editRule": "Rediger varslingsregel", - "ruleName": "Regelnavn", - "ruleNameRequired": "Navn er obligatorisk", - "triggerType": "Avtrekker", - "thresholdValue": "Terskel (%)", - "durationSeconds": "Varighet (sekunder, 0 = avfyr umiddelbart)", - "cooldownMinutes": "Nedkjølingstid (minutter)", - "channels": "Varslingskanaler", - "noChannelsHint": "Legg først til kanaler i Kanaler-fanen", - "ruleSaveFailed": "Kunne ikke lagre regelen" + "channelSaveFailed": "Kunne ikke lagre kanalen" }, "ai": { "title": "Assistent", diff --git a/src/ui/locales/translated/pl_PL.json b/src/ui/locales/translated/pl_PL.json index 0100105d5..c2805e6c5 100644 --- a/src/ui/locales/translated/pl_PL.json +++ b/src/ui/locales/translated/pl_PL.json @@ -287,7 +287,6 @@ "loading": "Ładowanie...", "noData": "Brak dostępnych danych", "allClear": "Bez alertów", - "acknowledgeAlert": "Potwierdź", "noPingUrls": "Brak skonfigurowanych adresów URL", "pingLabel": "Etykieta", "addPingUrl": "Dodaj adres URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Historyczny wykres procesora, pamięci, dysku lub sieci dla hosta", "widgetHostGridName": "Siatka hostów", "widgetHostGridDesc": "Widok siatki statusów hostów SSH", - "widgetAlertFeedName": "Kanał alertów", - "widgetAlertFeedDesc": "Wyzwolone alerty na żywo z możliwością potwierdzenia", "widgetPingStatusName": "Status pingu", "widgetPingStatusDesc": "Status pingu HTTP dla jednego lub większej liczby adresów URL", "widgetRecentActivityName": "Ostatnia aktywność", @@ -747,7 +744,6 @@ "portForwarding": "Przekierowanie", "sftp": "SFTP", "connections": "Połączenia", - "alerts": "Alerty", "serial": "Port szeregowy", "keepSideMenuOpen": "Zachowaj otwarte menu", "collapseSideMenu": "Zwiń menu", @@ -4890,21 +4886,6 @@ "viewHistory": "Wyświetl historię" }, "alerts": { - "tabFirings": "Alerty", - "tabRules": "Reguły", - "tabChannels": "Kanały", - "noFirings": "Brak niepotwierdzonych alertów", - "noRules": "Nie skonfigurowano żadnych reguł alertów", - "noChannels": "Brak skonfigurowanych kanałów powiadomień", - "rulesDesc": "Reguły alertów wyzwalają powiadomienia", - "channelsDesc": "Gdzie wysyłane są powiadomienia o alertach", - "acknowledge": "Potwierdź", - "ackAll": "Potwierdź wszystkie", - "allAcknowledged": "Wszystkie alerty potwierdzone", - "ackFailed": "Nie udało się potwierdzić alertu", - "ackAllFailed": "Nie udało się potwierdzić wszystkich alertów", - "showAcknowledged": "Pokaż wszystkie", - "hideAcknowledged": "Ukryj potwierdzone", "addChannel": "Dodaj kanał", "editChannel": "Edytuj kanał", "channelName": "Nazwa", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Temat", "ntfyTopicRequired": "Temat jest wymagany", "ntfyToken": "Token dostępu (opcjonalnie)", - "channelSaveFailed": "Nie udało się zapisać kanału", - "test": "Test", - "testSent": "Wysłano powiadomienie testowe", - "testFailed": "Powiadomienie testowe nie powiodło się", - "testFailedWithReason": "Powiadomienie testowe nie powiodło się: {{reason}}", - "addRule": "Dodaj regułę alertu", - "editRule": "Edytuj regułę alertu", - "ruleName": "Nazwa reguły", - "ruleNameRequired": "Nazwa jest wymagana", - "triggerType": "Wyzwalacz", - "thresholdValue": "Próg (%)", - "durationSeconds": "Czas trwania (sekundy, 0 = wyzwól natychmiast)", - "cooldownMinutes": "Czas wyciszenia (minuty)", - "channels": "Kanały powiadomień", - "noChannelsHint": "Najpierw dodaj kanały na karcie Kanały", - "ruleSaveFailed": "Nie udało się zapisać reguły" + "channelSaveFailed": "Nie udało się zapisać kanału" }, "ai": { "title": "Asystent", diff --git a/src/ui/locales/translated/pt_BR.json b/src/ui/locales/translated/pt_BR.json index 6d9fbef9e..f108a3dde 100644 --- a/src/ui/locales/translated/pt_BR.json +++ b/src/ui/locales/translated/pt_BR.json @@ -287,7 +287,6 @@ "loading": "Carregando...", "noData": "Não há dados disponíveis.", "allClear": "Tudo certo", - "acknowledgeAlert": "Reconhecer", "noPingUrls": "Nenhuma URL configurada", "pingLabel": "Rótulo", "addPingUrl": "Adicionar URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Gráfico histórico de CPU, memória, disco ou rede para um host", "widgetHostGridName": "Grade de anfitriões", "widgetHostGridDesc": "Visualização em grade dos status dos hosts SSH", - "widgetAlertFeedName": "Feed de alertas", - "widgetAlertFeedDesc": "Disparos de alertas em tempo real com suporte de confirmação", "widgetPingStatusName": "Status do ping", "widgetPingStatusDesc": "Status do ping HTTP para um ou mais URLs", "widgetRecentActivityName": "Atividade recente", @@ -747,7 +744,6 @@ "portForwarding": "Encaminhamento", "sftp": "SFTP", "connections": "Conexões", - "alerts": "Alertas", "serial": "Serial", "keepSideMenuOpen": "Mantenha o menu aberto", "collapseSideMenu": "Recolher menu", @@ -4890,21 +4886,6 @@ "viewHistory": "Ver histórico" }, "alerts": { - "tabFirings": "Alertas", - "tabRules": "Regras", - "tabChannels": "Canais", - "noFirings": "Nenhum alerta não reconhecido", - "noRules": "Nenhuma regra de alerta configurada", - "noChannels": "Nenhum canal de notificação configurado", - "rulesDesc": "As regras de alerta acionam notificações.", - "channelsDesc": "Para onde são enviadas as notificações de alerta", - "acknowledge": "Reconhecer", - "ackAll": "Concordo com tudo", - "allAcknowledged": "Todos os alertas foram reconhecidos.", - "ackFailed": "Falha em reconhecer o alerta", - "ackAllFailed": "Não reconheceu todos os alertas.", - "showAcknowledged": "Mostrar tudo", - "hideAcknowledged": "Esconder Acked", "addChannel": "Adicionar canal", "editChannel": "Editar canal", "channelName": "Nome", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Tópico", "ntfyTopicRequired": "É necessário definir o tema.", "ntfyToken": "Token de acesso (opcional)", - "channelSaveFailed": "Falha ao salvar o canal", - "test": "Teste", - "testSent": "Notificação de teste enviada", - "testFailed": "Falha na notificação de teste", - "testFailedWithReason": "Falha na notificação de teste: {{reason}}", - "addRule": "Adicionar regra de alerta", - "editRule": "Editar regra de alerta", - "ruleName": "Nome da regra", - "ruleNameRequired": "O nome é obrigatório.", - "triggerType": "Acionar", - "thresholdValue": "Limite (%)", - "durationSeconds": "Duração (segundos, 0 = disparar imediatamente)", - "cooldownMinutes": "Tempo de resfriamento (minutos)", - "channels": "Canais de notificação", - "noChannelsHint": "Adicione os canais primeiro na aba Canais.", - "ruleSaveFailed": "Falha ao salvar a regra" + "channelSaveFailed": "Falha ao salvar o canal" }, "ai": { "title": "Assistente", diff --git a/src/ui/locales/translated/pt_PT.json b/src/ui/locales/translated/pt_PT.json index 74146624d..29ce3020d 100644 --- a/src/ui/locales/translated/pt_PT.json +++ b/src/ui/locales/translated/pt_PT.json @@ -287,7 +287,6 @@ "loading": "A carregar...", "noData": "Sem dados disponíveis", "allClear": "Tudo em ordem", - "acknowledgeAlert": "Reconhecer", "noPingUrls": "Nenhum URL configurado", "pingLabel": "Etiqueta", "addPingUrl": "Adicionar URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Gráfico histórico de CPU, memória, disco ou rede para um host", "widgetHostGridName": "Grelha de hosts", "widgetHostGridDesc": "Vista em grelha dos estados dos hosts SSH", - "widgetAlertFeedName": "Feed de alertas", - "widgetAlertFeedDesc": "Disparos de alertas em tempo real com suporte a reconhecimento", "widgetPingStatusName": "Estado do ping", "widgetPingStatusDesc": "Estado do ping HTTP para um ou mais URLs", "widgetRecentActivityName": "Atividade recente", @@ -747,7 +744,6 @@ "portForwarding": "Encaminhamento", "sftp": "SFTP", "connections": "Ligações", - "alerts": "Alertas", "serial": "Serial", "keepSideMenuOpen": "Mantenha o menu aberto", "collapseSideMenu": "Recolher menu", @@ -4890,21 +4886,6 @@ "viewHistory": "Ver Histórico" }, "alerts": { - "tabFirings": "Alertas", - "tabRules": "Regras", - "tabChannels": "Canais", - "noFirings": "Nenhum alerta por reconhecer", - "noRules": "Nenhuma regra de alerta configurada", - "noChannels": "Nenhum canal de notificação configurado", - "rulesDesc": "As regras de alerta disparam notificações", - "channelsDesc": "Onde as notificações de alerta são enviadas", - "acknowledge": "Reconhecer", - "ackAll": "Reconhecer Todos", - "allAcknowledged": "Todos os alertas reconhecidos", - "ackFailed": "Falha ao reconhecer o alerta", - "ackAllFailed": "Falha ao reconhecer todos os alertas", - "showAcknowledged": "Mostrar Todos", - "hideAcknowledged": "Ocultar Reconhecidos", "addChannel": "Adicionar Canal", "editChannel": "Editar Canal", "channelName": "Nome", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Tópico", "ntfyTopicRequired": "O tópico é obrigatório", "ntfyToken": "Token de acesso (opcional)", - "channelSaveFailed": "Falha ao guardar o canal", - "test": "Testar", - "testSent": "Notificação de teste enviada", - "testFailed": "Falha na notificação de teste", - "testFailedWithReason": "Falha na notificação de teste: {{reason}}", - "addRule": "Adicionar regra de alerta", - "editRule": "Editar regra de alerta", - "ruleName": "Nome da regra", - "ruleNameRequired": "O nome é obrigatório", - "triggerType": "Gatilho", - "thresholdValue": "Limiar (%)", - "durationSeconds": "Duração (segundos, 0 = disparar imediatamente)", - "cooldownMinutes": "Período de arrefecimento (minutos)", - "channels": "Canais de notificação", - "noChannelsHint": "Adicione canais primeiro no separador Canais", - "ruleSaveFailed": "Falha ao guardar a regra" + "channelSaveFailed": "Falha ao guardar o canal" }, "ai": { "title": "Assistente", diff --git a/src/ui/locales/translated/ro_RO.json b/src/ui/locales/translated/ro_RO.json index c0ac9c6ef..add0edbb8 100644 --- a/src/ui/locales/translated/ro_RO.json +++ b/src/ui/locales/translated/ro_RO.json @@ -287,7 +287,6 @@ "loading": "Încărcare...", "noData": "Nu sunt disponibile date", "allClear": "Totul este clar", - "acknowledgeAlert": "Recunoaște", "noPingUrls": "Nicio adresă URL configurată", "pingLabel": "Eticheta", "addPingUrl": "Adăugați adresa URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Diagramă istorică CPU, memorie, disc sau rețea pentru o gazdă", "widgetHostGridName": "Grilă gazdă", "widgetHostGridDesc": "Vizualizare grilă a stărilor gazdelor SSH", - "widgetAlertFeedName": "Flux de alerte", - "widgetAlertFeedDesc": "Declanșări în direct cu asistență pentru confirmare", "widgetPingStatusName": "Starea ping-ului", "widgetPingStatusDesc": "Starea ping-ului HTTP pentru una sau mai multe adrese URL", "widgetRecentActivityName": "Activitate recentă", @@ -747,7 +744,6 @@ "portForwarding": "Redirecționare", "sftp": "SFTP", "connections": "Conexiuni", - "alerts": "Alerte", "serial": "Serial", "keepSideMenuOpen": "Mențineți meniul deschis", "collapseSideMenu": "Restrângeți meniul", @@ -4890,21 +4886,6 @@ "viewHistory": "Vizualizați istoricul" }, "alerts": { - "tabFirings": "Alerte", - "tabRules": "Reguli", - "tabChannels": "Canale", - "noFirings": "Nicio alertă neconfirmată", - "noRules": "Nicio regulă de alertă configurată", - "noChannels": "Nu sunt configurate canale de notificare", - "rulesDesc": "Regulile de alertă declanșează notificări", - "channelsDesc": "Unde sunt trimise notificările de alertă", - "acknowledge": "Recunoaște", - "ackAll": "Confirmare tuturor", - "allAcknowledged": "Toate alertele au fost confirmate", - "ackFailed": "Nu s-a putut confirma alerta", - "ackAllFailed": "Nu s-au putut confirma toate alertele", - "showAcknowledged": "Afișează tot", - "hideAcknowledged": "Ascundeți confirmarea", "addChannel": "Adăugați canal", "editChannel": "Editați canalul", "channelName": "Nume", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Subiect", "ntfyTopicRequired": "Subiectul este obligatoriu", "ntfyToken": "Token de acces (opțional)", - "channelSaveFailed": "Canalul nu a putut fi salvat.", - "test": "Test", - "testSent": "Notificare de testare trimisă", - "testFailed": "Notificarea de testare a eșuat", - "testFailedWithReason": "Notificarea de testare a eșuat: {{reason}}", - "addRule": "Adăugați o regulă de alertă", - "editRule": "Editați regula de alertă", - "ruleName": "Nume regulă", - "ruleNameRequired": "Numele este obligatoriu", - "triggerType": "Declanșator", - "thresholdValue": "Prag (%)", - "durationSeconds": "Durată (secunde, 0 = declanșează imediat)", - "cooldownMinutes": "Timp de răcire (minute)", - "channels": "Canale de notificare", - "noChannelsHint": "Adăugați mai întâi canale în fila Canale", - "ruleSaveFailed": "Nu s-a putut salva regula" + "channelSaveFailed": "Canalul nu a putut fi salvat." }, "ai": { "title": "Asistent", diff --git a/src/ui/locales/translated/ru_RU.json b/src/ui/locales/translated/ru_RU.json index 45448ba7d..a95ee5631 100644 --- a/src/ui/locales/translated/ru_RU.json +++ b/src/ui/locales/translated/ru_RU.json @@ -287,7 +287,6 @@ "loading": "Загрузка...", "noData": "Нет данных", "allClear": "Всё в порядке", - "acknowledgeAlert": "Подтвердить", "noPingUrls": "URL-адреса не настроены", "pingLabel": "Метка", "addPingUrl": "Добавить URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "График истории использования ЦП, памяти, диска или сети для хоста", "widgetHostGridName": "Сетка хостов", "widgetHostGridDesc": "Представление статусов хостов SSH в виде сетки", - "widgetAlertFeedName": "Лента оповещений", - "widgetAlertFeedDesc": "Живые срабатывания оповещений с возможностью подтверждения", "widgetPingStatusName": "Статус ping", "widgetPingStatusDesc": "Статус HTTP ping для одного или нескольких URL", "widgetRecentActivityName": "Недавняя активность", @@ -747,7 +744,6 @@ "portForwarding": "Пересылка", "sftp": "SFTP", "connections": "Подключения", - "alerts": "Оповещения", "serial": "Последовательный порт", "keepSideMenuOpen": "Оставить меню открытым", "collapseSideMenu": "Свернуть меню", @@ -4890,21 +4886,6 @@ "viewHistory": "Просмотреть историю" }, "alerts": { - "tabFirings": "Оповещения", - "tabRules": "Правила", - "tabChannels": "Каналы", - "noFirings": "Нет неподтверждённых оповещений", - "noRules": "Не настроены правила оповещений", - "noChannels": "Не настроены каналы уведомлений", - "rulesDesc": "Правила оповещений инициируют уведомления", - "channelsDesc": "Куда отправляются уведомления об оповещениях", - "acknowledge": "Подтвердить", - "ackAll": "Подтвердить все", - "allAcknowledged": "Все оповещения подтверждены", - "ackFailed": "Не удалось подтвердить оповещение", - "ackAllFailed": "Не удалось подтвердить все оповещения", - "showAcknowledged": "Показать все", - "hideAcknowledged": "Скрыть подтверждённые", "addChannel": "Добавить канал", "editChannel": "Изменить канал", "channelName": "Название", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Тема", "ntfyTopicRequired": "Тема обязательна", "ntfyToken": "Токен доступа (необязательно)", - "channelSaveFailed": "Не удалось сохранить канал", - "test": "Проверить", - "testSent": "Тестовое уведомление отправлено", - "testFailed": "Ошибка отправки тестового уведомления", - "testFailedWithReason": "Тестовое уведомление не пройдено: {{reason}}", - "addRule": "Добавить правило оповещения", - "editRule": "Редактировать правило оповещения", - "ruleName": "Имя правила", - "ruleNameRequired": "Имя обязательно", - "triggerType": "Триггер", - "thresholdValue": "Порог (%)", - "durationSeconds": "Длительность (секунд, 0 = сработать немедленно)", - "cooldownMinutes": "Задержка повторения (минут)", - "channels": "Каналы уведомлений", - "noChannelsHint": "Сначала добавьте каналы на вкладке «Каналы»", - "ruleSaveFailed": "Не удалось сохранить правило" + "channelSaveFailed": "Не удалось сохранить канал" }, "ai": { "title": "Помощник", diff --git a/src/ui/locales/translated/sr_SP.json b/src/ui/locales/translated/sr_SP.json index 81944b13c..9a8d38d0b 100644 --- a/src/ui/locales/translated/sr_SP.json +++ b/src/ui/locales/translated/sr_SP.json @@ -287,7 +287,6 @@ "loading": "Учитавање...", "noData": "Нема доступних података", "allClear": "Све је чисто", - "acknowledgeAlert": "Потврди", "noPingUrls": "Није конфигурисан ниједан URL", "pingLabel": "Ознака", "addPingUrl": "Додај URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Историјски графикон процесора, меморије, диска или мреже за хост", "widgetHostGridName": "Хост мрежа", "widgetHostGridDesc": "Приказ мреже статуса SSH хоста", - "widgetAlertFeedName": "Фид обавештења", - "widgetAlertFeedDesc": "Укључивање упозорења уживо са подршком за потврду", "widgetPingStatusName": "Статус пинга", "widgetPingStatusDesc": "HTTP пинг статус за један или више URL-ова", "widgetRecentActivityName": "Недавне активности", @@ -747,7 +744,6 @@ "portForwarding": "Преусмеравање", "sftp": "СФТП", "connections": "Везе", - "alerts": "Упозорења", "serial": "Серијски", "keepSideMenuOpen": "Остави мени отвореним", "collapseSideMenu": "Сакриј мени", @@ -4890,21 +4886,6 @@ "viewHistory": "Прикажи историју" }, "alerts": { - "tabFirings": "Упозорења", - "tabRules": "Правила", - "tabChannels": "Канали", - "noFirings": "Нема непотврђених упозорења", - "noRules": "Није конфигурисано ниједно правило упозорења", - "noChannels": "Није конфигурисан ниједан канал за обавештења", - "rulesDesc": "Правила упозорења покрећу обавештења", - "channelsDesc": "Где се шаљу обавештења", - "acknowledge": "Потврди", - "ackAll": "Потврди све", - "allAcknowledged": "Сва упозорења су потврђена", - "ackFailed": "Потврђивање упозорења није успело", - "ackAllFailed": "Није успело потврђивање свих упозорења", - "showAcknowledged": "Прикажи све", - "hideAcknowledged": "Сакриј потврђено", "addChannel": "Додај канал", "editChannel": "Измени канал", "channelName": "Име", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Тема", "ntfyTopicRequired": "Тема је обавезна", "ntfyToken": "Приступни токен (опционо)", - "channelSaveFailed": "Чување канала није успело", - "test": "Тест", - "testSent": "Послато је пробно обавештење", - "testFailed": "Обавештење о тестирању није успело", - "testFailedWithReason": "Обавештење о тестирању није успело: {{reason}}", - "addRule": "Додај правило упозорења", - "editRule": "Измени правило упозорења", - "ruleName": "Назив правила", - "ruleNameRequired": "Име је обавезно", - "triggerType": "Окидач", - "thresholdValue": "Праг (%)", - "durationSeconds": "Трајање (секунде, 0 = одмах се активира)", - "cooldownMinutes": "Хлађење (минути)", - "channels": "Канали за обавештења", - "noChannelsHint": "Прво додајте канале на картици Канали", - "ruleSaveFailed": "Чување правила није успело" + "channelSaveFailed": "Чување канала није успело" }, "ai": { "title": "Асистент", diff --git a/src/ui/locales/translated/sv_SE.json b/src/ui/locales/translated/sv_SE.json index 1d8470306..28d18ee61 100644 --- a/src/ui/locales/translated/sv_SE.json +++ b/src/ui/locales/translated/sv_SE.json @@ -287,7 +287,6 @@ "loading": "Belastning...", "noData": "Inga data tillgängliga", "allClear": "Faran över", - "acknowledgeAlert": "Erkänna", "noPingUrls": "Inga webbadresser konfigurerade", "pingLabel": "Märka", "addPingUrl": "Lägg till URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Historiskt diagram över CPU, minne, disk eller nätverk för en värd", "widgetHostGridName": "Värdnät", "widgetHostGridDesc": "Rutnätsvy över SSH-värdstatusar", - "widgetAlertFeedName": "Aviseringsflöde", - "widgetAlertFeedDesc": "Live-avfyrningar med bekräftelsestöd", "widgetPingStatusName": "Pingstatus", "widgetPingStatusDesc": "HTTP-pingstatus för en eller flera URL:er", "widgetRecentActivityName": "Senaste aktivitet", @@ -747,7 +744,6 @@ "portForwarding": "Spedition", "sftp": "SFTP", "connections": "Anslutningar", - "alerts": "Aviseringar", "serial": "Serie", "keepSideMenuOpen": "Håll menyn öppen", "collapseSideMenu": "Minimera menyn", @@ -4890,21 +4886,6 @@ "viewHistory": "Visa historik" }, "alerts": { - "tabFirings": "Aviseringar", - "tabRules": "Regler", - "tabChannels": "Kanaler", - "noFirings": "Inga okvitterade varningar", - "noRules": "Inga varningsregler konfigurerade", - "noChannels": "Inga aviseringskanaler konfigurerade", - "rulesDesc": "Aviseringsregler utlöser aviseringar", - "channelsDesc": "Vart varningsmeddelanden skickas", - "acknowledge": "Erkänna", - "ackAll": "Bekräfta alla", - "allAcknowledged": "Alla varningar bekräftade", - "ackFailed": "Kunde inte bekräfta varningen", - "ackAllFailed": "Kunde inte bekräfta alla varningar", - "showAcknowledged": "Visa alla", - "hideAcknowledged": "Dölj godkända", "addChannel": "Lägg till kanal", "editChannel": "Redigera kanal", "channelName": "Namn", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Ämne", "ntfyTopicRequired": "Ämne är obligatoriskt", "ntfyToken": "Åtkomsttoken (valfritt)", - "channelSaveFailed": "Misslyckades med att spara kanalen", - "test": "Testa", - "testSent": "Testmeddelande skickat", - "testFailed": "Testmeddelandet misslyckades", - "testFailedWithReason": "Testmeddelande misslyckades: {{reason}}", - "addRule": "Lägg till varningsregel", - "editRule": "Redigera varningsregel", - "ruleName": "Regelnamn", - "ruleNameRequired": "Namn krävs", - "triggerType": "Utlösare", - "thresholdValue": "Tröskelvärde (%)", - "durationSeconds": "Varaktighet (sekunder, 0 = avfyras omedelbart)", - "cooldownMinutes": "Nedkylningstid (minuter)", - "channels": "Aviseringskanaler", - "noChannelsHint": "Lägg först till kanaler på fliken Kanaler", - "ruleSaveFailed": "Det gick inte att spara regeln" + "channelSaveFailed": "Misslyckades med att spara kanalen" }, "ai": { "title": "Assistent", diff --git a/src/ui/locales/translated/th_TH.json b/src/ui/locales/translated/th_TH.json index 4fec0e25f..c32bbaa6c 100644 --- a/src/ui/locales/translated/th_TH.json +++ b/src/ui/locales/translated/th_TH.json @@ -287,7 +287,6 @@ "loading": "กำลังโหลด...", "noData": "ไม่มีข้อมูล", "allClear": "ทุกอย่างเรียบร้อย", - "acknowledgeAlert": "รับทราบ", "noPingUrls": "ไม่มีการกำหนดค่า URL", "pingLabel": "ฉลาก", "addPingUrl": "เพิ่ม URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "แผนภูมิแสดงประวัติการใช้งาน CPU, หน่วยความจำ, ดิสก์ หรือเครือข่ายสำหรับโฮสต์", "widgetHostGridName": "โฮสต์กริด", "widgetHostGridDesc": "การแสดงผลแบบตารางของสถานะโฮสต์ SSH", - "widgetAlertFeedName": "ฟีดแจ้งเตือน", - "widgetAlertFeedDesc": "การแจ้งเตือนแบบเรียลไทม์พร้อมการยืนยันการรับการแจ้งเตือน", "widgetPingStatusName": "สถานะการปิง", "widgetPingStatusDesc": "สถานะการ ping HTTP สำหรับ URL หนึ่งรายการขึ้นไป", "widgetRecentActivityName": "กิจกรรมล่าสุด", @@ -747,7 +744,6 @@ "portForwarding": "การส่งต่อ", "sftp": "เอสเอฟทีพี", "connections": "การเชื่อมต่อ", - "alerts": "การแจ้งเตือน", "serial": "ซีเรียล", "keepSideMenuOpen": "เปิดเมนูค้างไว้", "collapseSideMenu": "ยุบเมนู", @@ -4890,21 +4886,6 @@ "viewHistory": "ประวัติการดู" }, "alerts": { - "tabFirings": "การแจ้งเตือน", - "tabRules": "กฎ", - "tabChannels": "ช่องต่างๆ", - "noFirings": "ไม่มีการแจ้งเตือนที่ยังไม่ได้รับการยืนยัน", - "noRules": "ไม่มีการกำหนดค่ากฎการแจ้งเตือน", - "noChannels": "ไม่ได้กำหนดค่าช่องทางการแจ้งเตือนใดๆ", - "rulesDesc": "กฎการแจ้งเตือนจะเรียกใช้การแจ้งเตือน", - "channelsDesc": "ส่งการแจ้งเตือนไปยังที่ต่างๆ", - "acknowledge": "รับทราบ", - "ackAll": "ยอมรับทั้งหมด", - "allAcknowledged": "รับทราบการแจ้งเตือนทั้งหมดแล้ว", - "ackFailed": "ไม่ตอบรับการแจ้งเตือน", - "ackAllFailed": "ไม่สามารถตอบรับการแจ้งเตือนทั้งหมดได้", - "showAcknowledged": "แสดงทั้งหมด", - "hideAcknowledged": "ซ่อน ตอบรับ", "addChannel": "เพิ่มช่องทาง", "editChannel": "แก้ไขช่อง", "channelName": "ชื่อ", @@ -4917,22 +4898,7 @@ "ntfyTopic": "หัวข้อ", "ntfyTopicRequired": "จำเป็นต้องระบุหัวข้อ", "ntfyToken": "โทเค็นการเข้าถึง (ไม่บังคับ)", - "channelSaveFailed": "ไม่สามารถบันทึกช่องได้", - "test": "ทดสอบ", - "testSent": "ส่งการแจ้งเตือนการทดสอบแล้ว", - "testFailed": "การแจ้งเตือนการทดสอบล้มเหลว", - "testFailedWithReason": "การแจ้งเตือนการทดสอบล้มเหลว: {{reason}}", - "addRule": "เพิ่มกฎการแจ้งเตือน", - "editRule": "แก้ไขกฎการแจ้งเตือน", - "ruleName": "ชื่อกฎ", - "ruleNameRequired": "ต้องระบุชื่อ", - "triggerType": "สิ่งกระตุ้น", - "thresholdValue": "เกณฑ์ (%)", - "durationSeconds": "ระยะเวลา (วินาที, 0 = ยิงทันที)", - "cooldownMinutes": "ระยะเวลาคูลดาวน์ (นาที)", - "channels": "ช่องทางการแจ้งเตือน", - "noChannelsHint": "เพิ่มช่องในแท็บช่องก่อน", - "ruleSaveFailed": "ไม่สามารถบันทึกกฎได้" + "channelSaveFailed": "ไม่สามารถบันทึกช่องได้" }, "ai": { "title": "ผู้ช่วย", diff --git a/src/ui/locales/translated/tr_TR.json b/src/ui/locales/translated/tr_TR.json index 8446e3828..88f5bc0bd 100644 --- a/src/ui/locales/translated/tr_TR.json +++ b/src/ui/locales/translated/tr_TR.json @@ -287,7 +287,6 @@ "loading": "Yükleniyor...", "noData": "Veri yok", "allClear": "Her şey normal", - "acknowledgeAlert": "Onayla", "noPingUrls": "Hiçbir URL yapılandırılmamış", "pingLabel": "Etiket", "addPingUrl": "URL Ekle", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Bir sunucu için geçmiş CPU, bellek, disk veya ağ grafiği", "widgetHostGridName": "Sunucu Izgarası", "widgetHostGridDesc": "SSH sunucu durumlarının ızgara görünümü", - "widgetAlertFeedName": "Uyarı Akışı", - "widgetAlertFeedDesc": "Onay desteği ile canlı uyarı tetiklemeleri", "widgetPingStatusName": "Ping Durumu", "widgetPingStatusDesc": "Bir veya daha fazla URL için HTTP ping durumu", "widgetRecentActivityName": "Son Etkinlikler", @@ -747,7 +744,6 @@ "portForwarding": "İletme", "sftp": "SFTP", "connections": "Bağlantılar", - "alerts": "Uyarılar", "serial": "Seri", "keepSideMenuOpen": "Menüyü Açık Tutun", "collapseSideMenu": "Menüyü Daralt", @@ -4890,21 +4886,6 @@ "viewHistory": "Geçmişi Görüntüle" }, "alerts": { - "tabFirings": "Uyarılar", - "tabRules": "Kurallar", - "tabChannels": "Kanallar", - "noFirings": "Onaylanmamış uyarı yok", - "noRules": "Uyarı kuralı yapılandırılmamış", - "noChannels": "Bildirim kanalı yapılandırılmamış", - "rulesDesc": "Uyarı kuralları bildirimleri tetikler", - "channelsDesc": "Uyarı bildirimlerinin gönderildiği yer", - "acknowledge": "Onayla", - "ackAll": "Tümünü Onayla", - "allAcknowledged": "Tüm uyarılar onaylandı", - "ackFailed": "Uyarı onaylanamadı", - "ackAllFailed": "Tüm uyarılar onaylanamadı", - "showAcknowledged": "Tümünü Göster", - "hideAcknowledged": "Onaylananları Gizle", "addChannel": "Kanal Ekle", "editChannel": "Kanalı Düzenle", "channelName": "Ad", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Konu", "ntfyTopicRequired": "Konu zorunludur", "ntfyToken": "Erişim Anahtarı (isteğe bağlı)", - "channelSaveFailed": "Kanal kaydedilemedi", - "test": "Test Et", - "testSent": "Test bildirimi gönderildi", - "testFailed": "Test bildirimi başarısız oldu", - "testFailedWithReason": "Test bildirimi başarısız oldu: {{reason}}", - "addRule": "Uyarı Kuralı Ekle", - "editRule": "Uyarı Kuralını Düzenle", - "ruleName": "Kural Adı", - "ruleNameRequired": "Ad zorunludur", - "triggerType": "Tetikleyici", - "thresholdValue": "Eşik (%)", - "durationSeconds": "Süre (saniye, 0 = hemen tetikle)", - "cooldownMinutes": "Bekleme süresi (dakika)", - "channels": "Bildirim Kanalları", - "noChannelsHint": "Önce Kanallar sekmesinde kanal ekleyin", - "ruleSaveFailed": "Kural kaydedilemedi" + "channelSaveFailed": "Kanal kaydedilemedi" }, "ai": { "title": "Asistan", diff --git a/src/ui/locales/translated/uk_UA.json b/src/ui/locales/translated/uk_UA.json index 2b0d483ff..00434ca6a 100644 --- a/src/ui/locales/translated/uk_UA.json +++ b/src/ui/locales/translated/uk_UA.json @@ -287,7 +287,6 @@ "loading": "Завантаження...", "noData": "Дані недоступні", "allClear": "Все чисто", - "acknowledgeAlert": "Підтвердити", "noPingUrls": "URL-адреси не налаштовано", "pingLabel": "Мітка", "addPingUrl": "Додати URL-адресу", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Історична діаграма процесора, пам'яті, диска або мережі для хоста", "widgetHostGridName": "Сітка хоста", "widgetHostGridDesc": "Таблиця статусів хостів SSH", - "widgetAlertFeedName": "Стрічка сповіщень", - "widgetAlertFeedDesc": "Активація тривог у реальному часі з підтримкою підтвердження", "widgetPingStatusName": "Стан пінгу", "widgetPingStatusDesc": "Статус HTTP-пінгу для однієї або кількох URL-адрес", "widgetRecentActivityName": "Нещодавня активність", @@ -747,7 +744,6 @@ "portForwarding": "Переадресація", "sftp": "SFTP", "connections": "З'єднання", - "alerts": "Сповіщення", "serial": "Серійний", "keepSideMenuOpen": "Залишити меню відкритим", "collapseSideMenu": "Згорнути меню", @@ -4890,21 +4886,6 @@ "viewHistory": "Переглянути історію" }, "alerts": { - "tabFirings": "Сповіщення", - "tabRules": "Правила", - "tabChannels": "Канали", - "noFirings": "Немає непідтверджених сповіщень", - "noRules": "Правила сповіщень не налаштовано", - "noChannels": "Канали сповіщень не налаштовано", - "rulesDesc": "Правила сповіщень запускають сповіщення", - "channelsDesc": "Куди надсилаються сповіщення", - "acknowledge": "Підтвердити", - "ackAll": "Підтвердження всім", - "allAcknowledged": "Усі сповіщення підтверджено", - "ackFailed": "Не вдалося підтвердити сповіщення", - "ackAllFailed": "Не вдалося підтвердити всі сповіщення", - "showAcknowledged": "Показати все", - "hideAcknowledged": "Приховати підтверджено", "addChannel": "Додати канал", "editChannel": "Редагувати канал", "channelName": "Ім'я", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Тема", "ntfyTopicRequired": "Тема обов'язкова", "ntfyToken": "Маркер доступу (необов'язково)", - "channelSaveFailed": "Не вдалося зберегти канал", - "test": "Тест", - "testSent": "Тестове сповіщення надіслано", - "testFailed": "Не вдалося виконати тестове сповіщення", - "testFailedWithReason": "Не вдалося виконати тестове сповіщення: {{reason}}", - "addRule": "Додати правило сповіщення", - "editRule": "Редагувати правило сповіщення", - "ruleName": "Назва правила", - "ruleNameRequired": "Ім'я обов'язкове", - "triggerType": "Тригер", - "thresholdValue": "Поріг (%)", - "durationSeconds": "Тривалість (секунди, 0 = негайно спрацьовувати)", - "cooldownMinutes": "Охолодження (хвилини)", - "channels": "Канали сповіщень", - "noChannelsHint": "Спочатку додайте канали на вкладці «Канали»", - "ruleSaveFailed": "Не вдалося зберегти правило" + "channelSaveFailed": "Не вдалося зберегти канал" }, "ai": { "title": "Помічник", diff --git a/src/ui/locales/translated/vi_VN.json b/src/ui/locales/translated/vi_VN.json index 05098d972..9141526b6 100644 --- a/src/ui/locales/translated/vi_VN.json +++ b/src/ui/locales/translated/vi_VN.json @@ -287,7 +287,6 @@ "loading": "Đang tải...", "noData": "Không có dữ liệu", "allClear": "Tất cả ổn", - "acknowledgeAlert": "Xác nhận", "noPingUrls": "Chưa cấu hình URL", "pingLabel": "Nhãn", "addPingUrl": "Thêm URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "Biểu đồ lịch sử CPU, bộ nhớ, ổ đĩa hoặc mạng cho một máy chủ", "widgetHostGridName": "Lưới máy chủ", "widgetHostGridDesc": "Hiển thị trạng thái máy chủ SSH dạng lưới", - "widgetAlertFeedName": "Luồng cảnh báo", - "widgetAlertFeedDesc": "Cảnh báo trực tiếp kèm hỗ trợ xác nhận", "widgetPingStatusName": "Trạng thái ping", "widgetPingStatusDesc": "Trạng thái ping HTTP cho một hoặc nhiều URL", "widgetRecentActivityName": "Hoạt động gần đây", @@ -747,7 +744,6 @@ "portForwarding": "Chuyển tiếp", "sftp": "SFTP", "connections": "Kết nối", - "alerts": "Cảnh báo", "serial": "Nối tiếp", "keepSideMenuOpen": "Giữ menu luôn mở", "collapseSideMenu": "Menu thu gọn", @@ -4890,21 +4886,6 @@ "viewHistory": "Xem lịch sử" }, "alerts": { - "tabFirings": "Cảnh báo", - "tabRules": "Quy tắc", - "tabChannels": "Kênh", - "noFirings": "Không có cảnh báo chưa xác nhận", - "noRules": "Chưa cấu hình quy tắc cảnh báo", - "noChannels": "Chưa cấu hình kênh thông báo", - "rulesDesc": "Quy tắc cảnh báo kích hoạt thông báo", - "channelsDesc": "Nơi gửi thông báo cảnh báo", - "acknowledge": "Xác nhận", - "ackAll": "Xác nhận tất cả", - "allAcknowledged": "Tất cả cảnh báo đã được xác nhận", - "ackFailed": "Không thể xác nhận cảnh báo", - "ackAllFailed": "Không thể xác nhận tất cả cảnh báo", - "showAcknowledged": "Hiện tất cả", - "hideAcknowledged": "Ẩn đã xác nhận", "addChannel": "Thêm kênh", "editChannel": "Sửa kênh", "channelName": "Tên", @@ -4917,22 +4898,7 @@ "ntfyTopic": "Chủ đề", "ntfyTopicRequired": "Chủ đề là bắt buộc", "ntfyToken": "Mã truy cập (tùy chọn)", - "channelSaveFailed": "Lỗi khi lưu kênh", - "test": "Kiểm tra", - "testSent": "Đã gửi thông báo kiểm tra", - "testFailed": "Gửi thông báo kiểm tra thất bại", - "testFailedWithReason": "Thông báo kiểm tra thất bại: {{reason}}", - "addRule": "Thêm quy tắc cảnh báo", - "editRule": "Sửa quy tắc cảnh báo", - "ruleName": "Tên quy tắc", - "ruleNameRequired": "Tên là bắt buộc", - "triggerType": "Kích hoạt", - "thresholdValue": "Ngưỡng (%)", - "durationSeconds": "Thời gian (giây, 0 = kích hoạt ngay)", - "cooldownMinutes": "Thời gian chờ (phút)", - "channels": "Kênh thông báo", - "noChannelsHint": "Vui lòng thêm kênh trong tab Kênh trước", - "ruleSaveFailed": "Lỗi khi lưu quy tắc" + "channelSaveFailed": "Lỗi khi lưu kênh" }, "ai": { "title": "Trợ lý", diff --git a/src/ui/locales/translated/zh_CN.json b/src/ui/locales/translated/zh_CN.json index 53e1fb5c7..4297af0be 100644 --- a/src/ui/locales/translated/zh_CN.json +++ b/src/ui/locales/translated/zh_CN.json @@ -287,7 +287,6 @@ "loading": "加载中...", "noData": "暂无数据", "allClear": "一切正常", - "acknowledgeAlert": "确认告警", "noPingUrls": "未配置 URL", "pingLabel": "标签", "addPingUrl": "添加 URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "主机的历史 CPU、内存、磁盘或网络图表", "widgetHostGridName": "主机网格", "widgetHostGridDesc": "SSH 主机状态的网格视图", - "widgetAlertFeedName": "告警信息流", - "widgetAlertFeedDesc": "实时告警触发信息,支持确认操作", "widgetPingStatusName": "Ping 状态", "widgetPingStatusDesc": "一个或多个 URL 的 HTTP ping 状态", "widgetRecentActivityName": "近期活动", @@ -747,7 +744,6 @@ "portForwarding": "转发", "sftp": "SFTP", "connections": "连接", - "alerts": "告警", "serial": "串口", "keepSideMenuOpen": "保持菜单打开", "collapseSideMenu": "折叠菜单", @@ -4890,21 +4886,6 @@ "viewHistory": "查看历史" }, "alerts": { - "tabFirings": "告警", - "tabRules": "规则", - "tabChannels": "通道", - "noFirings": "没有未确认告警", - "noRules": "未配置告警规则", - "noChannels": "未配置通知渠道", - "rulesDesc": "告警规则触发通知", - "channelsDesc": "告警通知的发送渠道", - "acknowledge": "确认告警", - "ackAll": "全部确认", - "allAcknowledged": "所有告警已确认", - "ackFailed": "确认告警失败", - "ackAllFailed": "确认所有告警失败", - "showAcknowledged": "显示全部", - "hideAcknowledged": "隐藏已确认", "addChannel": "添加渠道", "editChannel": "编辑渠道", "channelName": "名称", @@ -4917,22 +4898,7 @@ "ntfyTopic": "主题", "ntfyTopicRequired": "主题为必填项", "ntfyToken": "访问令牌(选填)", - "channelSaveFailed": "保存渠道失败", - "test": "测试", - "testSent": "测试通知已发送", - "testFailed": "测试通知失败", - "testFailedWithReason": "测试通知失败:{{reason}}", - "addRule": "添加告警规则", - "editRule": "编辑告警规则", - "ruleName": "规则名称", - "ruleNameRequired": "名称为必填项", - "triggerType": "触发条件", - "thresholdValue": "阈值(%)", - "durationSeconds": "持续时间(秒,0 表示立即触发)", - "cooldownMinutes": "冷却时间(分钟)", - "channels": "通知渠道", - "noChannelsHint": "请先在渠道标签页中添加渠道", - "ruleSaveFailed": "保存规则失败" + "channelSaveFailed": "保存渠道失败" }, "ai": { "title": "助手", diff --git a/src/ui/locales/translated/zh_TW.json b/src/ui/locales/translated/zh_TW.json index 39fc64de8..440d7eae1 100644 --- a/src/ui/locales/translated/zh_TW.json +++ b/src/ui/locales/translated/zh_TW.json @@ -287,7 +287,6 @@ "loading": "載入中...", "noData": "無可用資料", "allClear": "一切正常", - "acknowledgeAlert": "確認", "noPingUrls": "未設定 URL", "pingLabel": "標籤", "addPingUrl": "新增 URL", @@ -324,8 +323,6 @@ "widgetMetricsChartDesc": "主機的歷史 CPU、記憶體、磁碟或網路圖表", "widgetHostGridName": "主機方格", "widgetHostGridDesc": "SSH 主機狀態的方格檢視", - "widgetAlertFeedName": "警報動態", - "widgetAlertFeedDesc": "即時警報觸發並支援確認", "widgetPingStatusName": "Ping 狀態", "widgetPingStatusDesc": "一個或多個 URL 的 HTTP ping 狀態", "widgetRecentActivityName": "近期活動", @@ -747,7 +744,6 @@ "portForwarding": "轉發", "sftp": "SFTP", "connections": "連線", - "alerts": "警示", "serial": "序列", "keepSideMenuOpen": "保持菜單打開", "collapseSideMenu": "折疊菜單", @@ -4890,21 +4886,6 @@ "viewHistory": "檢視歷史記錄" }, "alerts": { - "tabFirings": "警示", - "tabRules": "規則", - "tabChannels": "通道", - "noFirings": "沒有未確認的警示", - "noRules": "未設定警示規則", - "noChannels": "未設定通知通道", - "rulesDesc": "警示規則會觸發通知", - "channelsDesc": "警示通知傳送的位置", - "acknowledge": "確認", - "ackAll": "全部確認", - "allAcknowledged": "所有警示已確認", - "ackFailed": "確認警示失敗", - "ackAllFailed": "確認所有警示失敗", - "showAcknowledged": "顯示全部", - "hideAcknowledged": "隱藏已確認", "addChannel": "新增通道", "editChannel": "編輯通道", "channelName": "名稱", @@ -4917,22 +4898,7 @@ "ntfyTopic": "主題", "ntfyTopicRequired": "主題為必填", "ntfyToken": "存取權杖(選填)", - "channelSaveFailed": "無法儲存頻道", - "test": "測試", - "testSent": "已傳送測試通知", - "testFailed": "測試通知失敗", - "testFailedWithReason": "測試通知失敗: {{reason}}", - "addRule": "新增警示規則", - "editRule": "編輯警示規則", - "ruleName": "規則名稱", - "ruleNameRequired": "名稱為必填", - "triggerType": "觸發條件", - "thresholdValue": "閾值(%)", - "durationSeconds": "持續時間(秒,0 = 立即觸發)", - "cooldownMinutes": "冷卻時間(分鐘)", - "channels": "通知頻道", - "noChannelsHint": "請先於「頻道」分頁新增頻道", - "ruleSaveFailed": "無法儲存規則" + "channelSaveFailed": "無法儲存頻道" }, "ai": { "title": "助理", diff --git a/src/ui/shell/tabUtils.tsx b/src/ui/shell/tabUtils.tsx index e158256b5..881dcd50f 100644 --- a/src/ui/shell/tabUtils.tsx +++ b/src/ui/shell/tabUtils.tsx @@ -25,7 +25,6 @@ import { Fingerprint, Hammer, Play, - Plug, ScrollText, Sparkles, Presentation, @@ -154,9 +153,6 @@ const FleetInventoryTab = lazy(() => const TermixIdPanel = lazy(() => import("@/sidebar/TermixIdPanel").then((m) => ({ default: m.TermixIdPanel })), ); -const AlertsPanel = lazy(() => - import("@/sidebar/AlertsPanel").then((m) => ({ default: m.AlertsPanel })), -); const SessionLogsPanel = lazy(() => import("@/sidebar/SessionLogsPanel").then((m) => ({ default: m.SessionLogsPanel, @@ -391,8 +387,6 @@ export function tabIcon(type: TabType) { return ; case "termix-id": return ; - case "alerts": - return ; case "session-logs": return ; case "snippets": @@ -721,13 +715,6 @@ export function renderTabContent( , ); - case "alerts": - return withTabSuspense( - - - , - ); - case "session-logs": return withTabSuspense( diff --git a/src/ui/shell/workspaceUtils.ts b/src/ui/shell/workspaceUtils.ts index a61141f7d..8fa7d07a1 100644 --- a/src/ui/shell/workspaceUtils.ts +++ b/src/ui/shell/workspaceUtils.ts @@ -26,7 +26,6 @@ export const WORKSPACE_CAPTURABLE_TYPES: TabType[] = [ "homepage", "fleet-inventory", "termix-id", - "alerts", "session-logs", "snippets", "macros", @@ -44,7 +43,6 @@ export const HOSTLESS_WORKSPACE_TAB_TYPES: TabType[] = [ "fleet-inventory", "docker", "termix-id", - "alerts", "session-logs", "snippets", "macros", diff --git a/src/ui/sidebar/AlertRuleDialog.tsx b/src/ui/sidebar/AlertRuleDialog.tsx deleted file mode 100644 index 5717706bd..000000000 --- a/src/ui/sidebar/AlertRuleDialog.tsx +++ /dev/null @@ -1,274 +0,0 @@ -import { useState, useEffect } from "react"; -import { useTranslation } from "react-i18next"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogFooter, -} from "@/components/dialog"; -import { Button } from "@/components/button"; -import { Input } from "@/components/input"; -import { toast } from "sonner"; -import { - createAlertRule, - updateAlertRule, - type AlertRule, - type NotificationChannel, -} from "@/api/alerts-api"; - -const TRIGGER_TYPES = [ - { value: "host_offline", label: "Host Offline", hasThreshold: false }, - { value: "host_online", label: "Host Online", hasThreshold: false }, - { value: "cpu_threshold", label: "CPU Usage Threshold", hasThreshold: true }, - { - value: "memory_threshold", - label: "Memory Usage Threshold", - hasThreshold: true, - }, - { - value: "disk_threshold", - label: "Disk Usage Threshold", - hasThreshold: true, - }, - { - value: "health_check_failure", - label: "Health Check Failure", - hasThreshold: false, - }, - { value: "user_login", label: "User SSH Login", hasThreshold: false }, -]; - -interface AlertRuleDialogProps { - open: boolean; - onOpenChange: (open: boolean) => void; - rule: AlertRule | null; - channels: NotificationChannel[]; - onSaved: () => void; -} - -export function AlertRuleDialog({ - open, - onOpenChange, - rule, - channels, - onSaved, -}: AlertRuleDialogProps) { - const { t } = useTranslation(); - const [name, setName] = useState(""); - const [triggerType, setTriggerType] = useState("host_offline"); - const [threshold, setThreshold] = useState("80"); - const [durationSeconds, setDurationSeconds] = useState("0"); - const [cooldownMinutes, setCooldownMinutes] = useState("15"); - const [selectedChannels, setSelectedChannels] = useState([]); - const [saving, setSaving] = useState(false); - - const triggerDef = TRIGGER_TYPES.find((tt) => tt.value === triggerType); - const hasThreshold = triggerDef?.hasThreshold ?? false; - - useEffect(() => { - if (!open) return; - if (rule) { - setName(rule.name); - setTriggerType(rule.triggerType); - setThreshold( - rule.thresholdValue != null ? String(rule.thresholdValue) : "80", - ); - setDurationSeconds( - rule.thresholdDurationSeconds != null - ? String(rule.thresholdDurationSeconds) - : "0", - ); - setCooldownMinutes(String(rule.cooldownMinutes)); - setSelectedChannels(rule.channelIds ?? []); - } else { - setName(""); - setTriggerType("host_offline"); - setThreshold("80"); - setDurationSeconds("0"); - setCooldownMinutes("15"); - setSelectedChannels([]); - } - }, [open, rule]); - - function toggleChannel(id: number) { - setSelectedChannels((prev) => - prev.includes(id) ? prev.filter((c) => c !== id) : [...prev, id], - ); - } - - async function handleSave() { - if (!name.trim()) { - toast.error(t("alerts.ruleNameRequired", "Name is required")); - return; - } - setSaving(true); - try { - const payload = { - name: name.trim(), - triggerType, - thresholdValue: hasThreshold ? Number(threshold) : null, - thresholdDurationSeconds: - hasThreshold && Number(durationSeconds) > 0 - ? Number(durationSeconds) - : null, - cooldownMinutes: Number(cooldownMinutes) || 15, - channels: selectedChannels, - }; - if (rule) { - await updateAlertRule(rule.id, payload); - } else { - await createAlertRule(payload); - } - onSaved(); - } catch { - toast.error(t("alerts.ruleSaveFailed", "Failed to save rule")); - } finally { - setSaving(false); - } - } - - return ( - - - - - {rule - ? t("alerts.editRule", "Edit Alert Rule") - : t("alerts.addRule", "Add Alert Rule")} - - - -
-
- - setName(e.target.value)} - className="text-sm" - /> -
- -
- -
- {TRIGGER_TYPES.map((tt) => ( - - ))} -
-
- - {hasThreshold && ( - <> -
- -
- setThreshold(e.target.value)} - className="w-20 text-sm" - /> - % -
-
-
- - setDurationSeconds(e.target.value)} - className="w-24 text-sm" - /> -
- - )} - -
- - setCooldownMinutes(e.target.value)} - className="w-24 text-sm" - /> -
- -
- - {channels.length === 0 ? ( - - {t( - "alerts.noChannelsHint", - "Add channels in the Channels tab first", - )} - - ) : ( -
- {channels.map((ch) => ( - - ))} -
- )} -
-
- - - - - -
-
- ); -} diff --git a/src/ui/sidebar/AlertsPanel.tsx b/src/ui/sidebar/AlertsPanel.tsx deleted file mode 100644 index b5180c3f8..000000000 --- a/src/ui/sidebar/AlertsPanel.tsx +++ /dev/null @@ -1,471 +0,0 @@ -import { useState, useEffect, useCallback } from "react"; -import { useTranslation } from "react-i18next"; -import { - Bell, - BellOff, - Check, - CheckCheck, - Trash2, - Plus, - Settings2, -} from "lucide-react"; -import { toast } from "sonner"; -import { Button } from "@/components/button"; -import { - getAlertFirings, - acknowledgeAlertFiring, - acknowledgeAllAlertFirings, - getAlertRules, - getNotificationChannels, - deleteAlertRule, - deleteNotificationChannel, - testNotificationChannel, - type AlertFiring, - type AlertRule, - type NotificationChannel, -} from "@/api/alerts-api"; -import { AlertRuleDialog } from "./AlertRuleDialog"; -import { NotificationChannelDialog } from "./NotificationChannelDialog"; - -type PanelTab = "firings" | "rules" | "channels"; - -const SEVERITY_CLASS: Record = { - info: "bg-blue-500/20 text-blue-400 border-blue-500/30", - warning: "bg-yellow-500/20 text-yellow-400 border-yellow-500/30", - critical: "bg-red-500/20 text-red-400 border-red-500/30", -}; - -function timeAgo(isoStr: string): string { - const ms = Date.now() - new Date(isoStr).getTime(); - if (!Number.isFinite(ms)) return ""; - const sec = Math.floor(ms / 1000); - if (sec < 60) return `${sec}s ago`; - const min = Math.floor(sec / 60); - if (min < 60) return `${min}m ago`; - const hr = Math.floor(min / 60); - if (hr < 24) return `${hr}h ago`; - return `${Math.floor(hr / 24)}d ago`; -} - -export function AlertsPanel() { - const { t } = useTranslation(); - const [tab, setTab] = useState("firings"); - - // Firings state - const [firings, setFirings] = useState([]); - const [firingsLoading, setFiringsLoading] = useState(true); - const [showAcknowledged, setShowAcknowledged] = useState(false); - - // Rules state - const [rules, setRules] = useState([]); - const [rulesLoading, setRulesLoading] = useState(false); - const [ruleDialogOpen, setRuleDialogOpen] = useState(false); - const [editRule, setEditRule] = useState(null); - - // Channels state - const [channels, setChannels] = useState([]); - const [channelsLoading, setChannelsLoading] = useState(false); - const [channelDialogOpen, setChannelDialogOpen] = useState(false); - const [editChannel, setEditChannel] = useState( - null, - ); - - const loadFirings = useCallback(() => { - setFiringsLoading(true); - getAlertFirings({ limit: 100 }) - .then(setFirings) - .catch(() => {}) - .finally(() => setFiringsLoading(false)); - }, []); - - const loadRules = useCallback(() => { - setRulesLoading(true); - getAlertRules() - .then(setRules) - .catch(() => {}) - .finally(() => setRulesLoading(false)); - }, []); - - const loadChannels = useCallback(() => { - setChannelsLoading(true); - getNotificationChannels() - .then(setChannels) - .catch(() => {}) - .finally(() => setChannelsLoading(false)); - }, []); - - useEffect(() => { - loadFirings(); - loadChannels(); - }, [loadFirings, loadChannels]); - - useEffect(() => { - if (tab === "rules") loadRules(); - if (tab === "channels") loadChannels(); - }, [tab, loadRules, loadChannels]); - - const visibleFirings = firings.filter((f) => - showAcknowledged ? true : !f.acknowledged, - ); - - async function handleAck(id: number) { - try { - await acknowledgeAlertFiring(id); - setFirings((prev) => - prev.map((f) => (f.id === id ? { ...f, acknowledged: true } : f)), - ); - } catch { - toast.error(t("alerts.ackFailed", "Failed to acknowledge alert")); - } - } - - async function handleAckAll() { - try { - await acknowledgeAllAlertFirings(); - setFirings((prev) => prev.map((f) => ({ ...f, acknowledged: true }))); - toast.success(t("alerts.allAcknowledged", "All alerts acknowledged")); - } catch { - toast.error(t("alerts.ackAllFailed", "Failed to acknowledge all alerts")); - } - } - - async function handleDeleteRule(id: number) { - if (!confirm(t("common.confirmDelete", "Delete this rule?"))) return; - try { - await deleteAlertRule(id); - setRules((prev) => prev.filter((r) => r.id !== id)); - toast.success(t("common.deleted", "Deleted")); - } catch { - toast.error(t("common.deleteFailed", "Delete failed")); - } - } - - async function handleDeleteChannel(id: number) { - if (!confirm(t("common.confirmDelete", "Delete this channel?"))) return; - try { - await deleteNotificationChannel(id); - setChannels((prev) => prev.filter((c) => c.id !== id)); - toast.success(t("common.deleted", "Deleted")); - } catch { - toast.error(t("common.deleteFailed", "Delete failed")); - } - } - - async function handleTestChannel(id: number) { - try { - await testNotificationChannel(id); - toast.success(t("alerts.testSent", "Test notification sent")); - } catch (err) { - const detail = err instanceof Error ? err.message : undefined; - toast.error( - detail - ? t( - "alerts.testFailedWithReason", - "Test notification failed: {{reason}}", - { reason: detail }, - ) - : t("alerts.testFailed", "Test notification failed"), - ); - } - } - - const unreadCount = firings.filter((f) => !f.acknowledged).length; - - return ( -
- {/* Tab strip */} -
- {(["firings", "rules", "channels"] as PanelTab[]).map((t_) => ( - - ))} -
- - {/* Firings tab */} - {tab === "firings" && ( -
-
- -
- {unreadCount > 0 && ( - - )} - -
- -
- {firingsLoading && ( -
- {t("common.loading", "Loading...")} -
- )} - {!firingsLoading && visibleFirings.length === 0 && ( -
- - - {t("alerts.noFirings", "No unacknowledged alerts")} - -
- )} - {!firingsLoading && - visibleFirings.map((firing) => ( -
-
- - {firing.severity} - - - {firing.hostName} - - {!firing.acknowledged && ( - - )} -
- - {firing.message} - -
- {firing.ruleName && {firing.ruleName}} - {timeAgo(firing.firedAt)} -
-
- ))} -
-
- )} - - {/* Rules tab */} - {tab === "rules" && ( -
-
- - {t("alerts.rulesDesc", "Alert rules trigger notifications")} - - -
- -
- {rulesLoading && ( -
- {t("common.loading", "Loading...")} -
- )} - {!rulesLoading && rules.length === 0 && ( -
- - - {t("alerts.noRules", "No alert rules configured")} - -
- )} - {!rulesLoading && - rules.map((rule) => ( -
-
-
- {rule.name} -
-
- {(rule.triggerType || "").replace(/_/g, " ")} -
-
-
- - -
- ))} -
-
- )} - - {/* Channels tab */} - {tab === "channels" && ( -
-
- - {t("alerts.channelsDesc", "Where alert notifications are sent")} - - -
- -
- {channelsLoading && ( -
- {t("common.loading", "Loading...")} -
- )} - {!channelsLoading && channels.length === 0 && ( -
- - - {t( - "alerts.noChannels", - "No notification channels configured", - )} - -
- )} - {!channelsLoading && - channels.map((channel) => ( -
-
-
- {channel.name} -
-
- {channel.type} -
-
-
- - - -
- ))} -
-
- )} - - { - setRuleDialogOpen(false); - loadRules(); - }} - /> - - { - setChannelDialogOpen(false); - loadChannels(); - }} - /> -
- ); -} diff --git a/src/ui/sidebar/AppRail.tsx b/src/ui/sidebar/AppRail.tsx index c9f818291..63d3e7b14 100644 --- a/src/ui/sidebar/AppRail.tsx +++ b/src/ui/sidebar/AppRail.tsx @@ -1,7 +1,6 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, type ReactElement } from "react"; import { useTranslation } from "react-i18next"; import { - Bell, Check, LogOut, PanelRight, @@ -12,7 +11,6 @@ import { User, } from "lucide-react"; import type { SplitMode, TabType, ToolsTab } from "@/types/ui-types"; -import { getAlertFirings } from "@/api/alerts-api"; import { isElectron } from "@/lib/electron"; import { readRailPreference, setRailPreference } from "./rail-preferences"; import { visibleRailItems } from "./rail-items"; @@ -31,7 +29,6 @@ export type RailView = | "session-logs" | "user-profile" | "admin-settings" - | "alerts" | "automations" | "ai" | "fleets" @@ -148,49 +145,6 @@ export function AppRail({ promotable?: boolean; rightDockable?: boolean; } | null>(null); - const [unreadAlerts, setUnreadAlerts] = useState(0); - - useEffect(() => { - let cancelled = false; - let intervalId: ReturnType | null = null; - - const poll = () => { - if (document.visibilityState === "hidden") return; - getAlertFirings({ acknowledged: false, limit: 50 }) - .then((firings) => { - if (!cancelled) setUnreadAlerts(firings.length); - }) - .catch(() => {}); - }; - - const start = () => { - if (intervalId !== null) return; - intervalId = setInterval(poll, 30000); - }; - const stop = () => { - if (intervalId === null) return; - clearInterval(intervalId); - intervalId = null; - }; - const onVisibility = () => { - if (document.visibilityState === "hidden") { - stop(); - return; - } - poll(); - start(); - }; - - poll(); - if (document.visibilityState !== "hidden") start(); - document.addEventListener("visibilitychange", onVisibility); - - return () => { - cancelled = true; - stop(); - document.removeEventListener("visibilitychange", onVisibility); - }; - }, []); const [hiddenTabs, setHiddenTabs] = useState>(() => { try { const stored = localStorage.getItem("hiddenRailTabs"); @@ -457,28 +411,29 @@ export function AppRail({ style={{ width: railExpanded ? "calc(100% - 16px)" : 20 }} /> )} - {[ - { - view: "alerts" as RailView, - icon: , - title: t("nav.alerts"), - promotable: true, - }, - { - view: "user-profile" as RailView, - icon: , - title: t("nav.userProfile"), - }, - ...(isAdmin - ? [ - { - view: "admin-settings" as RailView, - icon: , - title: t("nav.admin"), - }, - ] - : []), - ].map((item) => ( + {( + [ + { + view: "user-profile" as RailView, + icon: , + title: t("nav.userProfile"), + }, + ...(isAdmin + ? [ + { + view: "admin-settings" as RailView, + icon: , + title: t("nav.admin"), + }, + ] + : []), + ] as { + view: RailView; + icon: ReactElement; + title: string; + promotable?: boolean; + }[] + ).map((item) => (