505 lines
19 KiB
PL/PgSQL
505 lines
19 KiB
PL/PgSQL
-- Voxyz Autonomous Architecture - Phase 10 Database Schema
|
|
-- Creates tables for Proposal Service, Policy System, Trigger Rules, and Daily Missions
|
|
|
|
-- Enable UUID extension
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
|
|
-- ============================================
|
|
-- 1. MISSION PROPOSALS TABLE
|
|
-- Stores AI-generated daily mission proposals
|
|
-- ============================================
|
|
CREATE TABLE IF NOT EXISTS ops_mission_proposals (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
-- Proposal metadata
|
|
proposal_date DATE NOT NULL,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'pending'
|
|
CHECK (status IN ('pending', 'approved', 'rejected', 'scheduled', 'completed', 'expired')),
|
|
|
|
-- Priority scoring (0-100)
|
|
priority_score INTEGER NOT NULL DEFAULT 50
|
|
CHECK (priority_score >= 0 AND priority_score <= 100),
|
|
|
|
-- Cap Gates compliance
|
|
passes_cap_gates BOOLEAN NOT NULL DEFAULT false,
|
|
cap_gate_violations JSONB DEFAULT '[]'::jsonb,
|
|
|
|
-- Source task references (links to gantt tasks)
|
|
source_task_ids TEXT[] DEFAULT '{}',
|
|
source_project_ids TEXT[] DEFAULT '{}',
|
|
|
|
-- Proposal content
|
|
title TEXT NOT NULL,
|
|
description TEXT,
|
|
rationale TEXT,
|
|
|
|
-- AI analysis summary
|
|
ai_analysis JSONB DEFAULT '{}'::jsonb,
|
|
|
|
-- Scheduling
|
|
suggested_start_time TIMESTAMP WITH TIME ZONE,
|
|
suggested_end_time TIMESTAMP WITH TIME ZONE,
|
|
estimated_duration_minutes INTEGER,
|
|
|
|
-- User decisions
|
|
approved_at TIMESTAMP WITH TIME ZONE,
|
|
approved_by UUID REFERENCES users(id),
|
|
rejected_at TIMESTAMP WITH TIME ZONE,
|
|
rejection_reason TEXT,
|
|
|
|
-- Calendar integration
|
|
calendar_event_id TEXT,
|
|
calendar_synced_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
-- Execution tracking
|
|
executed_at TIMESTAMP WITH TIME ZONE,
|
|
execution_notes TEXT,
|
|
|
|
-- Timestamps for lifecycle
|
|
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
|
|
-- Indexes
|
|
CONSTRAINT valid_dates CHECK (suggested_end_time > suggested_start_time OR suggested_start_time IS NULL)
|
|
);
|
|
|
|
-- Create indexes for mission_proposals
|
|
CREATE INDEX IF NOT EXISTS idx_proposals_status ON ops_mission_proposals(status);
|
|
CREATE INDEX IF NOT EXISTS idx_proposals_date ON ops_mission_proposals(proposal_date);
|
|
CREATE INDEX IF NOT EXISTS idx_proposals_priority ON ops_mission_proposals(priority_score DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_proposals_created_at ON ops_mission_proposals(created_at DESC);
|
|
|
|
-- ============================================
|
|
-- 2. POLICY TABLE
|
|
-- Stores operational policies and constraints
|
|
-- ============================================
|
|
CREATE TABLE IF NOT EXISTS ops_policy (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
-- Policy metadata
|
|
name VARCHAR(100) NOT NULL UNIQUE,
|
|
description TEXT,
|
|
category VARCHAR(50) NOT NULL
|
|
CHECK (category IN ('cap_gates', 'scheduling', 'prioritization', 'execution', 'general')),
|
|
|
|
-- Policy configuration
|
|
config JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
|
|
-- Policy rules (stored as JSON for flexibility)
|
|
rules JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
|
|
-- Status
|
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
effective_from TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
effective_until TIMESTAMP WITH TIME ZONE,
|
|
|
|
-- Versioning
|
|
version INTEGER NOT NULL DEFAULT 1,
|
|
previous_version_id UUID REFERENCES ops_policy(id),
|
|
|
|
-- Audit
|
|
created_by UUID REFERENCES users(id),
|
|
updated_by UUID REFERENCES users(id)
|
|
);
|
|
|
|
-- Create indexes for policy
|
|
CREATE INDEX IF NOT EXISTS idx_policy_category ON ops_policy(category);
|
|
CREATE INDEX IF NOT EXISTS idx_policy_active ON ops_policy(is_active) WHERE is_active = true;
|
|
|
|
-- ============================================
|
|
-- 3. TRIGGER RULES TABLE
|
|
-- Stores automated trigger rules for the system
|
|
-- ============================================
|
|
CREATE TABLE IF NOT EXISTS ops_trigger_rules (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
-- Rule metadata
|
|
name VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
|
|
-- Trigger type
|
|
trigger_type VARCHAR(50) NOT NULL
|
|
CHECK (trigger_type IN ('deadline_approaching', 'task_blocked', 'high_priority_created',
|
|
'stale_task', 'sprint_ending', 'milestone_reached',
|
|
'daily_mission_time', 'manual', 'calendar_conflict')),
|
|
|
|
-- Trigger conditions (JSON for complex conditions)
|
|
conditions JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
|
|
-- Action to take when triggered
|
|
action_type VARCHAR(50) NOT NULL
|
|
CHECK (action_type IN ('create_proposal', 'send_notification', 'escalate_priority',
|
|
'auto_schedule', 'request_review', 'update_status')),
|
|
|
|
action_config JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
|
|
-- Priority for rule evaluation order
|
|
priority INTEGER NOT NULL DEFAULT 100,
|
|
|
|
-- Status
|
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
|
|
-- Rate limiting
|
|
cooldown_minutes INTEGER DEFAULT 60,
|
|
max_triggers_per_day INTEGER DEFAULT 10,
|
|
|
|
-- Tracking
|
|
last_triggered_at TIMESTAMP WITH TIME ZONE,
|
|
trigger_count INTEGER DEFAULT 0,
|
|
|
|
-- Audit
|
|
created_by UUID REFERENCES users(id),
|
|
updated_by UUID REFERENCES users(id)
|
|
);
|
|
|
|
-- Create indexes for trigger_rules
|
|
CREATE INDEX IF NOT EXISTS idx_trigger_rules_type ON ops_trigger_rules(trigger_type);
|
|
CREATE INDEX IF NOT EXISTS idx_trigger_rules_active ON ops_trigger_rules(is_active) WHERE is_active = true;
|
|
CREATE INDEX IF NOT EXISTS idx_trigger_rules_priority ON ops_trigger_rules(priority);
|
|
|
|
-- ============================================
|
|
-- 4. CAP GATES TABLE
|
|
-- Stores queue management cap gates
|
|
-- ============================================
|
|
CREATE TABLE IF NOT EXISTS ops_cap_gates (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
-- Gate metadata
|
|
name VARCHAR(100) NOT NULL UNIQUE,
|
|
description TEXT,
|
|
|
|
-- Gate type
|
|
gate_type VARCHAR(50) NOT NULL
|
|
CHECK (gate_type IN ('daily_mission_limit', 'concurrent_high_priority',
|
|
'workload_capacity', 'focus_time_minimum',
|
|
'calendar_buffer', 'reaction_ratio')),
|
|
|
|
-- Configuration
|
|
max_value INTEGER NOT NULL,
|
|
min_value INTEGER DEFAULT 0,
|
|
unit VARCHAR(20) DEFAULT 'count',
|
|
|
|
-- Current state
|
|
current_value INTEGER DEFAULT 0,
|
|
last_evaluated_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
-- Policy reference
|
|
policy_id UUID REFERENCES ops_policy(id),
|
|
|
|
-- Status
|
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
is_blocking BOOLEAN NOT NULL DEFAULT false,
|
|
|
|
-- Evaluation window
|
|
evaluation_window_hours INTEGER DEFAULT 24,
|
|
|
|
-- Audit
|
|
created_by UUID REFERENCES users(id),
|
|
updated_by UUID REFERENCES users(id)
|
|
);
|
|
|
|
-- Create indexes for cap_gates
|
|
CREATE INDEX IF NOT EXISTS idx_cap_gates_type ON ops_cap_gates(gate_type);
|
|
CREATE INDEX IF NOT EXISTS idx_cap_gates_active ON ops_cap_gates(is_active) WHERE is_active = true;
|
|
|
|
-- ============================================
|
|
-- 5. DAILY MISSIONS TABLE
|
|
-- Stores generated and scheduled daily missions
|
|
-- ============================================
|
|
CREATE TABLE IF NOT EXISTS ops_daily_missions (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
-- Mission date
|
|
mission_date DATE NOT NULL,
|
|
|
|
-- Generation metadata
|
|
generated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
generated_by VARCHAR(50) DEFAULT 'ai_agent'
|
|
CHECK (generated_by IN ('ai_agent', 'manual', 'trigger')),
|
|
|
|
-- Mission status
|
|
status VARCHAR(20) NOT NULL DEFAULT 'draft'
|
|
CHECK (status IN ('draft', 'review', 'approved', 'scheduled', 'in_progress', 'completed', 'canceled')),
|
|
|
|
-- Proposal references (up to 3 missions per day)
|
|
primary_mission_id UUID REFERENCES ops_mission_proposals(id),
|
|
secondary_mission_id UUID REFERENCES ops_mission_proposals(id),
|
|
tertiary_mission_id UUID REFERENCES ops_mission_proposals(id),
|
|
|
|
-- Total estimated time
|
|
total_estimated_minutes INTEGER,
|
|
|
|
-- Focus time allocation
|
|
focus_time_start TIMESTAMP WITH TIME ZONE,
|
|
focus_time_end TIMESTAMP WITH TIME ZONE,
|
|
focus_time_minutes INTEGER,
|
|
|
|
-- Calendar blocks
|
|
calendar_blocks JSONB DEFAULT '[]'::jsonb,
|
|
|
|
-- Reaction matrix tracking
|
|
planned_reactions INTEGER DEFAULT 0,
|
|
actual_reactions INTEGER DEFAULT 0,
|
|
reaction_ratio DECIMAL(3,2) DEFAULT 0.00,
|
|
|
|
-- Completion tracking
|
|
completed_at TIMESTAMP WITH TIME ZONE,
|
|
completion_notes TEXT,
|
|
completion_rating INTEGER CHECK (completion_rating >= 1 AND completion_rating <= 5),
|
|
|
|
-- Feedback for AI learning
|
|
user_feedback JSONB DEFAULT '{}'::jsonb,
|
|
|
|
-- Unique constraint for one mission set per day
|
|
CONSTRAINT unique_daily_mission UNIQUE (mission_date)
|
|
);
|
|
|
|
-- Create indexes for daily_missions
|
|
CREATE INDEX IF NOT EXISTS idx_daily_missions_date ON ops_daily_missions(mission_date);
|
|
CREATE INDEX IF NOT EXISTS idx_daily_missions_status ON ops_daily_missions(status);
|
|
|
|
-- ============================================
|
|
-- 6. CALENDAR BLOCKS TABLE
|
|
-- Stores scheduled focus time blocks
|
|
-- ============================================
|
|
CREATE TABLE IF NOT EXISTS ops_calendar_blocks (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
-- Block metadata
|
|
block_date DATE NOT NULL,
|
|
|
|
-- Time range
|
|
start_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
end_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
|
|
-- Block type
|
|
block_type VARCHAR(50) NOT NULL
|
|
CHECK (block_type IN ('deep_work', 'mission_execution', 'planning',
|
|
'reaction_time', 'buffer', 'meeting')),
|
|
|
|
-- Linked mission
|
|
mission_id UUID REFERENCES ops_daily_missions(id),
|
|
proposal_id UUID REFERENCES ops_mission_proposals(id),
|
|
|
|
-- External calendar integration
|
|
calendar_event_id TEXT,
|
|
calendar_provider VARCHAR(20) DEFAULT 'google'
|
|
CHECK (calendar_provider IN ('google', 'outlook', 'apple', 'other')),
|
|
calendar_synced BOOLEAN DEFAULT false,
|
|
calendar_synced_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
-- Status
|
|
status VARCHAR(20) DEFAULT 'scheduled'
|
|
CHECK (status IN ('scheduled', 'active', 'completed', 'canceled', 'rescheduled')),
|
|
|
|
-- Notes
|
|
notes TEXT,
|
|
|
|
CONSTRAINT valid_block_times CHECK (end_time > start_time)
|
|
);
|
|
|
|
-- Create indexes for calendar_blocks
|
|
CREATE INDEX IF NOT EXISTS idx_calendar_blocks_date ON ops_calendar_blocks(block_date);
|
|
CREATE INDEX IF NOT EXISTS idx_calendar_blocks_mission ON ops_calendar_blocks(mission_id);
|
|
CREATE INDEX IF NOT EXISTS idx_calendar_blocks_status ON ops_calendar_blocks(status);
|
|
|
|
-- ============================================
|
|
-- 7. TRIGGER LOG TABLE
|
|
-- Stores trigger rule execution history
|
|
-- ============================================
|
|
CREATE TABLE IF NOT EXISTS ops_trigger_log (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
-- Trigger reference
|
|
rule_id UUID REFERENCES ops_trigger_rules(id),
|
|
rule_name VARCHAR(100),
|
|
|
|
-- Execution details
|
|
triggered_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
trigger_type VARCHAR(50) NOT NULL,
|
|
|
|
-- Context
|
|
context JSONB DEFAULT '{}'::jsonb,
|
|
task_ids TEXT[] DEFAULT '{}',
|
|
|
|
-- Result
|
|
action_taken VARCHAR(50),
|
|
action_result TEXT,
|
|
success BOOLEAN DEFAULT true,
|
|
error_message TEXT,
|
|
|
|
-- Proposal created (if applicable)
|
|
proposal_id UUID REFERENCES ops_mission_proposals(id)
|
|
);
|
|
|
|
-- Create indexes for trigger_log
|
|
CREATE INDEX IF NOT EXISTS idx_trigger_log_rule ON ops_trigger_log(rule_id);
|
|
CREATE INDEX IF NOT EXISTS idx_trigger_log_created ON ops_trigger_log(created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_trigger_log_type ON ops_trigger_log(trigger_type);
|
|
|
|
-- ============================================
|
|
-- 8. AGENT EXECUTION LOG TABLE
|
|
-- Stores AI agent execution history
|
|
-- ============================================
|
|
CREATE TABLE IF NOT EXISTS ops_agent_execution_log (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
-- Execution metadata
|
|
agent_name VARCHAR(50) NOT NULL
|
|
CHECK (agent_name IN ('proposal_generator', 'cap_gate_validator', 'calendar_scheduler',
|
|
'trigger_monitor', 'mission_optimizer', 'stale_task_detector')),
|
|
|
|
execution_type VARCHAR(50) NOT NULL
|
|
CHECK (execution_type IN ('scheduled', 'triggered', 'manual', 'reaction')),
|
|
|
|
-- Execution details
|
|
started_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
completed_at TIMESTAMP WITH TIME ZONE,
|
|
duration_ms INTEGER,
|
|
|
|
-- Input/Output
|
|
input_summary JSONB DEFAULT '{}'::jsonb,
|
|
output_summary JSONB DEFAULT '{}'::jsonb,
|
|
|
|
-- Results
|
|
proposals_created INTEGER DEFAULT 0,
|
|
proposals_approved INTEGER DEFAULT 0,
|
|
tasks_analyzed INTEGER DEFAULT 0,
|
|
|
|
-- Status
|
|
status VARCHAR(20) DEFAULT 'running'
|
|
CHECK (status IN ('running', 'success', 'partial', 'failed')),
|
|
error_message TEXT,
|
|
|
|
-- Performance metrics
|
|
ai_tokens_used INTEGER,
|
|
ai_cost_usd DECIMAL(10,4)
|
|
);
|
|
|
|
-- Create indexes for agent_execution_log
|
|
CREATE INDEX IF NOT EXISTS idx_agent_log_agent ON ops_agent_execution_log(agent_name);
|
|
CREATE INDEX IF NOT EXISTS idx_agent_log_created ON ops_agent_execution_log(created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_agent_log_status ON ops_agent_execution_log(status);
|
|
|
|
-- ============================================
|
|
-- DEFAULT POLICY INSERTS
|
|
-- ============================================
|
|
|
|
-- Insert default Cap Gates policies
|
|
INSERT INTO ops_policy (name, description, category, config, rules) VALUES
|
|
('daily_mission_limit', 'Maximum number of missions per day', 'cap_gates',
|
|
'{"max_missions_per_day": 3, "min_missions_per_day": 1}'::jsonb,
|
|
'{"enforce": true, "allow_override": false}'::jsonb),
|
|
|
|
('concurrent_high_priority', 'Limit on concurrent high-priority work', 'cap_gates',
|
|
'{"max_concurrent_high_priority": 2, "high_priority_threshold": 75}'::jsonb,
|
|
'{"enforce": true, "escalation_required": true}'::jsonb),
|
|
|
|
('workload_capacity', 'Daily workload capacity in minutes', 'cap_gates',
|
|
'{"max_daily_minutes": 480, "min_focus_block_minutes": 90}'::jsonb,
|
|
'{"enforce": true, "buffer_percentage": 20}'::jsonb),
|
|
|
|
('focus_time_minimum', 'Minimum required focus time per day', 'cap_gates',
|
|
'{"min_focus_minutes": 120, "preferred_focus_start": "09:00", "preferred_focus_end": "17:00"}'::jsonb,
|
|
'{"enforce": true, "auto_protect": true}'::jsonb),
|
|
|
|
('calendar_buffer', 'Buffer time between calendar events', 'cap_gates',
|
|
'{"min_buffer_minutes": 15, "default_buffer_minutes": 30}'::jsonb,
|
|
'{"enforce": true, "auto_add_buffer": true}'::jsonb),
|
|
|
|
('reaction_ratio', 'Percentage of time reserved for spontaneous reactions', 'cap_gates',
|
|
'{"reaction_ratio": 0.30, "min_reaction_minutes": 60}'::jsonb,
|
|
'{"enforce": false, "track_only": true}'::jsonb);
|
|
|
|
-- Insert default Trigger Rules
|
|
INSERT INTO ops_trigger_rules (name, description, trigger_type, conditions, action_type, action_config, priority) VALUES
|
|
('deadline_approaching_24h', 'Trigger when deadline is within 24 hours', 'deadline_approaching',
|
|
'{"hours_before": 24, "priority": "high"}'::jsonb, 'create_proposal',
|
|
'{"priority_boost": 20, "rationale_template": "Deadline approaching in {{hours}} hours"}'::jsonb, 100),
|
|
|
|
('deadline_approaching_72h', 'Trigger when deadline is within 72 hours', 'deadline_approaching',
|
|
'{"hours_before": 72, "priority": "medium"}'::jsonb, 'create_proposal',
|
|
'{"priority_boost": 10, "rationale_template": "Deadline approaching in {{hours}} hours"}'::jsonb, 90),
|
|
|
|
('task_blocked_24h', 'Trigger when task has been blocked for 24+ hours', 'task_blocked',
|
|
'{"blocked_hours": 24}'::jsonb, 'create_proposal',
|
|
'{"action": "escalate_and_propose_alternative", "priority_boost": 30}'::jsonb, 95),
|
|
|
|
('high_priority_created', 'Trigger when high priority task is created', 'high_priority_created',
|
|
'{"priority": "urgent"}'::jsonb, 'create_proposal',
|
|
'{"immediate_review": true, "priority_boost": 25}'::jsonb, 110),
|
|
|
|
('stale_task_7d', 'Trigger when task is stale for 7+ days', 'stale_task',
|
|
'{"stale_days": 7, "status_in": ["todo", "in-progress"]}'::jsonb, 'create_proposal',
|
|
'{"action": "review_and_reprioritize", "priority_boost": 15}'::jsonb, 80),
|
|
|
|
('stale_task_14d', 'Trigger when task is stale for 14+ days', 'stale_task',
|
|
'{"stale_days": 14, "status_in": ["todo", "in-progress"]}'::jsonb, 'create_proposal',
|
|
'{"action": "flag_for_review", "priority_boost": 25}'::jsonb, 85),
|
|
|
|
('sprint_ending_3d', 'Trigger when sprint ends in 3 days', 'sprint_ending',
|
|
'{"days_before": 3}'::jsonb, 'create_proposal',
|
|
'{"focus": "sprint_completion", "priority_boost": 20}'::jsonb, 88),
|
|
|
|
('daily_mission_generation', 'Trigger daily mission generation at 7 AM', 'daily_mission_time',
|
|
'{"hour": 7, "minute": 0}'::jsonb, 'create_proposal',
|
|
'{"generate_count": 3, "include_reactions": true}'::jsonb, 120);
|
|
|
|
-- Insert default Cap Gates
|
|
INSERT INTO ops_cap_gates (name, description, gate_type, max_value, min_value, unit, policy_id) VALUES
|
|
('daily_mission_count', 'Maximum missions per day', 'daily_mission_limit', 3, 1, 'count',
|
|
(SELECT id FROM ops_policy WHERE name = 'daily_mission_limit')),
|
|
|
|
('concurrent_high_priority', 'Concurrent high priority items', 'concurrent_high_priority', 2, 0, 'count',
|
|
(SELECT id FROM ops_policy WHERE name = 'concurrent_high_priority')),
|
|
|
|
('daily_workload', 'Daily workload capacity', 'workload_capacity', 480, 240, 'minutes',
|
|
(SELECT id FROM ops_policy WHERE name = 'workload_capacity')),
|
|
|
|
('daily_focus_time', 'Minimum daily focus time', 'focus_time_minimum', 480, 120, 'minutes',
|
|
(SELECT id FROM ops_policy WHERE name = 'focus_time_minimum')),
|
|
|
|
('reaction_time_reserve', 'Time reserved for reactions', 'reaction_ratio', 144, 60, 'minutes',
|
|
(SELECT id FROM ops_policy WHERE name = 'reaction_ratio'));
|
|
|
|
-- Create updated_at trigger function
|
|
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.updated_at = NOW();
|
|
RETURN NEW;
|
|
END;
|
|
$$ language 'plpgsql';
|
|
|
|
-- Create updated_at triggers for all tables
|
|
CREATE TRIGGER update_ops_mission_proposals_updated_at BEFORE UPDATE ON ops_mission_proposals
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_ops_policy_updated_at BEFORE UPDATE ON ops_policy
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_ops_trigger_rules_updated_at BEFORE UPDATE ON ops_trigger_rules
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_ops_cap_gates_updated_at BEFORE UPDATE ON ops_cap_gates
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_ops_daily_missions_updated_at BEFORE UPDATE ON ops_daily_missions
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_ops_calendar_blocks_updated_at BEFORE UPDATE ON ops_calendar_blocks
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|