005_query_planning_schema.sql 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. -- 005: add query planning state before the frozen acquisition boundary.
  2. CREATE TABLE IF NOT EXISTS creation_knowledge.query_plans (
  3. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  4. generator_kind text NOT NULL CHECK (
  5. generator_kind IN ('cartesian', 'manual', 'topic_table', 'agent_plan', 'history_gap')
  6. ),
  7. status text NOT NULL DEFAULT 'ready' CHECK (status IN ('planning', 'ready', 'failed')),
  8. input_snapshot jsonb NOT NULL DEFAULT '{}'::jsonb,
  9. generator_config jsonb NOT NULL DEFAULT '{}'::jsonb,
  10. max_queries integer CHECK (max_queries IS NULL OR max_queries >= 0),
  11. generated_count integer NOT NULL DEFAULT 0 CHECK (generated_count >= 0),
  12. normalized_count integer NOT NULL DEFAULT 0 CHECK (normalized_count >= 0),
  13. unique_count integer NOT NULL DEFAULT 0 CHECK (unique_count >= 0),
  14. selected_count integer NOT NULL DEFAULT 0 CHECK (selected_count >= 0),
  15. dropped_count integer NOT NULL DEFAULT 0 CHECK (dropped_count >= 0),
  16. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  17. created_at timestamptz NOT NULL DEFAULT now(),
  18. updated_at timestamptz NOT NULL DEFAULT now(),
  19. CHECK (normalized_count <= generated_count),
  20. CHECK (unique_count <= normalized_count),
  21. CHECK (selected_count <= unique_count),
  22. CHECK (dropped_count = generated_count - selected_count)
  23. );
  24. CREATE TABLE IF NOT EXISTS creation_knowledge.knowledge_needs (
  25. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  26. plan_id uuid NOT NULL REFERENCES creation_knowledge.query_plans(id) ON DELETE CASCADE,
  27. need_key text NOT NULL,
  28. decision_context text NOT NULL,
  29. unknown_information text NOT NULL,
  30. source_ref jsonb NOT NULL DEFAULT '{}'::jsonb,
  31. priority integer NOT NULL DEFAULT 0,
  32. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  33. created_at timestamptz NOT NULL DEFAULT now(),
  34. UNIQUE (plan_id, need_key)
  35. );
  36. CREATE TABLE IF NOT EXISTS creation_knowledge.query_plan_batches (
  37. plan_id uuid NOT NULL REFERENCES creation_knowledge.query_plans(id) ON DELETE CASCADE,
  38. batch_id uuid NOT NULL REFERENCES creation_knowledge.query_batches(id) ON DELETE CASCADE,
  39. created_at timestamptz NOT NULL DEFAULT now(),
  40. PRIMARY KEY (plan_id, batch_id)
  41. );
  42. CREATE TABLE IF NOT EXISTS creation_knowledge.query_knowledge_need_links (
  43. query_id uuid NOT NULL REFERENCES creation_knowledge.queries(id) ON DELETE CASCADE,
  44. knowledge_need_id uuid NOT NULL REFERENCES creation_knowledge.knowledge_needs(id) ON DELETE CASCADE,
  45. created_at timestamptz NOT NULL DEFAULT now(),
  46. PRIMARY KEY (query_id, knowledge_need_id)
  47. );
  48. CREATE INDEX IF NOT EXISTS idx_query_plans_kind_created
  49. ON creation_knowledge.query_plans(generator_kind, created_at);
  50. CREATE INDEX IF NOT EXISTS idx_knowledge_needs_plan_priority
  51. ON creation_knowledge.knowledge_needs(plan_id, priority DESC);
  52. CREATE INDEX IF NOT EXISTS idx_query_plan_batches_batch
  53. ON creation_knowledge.query_plan_batches(batch_id);
  54. CREATE INDEX IF NOT EXISTS idx_query_knowledge_need_links_need
  55. ON creation_knowledge.query_knowledge_need_links(knowledge_need_id);
  56. DROP TRIGGER IF EXISTS trg_query_plans_touch_updated_at
  57. ON creation_knowledge.query_plans;
  58. CREATE TRIGGER trg_query_plans_touch_updated_at
  59. BEFORE UPDATE ON creation_knowledge.query_plans
  60. FOR EACH ROW EXECUTE FUNCTION creation_knowledge.touch_updated_at();
  61. DO $$
  62. BEGIN
  63. IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'ck_app') THEN
  64. GRANT SELECT, INSERT, UPDATE, DELETE ON
  65. creation_knowledge.query_plans,
  66. creation_knowledge.knowledge_needs,
  67. creation_knowledge.query_plan_batches,
  68. creation_knowledge.query_knowledge_need_links
  69. TO ck_app;
  70. END IF;
  71. END;
  72. $$;
  73. INSERT INTO creation_knowledge.schema_migrations(version, description)
  74. VALUES ('005_query_planning_schema', 'Add query plans, knowledge needs, and legacy query links')
  75. ON CONFLICT (version) DO UPDATE SET
  76. description = EXCLUDED.description,
  77. applied_at = now();