193 lines
8.3 KiB
SQL
193 lines
8.3 KiB
SQL
ALTER TABLE ai_insight_snapshots ADD COLUMN IF NOT EXISTS deterministic_copy jsonb;
|
|
-- statement-break
|
|
ALTER TABLE ai_insight_snapshots ADD COLUMN IF NOT EXISTS provider_request_id text;
|
|
-- statement-break
|
|
UPDATE ai_insight_snapshots SET deterministic_copy=ai_response WHERE deterministic_copy IS NULL;
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS growth_coach_profiles (
|
|
id text PRIMARY KEY,
|
|
merchant_id bigint NOT NULL REFERENCES merchants(id),
|
|
terminal_id bigint NOT NULL REFERENCES terminals(id),
|
|
terminal_source_key text NOT NULL,
|
|
version integer NOT NULL CHECK (version > 0),
|
|
is_current boolean NOT NULL DEFAULT true,
|
|
business_description text NOT NULL CHECK (char_length(business_description) BETWEEN 20 AND 2000),
|
|
niches jsonb NOT NULL,
|
|
sales_channels jsonb NOT NULL,
|
|
primary_goal text NOT NULL CHECK (char_length(primary_goal) BETWEEN 3 AND 500),
|
|
constraints_text text NOT NULL DEFAULT '' CHECK (char_length(constraints_text) <= 1000),
|
|
difficulty smallint NOT NULL DEFAULT 2 CHECK (difficulty BETWEEN 1 AND 5),
|
|
actor_user_id bigint NOT NULL REFERENCES merchant_users(id),
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
UNIQUE (merchant_id,terminal_id,version)
|
|
);
|
|
-- statement-break
|
|
CREATE UNIQUE INDEX IF NOT EXISTS growth_coach_profile_current_idx ON growth_coach_profiles(merchant_id,terminal_id) WHERE is_current;
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS growth_coach_plans (
|
|
id text PRIMARY KEY,
|
|
merchant_id bigint NOT NULL REFERENCES merchants(id),
|
|
terminal_id bigint NOT NULL REFERENCES terminals(id),
|
|
terminal_source_key text NOT NULL,
|
|
profile_id text NOT NULL REFERENCES growth_coach_profiles(id),
|
|
parent_id text REFERENCES growth_coach_plans(id),
|
|
cadence text NOT NULL CHECK (cadence IN ('DAILY','WEEKLY','MONTHLY')),
|
|
status text NOT NULL CHECK (status IN ('GENERATING','READY','PARTIAL','FAILED','CLOSED')),
|
|
period_start date NOT NULL,
|
|
period_end date NOT NULL,
|
|
daily_brief text,
|
|
difficulty smallint NOT NULL CHECK (difficulty BETWEEN 1 AND 5),
|
|
prompt_version text NOT NULL,
|
|
schema_version text NOT NULL,
|
|
model text NOT NULL,
|
|
provider_request_id text,
|
|
input_tokens bigint NOT NULL DEFAULT 0,
|
|
output_tokens bigint NOT NULL DEFAULT 0,
|
|
latency_ms bigint NOT NULL DEFAULT 0,
|
|
provider_requests bigint NOT NULL DEFAULT 0,
|
|
estimated_cost text,
|
|
failure_code text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
completed_at timestamptz,
|
|
CHECK (period_end >= period_start)
|
|
);
|
|
-- statement-break
|
|
CREATE INDEX IF NOT EXISTS growth_coach_plans_scope_idx ON growth_coach_plans(merchant_id,terminal_id,cadence,period_start DESC);
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS growth_coach_recommendations (
|
|
id text PRIMARY KEY,
|
|
plan_id text NOT NULL REFERENCES growth_coach_plans(id) ON DELETE CASCADE,
|
|
merchant_id bigint NOT NULL REFERENCES merchants(id),
|
|
terminal_id bigint NOT NULL REFERENCES terminals(id),
|
|
rank smallint NOT NULL CHECK (rank BETWEEN 1 AND 5),
|
|
status text NOT NULL CHECK (status IN ('OFFERED','ACCEPTED','REJECTED','EXPIRED')),
|
|
action_type text NOT NULL CHECK (action_type IN ('MANUAL','METRIC')),
|
|
title text NOT NULL,
|
|
rationale text NOT NULL,
|
|
expected_impact text NOT NULL,
|
|
effort text NOT NULL CHECK (effort IN ('LOW','MEDIUM','HIGH')),
|
|
evidence_ids jsonb NOT NULL,
|
|
metric_id text,
|
|
metric_direction text CHECK (metric_direction IN ('INCREASE','DECREASE')),
|
|
action_level text CHECK (action_level IN ('SMALL','MEDIUM','STRETCH')),
|
|
baseline numeric(30,6),
|
|
target numeric(30,6),
|
|
sample_size bigint,
|
|
deadline date NOT NULL,
|
|
decision_reason text,
|
|
decision_note text,
|
|
decided_by bigint REFERENCES merchant_users(id),
|
|
decided_at timestamptz,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
UNIQUE(plan_id,rank)
|
|
);
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS golden_steps (
|
|
id text PRIMARY KEY,
|
|
recommendation_id text NOT NULL UNIQUE REFERENCES growth_coach_recommendations(id),
|
|
merchant_id bigint NOT NULL REFERENCES merchants(id),
|
|
terminal_id bigint NOT NULL REFERENCES terminals(id),
|
|
terminal_source_key text NOT NULL,
|
|
action_type text NOT NULL CHECK (action_type IN ('MANUAL','METRIC')),
|
|
title text NOT NULL,
|
|
status text NOT NULL CHECK (status IN ('NOT_STARTED','IN_PROGRESS','COMPLETED','ABANDONED','MISSED')),
|
|
metric_id text,
|
|
metric_direction text,
|
|
baseline numeric(30,6),
|
|
target numeric(30,6),
|
|
current_value numeric(30,6),
|
|
sample_size bigint,
|
|
deadline date NOT NULL,
|
|
started_at timestamptz,
|
|
completed_at timestamptz,
|
|
actor_user_id bigint NOT NULL REFERENCES merchant_users(id),
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
-- statement-break
|
|
CREATE INDEX IF NOT EXISTS golden_steps_scope_idx ON golden_steps(merchant_id,terminal_id,status,deadline);
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS growth_coach_jobs (
|
|
id text PRIMARY KEY,
|
|
merchant_id bigint NOT NULL REFERENCES merchants(id),
|
|
terminal_id bigint NOT NULL REFERENCES terminals(id),
|
|
terminal_source_key text NOT NULL,
|
|
profile_id text NOT NULL REFERENCES growth_coach_profiles(id),
|
|
cadence text NOT NULL CHECK (cadence IN ('DAILY','WEEKLY','MONTHLY')),
|
|
trigger_reason text NOT NULL,
|
|
period_start date NOT NULL,
|
|
period_end date NOT NULL,
|
|
fingerprint text NOT NULL UNIQUE,
|
|
idempotency_key text,
|
|
request_hash text,
|
|
status text NOT NULL CHECK (status IN ('QUEUED','RUNNING','COMPLETED','FAILED')),
|
|
attempts integer NOT NULL DEFAULT 0,
|
|
scheduled_at timestamptz NOT NULL DEFAULT now(),
|
|
lease_token text,
|
|
lease_expires_at timestamptz,
|
|
failure_code text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
completed_at timestamptz,
|
|
UNIQUE(merchant_id,idempotency_key)
|
|
);
|
|
-- statement-break
|
|
CREATE INDEX IF NOT EXISTS growth_coach_jobs_pending_idx ON growth_coach_jobs(scheduled_at,created_at) WHERE status IN ('QUEUED','RUNNING');
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS growth_coach_events (
|
|
id bigserial PRIMARY KEY,
|
|
merchant_id bigint NOT NULL REFERENCES merchants(id),
|
|
terminal_id bigint NOT NULL REFERENCES terminals(id),
|
|
actor_user_id bigint REFERENCES merchant_users(id),
|
|
entity_type text NOT NULL,
|
|
entity_id text NOT NULL,
|
|
event_type text NOT NULL,
|
|
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
occurred_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS growth_coach_progress_snapshots (
|
|
id bigserial PRIMARY KEY,
|
|
action_id text NOT NULL REFERENCES golden_steps(id) ON DELETE CASCADE,
|
|
watermark text NOT NULL,
|
|
value numeric(30,6) NOT NULL,
|
|
sample_size bigint NOT NULL,
|
|
evaluated_at timestamptz NOT NULL DEFAULT now(),
|
|
UNIQUE(action_id,watermark)
|
|
);
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS growth_coach_difficulty_proposals (
|
|
id text PRIMARY KEY,
|
|
merchant_id bigint NOT NULL REFERENCES merchants(id),
|
|
terminal_id bigint NOT NULL REFERENCES terminals(id),
|
|
from_level smallint NOT NULL CHECK (from_level BETWEEN 1 AND 5),
|
|
to_level smallint NOT NULL CHECK (to_level BETWEEN 1 AND 5),
|
|
reason text NOT NULL,
|
|
status text NOT NULL CHECK (status IN ('OFFERED','ACCEPTED','REJECTED','EXPIRED')),
|
|
decided_by bigint REFERENCES merchant_users(id),
|
|
decided_at timestamptz,
|
|
created_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS growth_coach_outcome_reviews (
|
|
id text PRIMARY KEY,
|
|
plan_id text NOT NULL UNIQUE REFERENCES growth_coach_plans(id),
|
|
merchant_id bigint NOT NULL REFERENCES merchants(id),
|
|
terminal_id bigint NOT NULL REFERENCES terminals(id),
|
|
summary text NOT NULL,
|
|
completed_on_time integer NOT NULL DEFAULT 0,
|
|
missed integer NOT NULL DEFAULT 0,
|
|
created_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
-- statement-break
|
|
CREATE TABLE IF NOT EXISTS growth_coach_idempotency (
|
|
merchant_id bigint NOT NULL REFERENCES merchants(id),
|
|
idempotency_key text NOT NULL,
|
|
request_hash text NOT NULL,
|
|
response jsonb NOT NULL,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
PRIMARY KEY(merchant_id,idempotency_key)
|
|
);
|
|
-- statement-break
|
|
INSERT INTO schema_migrations(version) VALUES (5) ON CONFLICT DO NOTHING;
|