feat(db): add bot_id column, constraints, enforce DATABASE_URL

- Extend `system_automations` with a non‑null `bot_id` UUID column, create an index on it, and add a unique constraint on `(bot_id, kind, param)` to support upserts.
- Add a unique constraint on `bot_configuration.config_key` to prevent duplicate configuration keys.
- Include migration guards to ensure the new constraint is only created once.
- Remove automatic writing of drive configuration to a `.env` file, cleaning up side‑effects during config loading.
- Change database connection handling to require `DATABASE_URL` to be set (no fallback), making the environment initialization explicit.
This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2025-11-05 08:47:28 -03:00
parent f0b8902042
commit 02c36a8888
7 changed files with 40 additions and 39 deletions

View file

@ -1,15 +0,0 @@
-- Migration 6.0.10: Add unique constraint for system_automations upsert
-- Description: Creates a unique constraint matching the ON CONFLICT target in set_schedule.rs
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'system_automations_bot_kind_param_unique'
) THEN
ALTER TABLE public.system_automations
ADD CONSTRAINT system_automations_bot_kind_param_unique
UNIQUE (bot_id, kind, param);
END IF;
END
$$;

View file

@ -8,3 +8,39 @@ ALTER TABLE public.system_automations ADD COLUMN IF NOT EXISTS name VARCHAR(255)
-- Create index on name column for faster lookups -- Create index on name column for faster lookups
CREATE INDEX IF NOT EXISTS idx_system_automations_name ON public.system_automations(name); CREATE INDEX IF NOT EXISTS idx_system_automations_name ON public.system_automations(name);
ALTER TABLE bot_configuration
ADD CONSTRAINT bot_configuration_config_key_unique UNIQUE (config_key);
-- Migration 6.0.9: Add bot_id column to system_automations
-- Description: Introduces a bot_id column to associate automations with a specific bot.
-- The column is added as UUID and indexed for efficient queries.
-- Add bot_id column if it does not exist
ALTER TABLE public.system_automations
ADD COLUMN IF NOT EXISTS bot_id UUID NOT NULL;
-- Create an index on bot_id for faster lookups
CREATE INDEX IF NOT EXISTS idx_system_automations_bot_id
ON public.system_automations (bot_id);
ALTER TABLE public.system_automations
ADD CONSTRAINT IF NOT EXISTS system_automations_bot_kind_param_unique
UNIQUE (bot_id, kind, param);
-- Migration 6.0.10: Add unique constraint for system_automations upsert
-- Description: Creates a unique constraint matching the ON CONFLICT target in set_schedule.rs
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'system_automations_bot_kind_param_unique'
) THEN
ALTER TABLE public.system_automations
ADD CONSTRAINT system_automations_bot_kind_param_unique
UNIQUE (bot_id, kind, param);
END IF;
END
$$;

View file

@ -1,2 +0,0 @@
ALTER TABLE bot_configuration
ADD CONSTRAINT bot_configuration_config_key_unique UNIQUE (config_key);

View file

@ -1,16 +0,0 @@
-- Migration 6.0.9: Add bot_id column to system_automations
-- Description: Introduces a bot_id column to associate automations with a specific bot.
-- The column is added as UUID and indexed for efficient queries.
-- Add bot_id column if it does not exist
ALTER TABLE public.system_automations
ADD COLUMN IF NOT EXISTS bot_id UUID NOT NULL;
-- Create an index on bot_id for faster lookups
CREATE INDEX IF NOT EXISTS idx_system_automations_bot_id
ON public.system_automations (bot_id);
ALTER TABLE public.system_automations
ADD CONSTRAINT IF NOT EXISTS system_automations_bot_kind_param_unique
UNIQUE (bot_id, kind, param);

View file

@ -132,11 +132,6 @@ impl AppConfig {
use_ssl: get_bool("DRIVE_USE_SSL", false), use_ssl: get_bool("DRIVE_USE_SSL", false),
}; };
// Write drive config to .env file
if let Err(e) = write_drive_config_to_env(&drive) {
warn!("Failed to write drive config to .env: {}", e);
}
Ok(AppConfig { Ok(AppConfig {
drive, drive,
server: ServerConfig { server: ServerConfig {

View file

@ -109,9 +109,11 @@ async fn main() -> std::io::Result<()> {
let env_path = std::env::current_dir()?.join("botserver-stack").join(".env"); let env_path = std::env::current_dir()?.join("botserver-stack").join(".env");
let cfg = if env_path.exists() { let cfg = if env_path.exists() {
info!("Environment already initialized, skipping bootstrap"); info!("Environment already initialized, skipping bootstrap");
match diesel::Connection::establish( match diesel::Connection::establish(
&std::env::var("DATABASE_URL") &std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgres://gbuser:@localhost:5432/botserver".to_string()), .unwrap()
) { ) {
Ok(mut conn) => AppConfig::from_database(&mut conn).expect("Failed to load config from DB"), Ok(mut conn) => AppConfig::from_database(&mut conn).expect("Failed to load config from DB"),
Err(_) => AppConfig::from_env().expect("Failed to load config from env"), Err(_) => AppConfig::from_env().expect("Failed to load config from env"),

1
src/shared/schema.rs Normal file
View file

@ -0,0 +1 @@
// @generated automatically by Diesel CLI.