96 lines
4.8 KiB
SQL
96 lines
4.8 KiB
SQL
CREATE TABLE IF NOT EXISTS business_parser_settings (
|
|
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
route_id text NOT NULL,
|
|
mode text NOT NULL DEFAULT 'ai',
|
|
revision bigint NOT NULL DEFAULT 1,
|
|
updated_by uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (organization_id, route_id),
|
|
CONSTRAINT business_parser_settings_route_check CHECK (route_id IN (
|
|
'team_order_create', 'team_order_batch_create', 'shared_plan_create',
|
|
'shared_child_order_create', 'passenger_list_import_independent',
|
|
'passenger_list_import_shared_child', 'arrangement_guide_create',
|
|
'arrangement_vehicle_create', 'arrangement_hotel_create',
|
|
'arrangement_transport_create', 'arrangement_other_create',
|
|
'order_update_shared_plan', 'order_update_shared_child',
|
|
'order_update_independent', 'arrangement_hotel_update',
|
|
'order_cancel', 'order_restore', 'confirmation_export'
|
|
)),
|
|
CONSTRAINT business_parser_settings_mode_check CHECK (mode IN ('ai', 'shadow', 'auto', 'program')),
|
|
CONSTRAINT business_parser_settings_revision_check CHECK (revision >= 1)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS business_parser_settings_updated_idx
|
|
ON business_parser_settings (organization_id, updated_at DESC);
|
|
|
|
ALTER TABLE tasks
|
|
ADD COLUMN IF NOT EXISTS business_route_id text,
|
|
ADD COLUMN IF NOT EXISTS input_contract_version text,
|
|
ADD COLUMN IF NOT EXISTS parser_mode text NOT NULL DEFAULT 'ai' CHECK (parser_mode IN ('ai', 'shadow', 'auto', 'program')),
|
|
ADD COLUMN IF NOT EXISTS parser_config_revision bigint NOT NULL DEFAULT 0 CHECK (parser_config_revision >= 0),
|
|
ADD COLUMN IF NOT EXISTS parser_engine_affinity text CHECK (parser_engine_affinity IN ('ai', 'program')),
|
|
ADD COLUMN IF NOT EXISTS parser_engine text CHECK (parser_engine IN ('ai', 'program')),
|
|
ADD COLUMN IF NOT EXISTS parser_version text,
|
|
ADD COLUMN IF NOT EXISTS parser_fallback_reason text,
|
|
ADD COLUMN IF NOT EXISTS parser_comparison_status text CHECK (parser_comparison_status IN ('equivalent', 'different', 'not_comparable')),
|
|
ADD COLUMN IF NOT EXISTS parser_reparse_count integer NOT NULL DEFAULT 0 CHECK (parser_reparse_count BETWEEN 0 AND 1);
|
|
|
|
UPDATE tasks
|
|
SET parser_mode = 'ai',
|
|
parser_config_revision = 0,
|
|
parser_engine_affinity = 'ai',
|
|
parser_engine = COALESCE(parser_engine, CASE WHEN parse_response IS NOT NULL OR parse_response_ciphertext IS NOT NULL THEN 'ai' END),
|
|
parser_version = COALESCE(parser_version, CASE WHEN parse_response IS NOT NULL OR parse_response_ciphertext IS NOT NULL THEN 'legacy-ai' END);
|
|
|
|
CREATE INDEX IF NOT EXISTS tasks_parser_route_idx
|
|
ON tasks (organization_id, business_route_id, parser_mode, created_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS parse_decisions (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
task_id uuid NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
|
attempt_no integer NOT NULL,
|
|
route_id text,
|
|
configured_mode text NOT NULL,
|
|
authoritative_engine text NOT NULL,
|
|
program_version text,
|
|
ai_prompt_version text,
|
|
fallback_reason text,
|
|
comparison_status text,
|
|
program_status text,
|
|
ai_status text,
|
|
program_error_code text,
|
|
ai_error_code text,
|
|
program_duration_ms integer,
|
|
ai_duration_ms integer,
|
|
program_result_hash text,
|
|
ai_result_hash text,
|
|
program_result_ciphertext text,
|
|
ai_result_ciphertext text,
|
|
diff_summary jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
review_status text,
|
|
reviewed_by uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
reviewed_at timestamptz,
|
|
review_note_ciphertext text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
CONSTRAINT parse_decisions_attempt_check CHECK (attempt_no >= 1),
|
|
CONSTRAINT parse_decisions_mode_check CHECK (configured_mode IN ('ai', 'shadow', 'auto', 'program')),
|
|
CONSTRAINT parse_decisions_engine_check CHECK (authoritative_engine IN ('ai', 'program')),
|
|
CONSTRAINT parse_decisions_comparison_check CHECK (comparison_status IS NULL OR comparison_status IN ('equivalent', 'different', 'not_comparable')),
|
|
CONSTRAINT parse_decisions_review_check CHECK (review_status IS NULL OR review_status IN ('pending', 'equivalent', 'program_correct', 'ai_correct', 'both_wrong')),
|
|
CONSTRAINT parse_decisions_duration_check CHECK (
|
|
(program_duration_ms IS NULL OR program_duration_ms >= 0)
|
|
AND (ai_duration_ms IS NULL OR ai_duration_ms >= 0)
|
|
),
|
|
UNIQUE (task_id, attempt_no)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS parse_decisions_route_stats_idx
|
|
ON parse_decisions (organization_id, route_id, created_at DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS parse_decisions_review_idx
|
|
ON parse_decisions (organization_id, review_status, created_at DESC)
|
|
WHERE review_status IS NOT NULL;
|