first commit

This commit is contained in:
2026-08-26 14:21:53 +03:00
commit fef66cd9dd
38 changed files with 5783 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
-- ConfigVault Database Schema
-- Run this in your Supabase SQL Editor
-- Enable UUID extension
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- ============================================
-- APPS TABLE
-- ============================================
CREATE TABLE apps (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
description TEXT,
icon_url TEXT,
api_key TEXT UNIQUE NOT NULL DEFAULT encode(gen_random_bytes(32), 'hex'),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- ============================================
-- ENVIRONMENTS TABLE
-- ============================================
CREATE TABLE environments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
app_id UUID NOT NULL REFERENCES apps(id) ON DELETE CASCADE,
name TEXT NOT NULL CHECK (name IN ('development', 'staging', 'production')),
UNIQUE(app_id, name)
);
-- ============================================
-- CONFIG ENTRIES TABLE
-- ============================================
CREATE TABLE config_entries (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
environment_id UUID NOT NULL REFERENCES environments(id) ON DELETE CASCADE,
key TEXT NOT NULL,
value TEXT NOT NULL,
type TEXT NOT NULL DEFAULT 'text' CHECK (type IN ('text', 'secret', 'url', 'json', 'boolean', 'number')),
description TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(environment_id, key)
);
-- ============================================
-- AUDIT LOGS TABLE
-- ============================================
CREATE TABLE audit_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
app_id UUID REFERENCES apps(id) ON DELETE SET NULL,
environment TEXT,
action TEXT NOT NULL CHECK (action IN ('create', 'update', 'delete', 'rotate_key', 'create_app', 'delete_app')),
key TEXT,
old_value TEXT, -- null for creates
actor TEXT NOT NULL DEFAULT 'admin',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- ============================================
-- AUTO-CREATE 3 ENVIRONMENTS ON NEW APP
-- ============================================
CREATE OR REPLACE FUNCTION create_default_environments()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO environments (app_id, name) VALUES
(NEW.id, 'development'),
(NEW.id, 'staging'),
(NEW.id, 'production');
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER on_app_created
AFTER INSERT ON apps
FOR EACH ROW EXECUTE FUNCTION create_default_environments();
-- ============================================
-- AUTO-UPDATE updated_at
-- ============================================
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER apps_updated_at
BEFORE UPDATE ON apps
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER config_entries_updated_at
BEFORE UPDATE ON config_entries
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- ============================================
-- ROW LEVEL SECURITY (disable for service role)
-- ============================================
ALTER TABLE apps DISABLE ROW LEVEL SECURITY;
ALTER TABLE environments DISABLE ROW LEVEL SECURITY;
ALTER TABLE config_entries DISABLE ROW LEVEL SECURITY;
ALTER TABLE audit_logs DISABLE ROW LEVEL SECURITY;
-- ============================================
-- INDEXES
-- ============================================
CREATE INDEX idx_environments_app_id ON environments(app_id);
CREATE INDEX idx_config_entries_environment_id ON config_entries(environment_id);
CREATE INDEX idx_audit_logs_app_id ON audit_logs(app_id);
CREATE INDEX idx_apps_api_key ON apps(api_key);
CREATE INDEX idx_apps_slug ON apps(slug);