001_creation_knowledge_schema.sql 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. -- Creation Knowledge formal cloud schema.
  2. -- Applied to database: creation_knowledge_prod
  3. -- Schema: creation_knowledge
  4. CREATE EXTENSION IF NOT EXISTS pgcrypto;
  5. CREATE SCHEMA IF NOT EXISTS creation_knowledge;
  6. CREATE TABLE IF NOT EXISTS creation_knowledge.schema_migrations (
  7. version text PRIMARY KEY,
  8. description text NOT NULL,
  9. applied_at timestamptz NOT NULL DEFAULT now()
  10. );
  11. CREATE OR REPLACE FUNCTION creation_knowledge.touch_updated_at()
  12. RETURNS trigger
  13. LANGUAGE plpgsql
  14. AS $$
  15. BEGIN
  16. NEW.updated_at = now();
  17. RETURN NEW;
  18. END;
  19. $$;
  20. CREATE TABLE IF NOT EXISTS creation_knowledge.query_batches (
  21. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  22. name text NOT NULL,
  23. source_type text NOT NULL DEFAULT 'manual',
  24. generation_method text,
  25. target_platforms text[] NOT NULL DEFAULT ARRAY[]::text[],
  26. status text NOT NULL DEFAULT 'draft',
  27. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  28. error_message text,
  29. created_at timestamptz NOT NULL DEFAULT now(),
  30. updated_at timestamptz NOT NULL DEFAULT now()
  31. );
  32. CREATE TABLE IF NOT EXISTS creation_knowledge.queries (
  33. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  34. batch_id uuid REFERENCES creation_knowledge.query_batches(id) ON DELETE CASCADE,
  35. query_text text NOT NULL,
  36. axes jsonb NOT NULL DEFAULT '{}'::jsonb,
  37. keep boolean,
  38. filter_reason text,
  39. status text NOT NULL DEFAULT 'draft',
  40. sort_order integer NOT NULL DEFAULT 0,
  41. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  42. error_message text,
  43. created_at timestamptz NOT NULL DEFAULT now(),
  44. updated_at timestamptz NOT NULL DEFAULT now()
  45. );
  46. CREATE TABLE IF NOT EXISTS creation_knowledge.acquisition_runs (
  47. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  48. batch_id uuid REFERENCES creation_knowledge.query_batches(id),
  49. run_key text UNIQUE,
  50. status text NOT NULL DEFAULT 'pending',
  51. note text,
  52. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  53. error_message text,
  54. started_at timestamptz,
  55. finished_at timestamptz,
  56. created_at timestamptz NOT NULL DEFAULT now(),
  57. updated_at timestamptz NOT NULL DEFAULT now()
  58. );
  59. CREATE TABLE IF NOT EXISTS creation_knowledge.acquisition_jobs (
  60. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  61. run_id uuid NOT NULL REFERENCES creation_knowledge.acquisition_runs(id) ON DELETE CASCADE,
  62. query_id uuid REFERENCES creation_knowledge.queries(id),
  63. platform text NOT NULL,
  64. status text NOT NULL DEFAULT 'pending',
  65. search_limit integer,
  66. display_limit integer,
  67. attempt_count integer NOT NULL DEFAULT 0,
  68. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  69. error_message text,
  70. started_at timestamptz,
  71. finished_at timestamptz,
  72. created_at timestamptz NOT NULL DEFAULT now(),
  73. updated_at timestamptz NOT NULL DEFAULT now(),
  74. UNIQUE (run_id, query_id, platform)
  75. );
  76. CREATE TABLE IF NOT EXISTS creation_knowledge.candidate_items (
  77. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  78. job_id uuid REFERENCES creation_knowledge.acquisition_jobs(id) ON DELETE SET NULL,
  79. query_id uuid REFERENCES creation_knowledge.queries(id) ON DELETE SET NULL,
  80. platform text NOT NULL,
  81. platform_item_id text,
  82. canonical_url text,
  83. content_type text,
  84. title text,
  85. author_name text,
  86. published_at timestamptz,
  87. raw_summary text,
  88. status text NOT NULL DEFAULT 'candidate',
  89. source_payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  90. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  91. error_message text,
  92. created_at timestamptz NOT NULL DEFAULT now(),
  93. updated_at timestamptz NOT NULL DEFAULT now()
  94. );
  95. CREATE TABLE IF NOT EXISTS creation_knowledge.media_assets (
  96. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  97. item_id uuid NOT NULL REFERENCES creation_knowledge.candidate_items(id) ON DELETE CASCADE,
  98. media_type text NOT NULL,
  99. source_url text,
  100. oss_url text,
  101. cdn_url text,
  102. position integer NOT NULL DEFAULT 0,
  103. status text NOT NULL DEFAULT 'pending',
  104. source_payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  105. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  106. error_message text,
  107. created_at timestamptz NOT NULL DEFAULT now(),
  108. updated_at timestamptz NOT NULL DEFAULT now()
  109. );
  110. CREATE TABLE IF NOT EXISTS creation_knowledge.item_classifications (
  111. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  112. item_id uuid NOT NULL REFERENCES creation_knowledge.candidate_items(id) ON DELETE CASCADE,
  113. is_creation_knowledge boolean,
  114. label text,
  115. confidence numeric(5,4),
  116. reason text,
  117. model_name text,
  118. prompt_version text,
  119. result_payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  120. status text NOT NULL DEFAULT 'pending',
  121. error_message text,
  122. created_at timestamptz NOT NULL DEFAULT now(),
  123. updated_at timestamptz NOT NULL DEFAULT now()
  124. );
  125. CREATE TABLE IF NOT EXISTS creation_knowledge.decode_jobs (
  126. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  127. item_id uuid NOT NULL REFERENCES creation_knowledge.candidate_items(id) ON DELETE CASCADE,
  128. status text NOT NULL DEFAULT 'pending',
  129. attempt_count integer NOT NULL DEFAULT 0,
  130. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  131. error_message text,
  132. started_at timestamptz,
  133. finished_at timestamptz,
  134. created_at timestamptz NOT NULL DEFAULT now(),
  135. updated_at timestamptz NOT NULL DEFAULT now()
  136. );
  137. CREATE TABLE IF NOT EXISTS creation_knowledge.decode_results (
  138. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  139. decode_job_id uuid REFERENCES creation_knowledge.decode_jobs(id) ON DELETE SET NULL,
  140. item_id uuid NOT NULL REFERENCES creation_knowledge.candidate_items(id) ON DELETE CASCADE,
  141. read_result jsonb NOT NULL DEFAULT '{}'::jsonb,
  142. gate_result jsonb NOT NULL DEFAULT '{}'::jsonb,
  143. framing_result jsonb NOT NULL DEFAULT '{}'::jsonb,
  144. status text NOT NULL DEFAULT 'draft',
  145. error_message text,
  146. created_at timestamptz NOT NULL DEFAULT now(),
  147. updated_at timestamptz NOT NULL DEFAULT now()
  148. );
  149. CREATE TABLE IF NOT EXISTS creation_knowledge.knowledge_particles (
  150. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  151. decode_result_id uuid REFERENCES creation_knowledge.decode_results(id) ON DELETE CASCADE,
  152. item_id uuid REFERENCES creation_knowledge.candidate_items(id) ON DELETE CASCADE,
  153. parent_particle_id uuid REFERENCES creation_knowledge.knowledge_particles(id) ON DELETE SET NULL,
  154. particle_type text NOT NULL CHECK (particle_type IN ('what', 'how', 'why')),
  155. title text NOT NULL,
  156. business_stage text,
  157. creation_stage text,
  158. content jsonb NOT NULL DEFAULT '{}'::jsonb,
  159. sort_order integer NOT NULL DEFAULT 0,
  160. status text NOT NULL DEFAULT 'draft',
  161. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  162. error_message text,
  163. created_at timestamptz NOT NULL DEFAULT now(),
  164. updated_at timestamptz NOT NULL DEFAULT now()
  165. );
  166. CREATE TABLE IF NOT EXISTS creation_knowledge.scope_results (
  167. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  168. particle_id uuid REFERENCES creation_knowledge.knowledge_particles(id) ON DELETE CASCADE,
  169. item_id uuid REFERENCES creation_knowledge.candidate_items(id) ON DELETE CASCADE,
  170. scope_type text NOT NULL,
  171. scope_value text NOT NULL,
  172. is_reused boolean,
  173. matched_scope_id text,
  174. confidence numeric(5,4),
  175. evidence jsonb NOT NULL DEFAULT '{}'::jsonb,
  176. status text NOT NULL DEFAULT 'draft',
  177. error_message text,
  178. created_at timestamptz NOT NULL DEFAULT now(),
  179. updated_at timestamptz NOT NULL DEFAULT now()
  180. );
  181. CREATE TABLE IF NOT EXISTS creation_knowledge.payload_drafts (
  182. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  183. particle_id uuid REFERENCES creation_knowledge.knowledge_particles(id) ON DELETE CASCADE,
  184. item_id uuid REFERENCES creation_knowledge.candidate_items(id) ON DELETE CASCADE,
  185. payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  186. review_status text NOT NULL DEFAULT 'pending',
  187. ingest_ready boolean NOT NULL DEFAULT false,
  188. status text NOT NULL DEFAULT 'draft',
  189. error_message text,
  190. created_at timestamptz NOT NULL DEFAULT now(),
  191. updated_at timestamptz NOT NULL DEFAULT now()
  192. );
  193. CREATE TABLE IF NOT EXISTS creation_knowledge.ingest_records (
  194. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  195. payload_draft_id uuid REFERENCES creation_knowledge.payload_drafts(id) ON DELETE SET NULL,
  196. target_system text NOT NULL,
  197. target_id text,
  198. status text NOT NULL DEFAULT 'pending',
  199. attempt_count integer NOT NULL DEFAULT 0,
  200. response_payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  201. error_message text,
  202. created_at timestamptz NOT NULL DEFAULT now(),
  203. updated_at timestamptz NOT NULL DEFAULT now()
  204. );
  205. CREATE TABLE IF NOT EXISTS creation_knowledge.pipeline_runs (
  206. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  207. run_key text UNIQUE,
  208. batch_id uuid REFERENCES creation_knowledge.query_batches(id) ON DELETE SET NULL,
  209. status text NOT NULL DEFAULT 'pending',
  210. current_stage text,
  211. config jsonb NOT NULL DEFAULT '{}'::jsonb,
  212. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  213. error_message text,
  214. started_at timestamptz,
  215. finished_at timestamptz,
  216. created_at timestamptz NOT NULL DEFAULT now(),
  217. updated_at timestamptz NOT NULL DEFAULT now()
  218. );
  219. CREATE TABLE IF NOT EXISTS creation_knowledge.pipeline_jobs (
  220. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  221. pipeline_run_id uuid NOT NULL REFERENCES creation_knowledge.pipeline_runs(id) ON DELETE CASCADE,
  222. stage text NOT NULL,
  223. status text NOT NULL DEFAULT 'pending',
  224. target_table text,
  225. target_id uuid,
  226. attempt_count integer NOT NULL DEFAULT 0,
  227. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  228. error_message text,
  229. started_at timestamptz,
  230. finished_at timestamptz,
  231. created_at timestamptz NOT NULL DEFAULT now(),
  232. updated_at timestamptz NOT NULL DEFAULT now()
  233. );
  234. CREATE TABLE IF NOT EXISTS creation_knowledge.pipeline_run_events (
  235. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  236. pipeline_run_id uuid REFERENCES creation_knowledge.pipeline_runs(id) ON DELETE CASCADE,
  237. pipeline_job_id uuid REFERENCES creation_knowledge.pipeline_jobs(id) ON DELETE SET NULL,
  238. stage text NOT NULL,
  239. event_type text NOT NULL,
  240. status text,
  241. severity text NOT NULL DEFAULT 'info',
  242. target_table text,
  243. target_id uuid,
  244. acquisition_run_id uuid REFERENCES creation_knowledge.acquisition_runs(id) ON DELETE SET NULL,
  245. acquisition_job_id uuid REFERENCES creation_knowledge.acquisition_jobs(id) ON DELETE SET NULL,
  246. query_id uuid REFERENCES creation_knowledge.queries(id) ON DELETE SET NULL,
  247. item_id uuid REFERENCES creation_knowledge.candidate_items(id) ON DELETE SET NULL,
  248. decode_job_id uuid REFERENCES creation_knowledge.decode_jobs(id) ON DELETE SET NULL,
  249. decode_result_id uuid REFERENCES creation_knowledge.decode_results(id) ON DELETE SET NULL,
  250. payload_draft_id uuid REFERENCES creation_knowledge.payload_drafts(id) ON DELETE SET NULL,
  251. ingest_record_id uuid REFERENCES creation_knowledge.ingest_records(id) ON DELETE SET NULL,
  252. platform text,
  253. attempt_index integer,
  254. message text,
  255. payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  256. error_message text,
  257. duration_ms integer,
  258. created_at timestamptz NOT NULL DEFAULT now()
  259. );
  260. CREATE TABLE IF NOT EXISTS creation_knowledge.candidate_item_hits (
  261. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  262. pipeline_run_id uuid REFERENCES creation_knowledge.pipeline_runs(id) ON DELETE CASCADE,
  263. acquisition_run_id uuid REFERENCES creation_knowledge.acquisition_runs(id) ON DELETE CASCADE,
  264. acquisition_job_id uuid REFERENCES creation_knowledge.acquisition_jobs(id) ON DELETE SET NULL,
  265. query_id uuid REFERENCES creation_knowledge.queries(id) ON DELETE SET NULL,
  266. item_id uuid REFERENCES creation_knowledge.candidate_items(id) ON DELETE SET NULL,
  267. platform text NOT NULL,
  268. unique_key text,
  269. platform_item_id text,
  270. search_provider text,
  271. detail_provider text,
  272. attempt_index integer,
  273. page_index integer,
  274. page_rank integer,
  275. candidate_rank integer,
  276. source_cursor text,
  277. is_duplicate_hit boolean NOT NULL DEFAULT false,
  278. raw_candidate jsonb NOT NULL DEFAULT '{}'::jsonb,
  279. metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
  280. created_at timestamptz NOT NULL DEFAULT now()
  281. );
  282. CREATE TABLE IF NOT EXISTS creation_knowledge.llm_call_traces (
  283. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  284. pipeline_run_id uuid REFERENCES creation_knowledge.pipeline_runs(id) ON DELETE CASCADE,
  285. pipeline_job_id uuid REFERENCES creation_knowledge.pipeline_jobs(id) ON DELETE SET NULL,
  286. run_event_id uuid REFERENCES creation_knowledge.pipeline_run_events(id) ON DELETE SET NULL,
  287. stage text NOT NULL,
  288. substage text,
  289. provider text,
  290. model_name text,
  291. endpoint text,
  292. prompt_name text,
  293. prompt_hash text,
  294. trace_context jsonb NOT NULL DEFAULT '{}'::jsonb,
  295. request_payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  296. response_payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  297. parsed_payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  298. status text NOT NULL DEFAULT 'pending',
  299. error_message text,
  300. latency_ms integer,
  301. attempt_index integer,
  302. created_at timestamptz NOT NULL DEFAULT now()
  303. );
  304. CREATE TABLE IF NOT EXISTS creation_knowledge.contract_artifacts (
  305. id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  306. contract_name text NOT NULL,
  307. contract_type text NOT NULL,
  308. version_label text,
  309. content_hash text NOT NULL,
  310. source_path text,
  311. snapshot jsonb NOT NULL DEFAULT '{}'::jsonb,
  312. created_at timestamptz NOT NULL DEFAULT now(),
  313. updated_at timestamptz NOT NULL DEFAULT now(),
  314. UNIQUE (contract_name, contract_type, source_path, content_hash)
  315. );
  316. CREATE TABLE IF NOT EXISTS creation_knowledge.run_contract_artifacts (
  317. pipeline_run_id uuid NOT NULL REFERENCES creation_knowledge.pipeline_runs(id) ON DELETE CASCADE,
  318. contract_artifact_id uuid NOT NULL REFERENCES creation_knowledge.contract_artifacts(id) ON DELETE CASCADE,
  319. created_at timestamptz NOT NULL DEFAULT now(),
  320. PRIMARY KEY (pipeline_run_id, contract_artifact_id)
  321. );
  322. CREATE INDEX IF NOT EXISTS idx_queries_batch ON creation_knowledge.queries(batch_id);
  323. CREATE INDEX IF NOT EXISTS idx_acquisition_runs_batch ON creation_knowledge.acquisition_runs(batch_id);
  324. CREATE INDEX IF NOT EXISTS idx_acquisition_jobs_run ON creation_knowledge.acquisition_jobs(run_id);
  325. CREATE INDEX IF NOT EXISTS idx_candidate_items_job ON creation_knowledge.candidate_items(job_id);
  326. CREATE INDEX IF NOT EXISTS idx_candidate_items_platform_item ON creation_knowledge.candidate_items(platform, platform_item_id);
  327. CREATE INDEX IF NOT EXISTS idx_media_assets_item ON creation_knowledge.media_assets(item_id);
  328. CREATE INDEX IF NOT EXISTS idx_item_classifications_item ON creation_knowledge.item_classifications(item_id);
  329. CREATE INDEX IF NOT EXISTS idx_decode_jobs_item ON creation_knowledge.decode_jobs(item_id);
  330. CREATE INDEX IF NOT EXISTS idx_decode_results_item ON creation_knowledge.decode_results(item_id);
  331. CREATE INDEX IF NOT EXISTS idx_knowledge_particles_item ON creation_knowledge.knowledge_particles(item_id);
  332. CREATE INDEX IF NOT EXISTS idx_scope_results_particle ON creation_knowledge.scope_results(particle_id);
  333. CREATE INDEX IF NOT EXISTS idx_payload_drafts_particle ON creation_knowledge.payload_drafts(particle_id);
  334. CREATE INDEX IF NOT EXISTS idx_ingest_records_payload ON creation_knowledge.ingest_records(payload_draft_id);
  335. CREATE INDEX IF NOT EXISTS idx_pipeline_runs_batch ON creation_knowledge.pipeline_runs(batch_id);
  336. CREATE INDEX IF NOT EXISTS idx_pipeline_runs_status ON creation_knowledge.pipeline_runs(status, current_stage);
  337. CREATE INDEX IF NOT EXISTS idx_pipeline_jobs_run ON creation_knowledge.pipeline_jobs(pipeline_run_id);
  338. CREATE INDEX IF NOT EXISTS idx_pipeline_jobs_stage_status ON creation_knowledge.pipeline_jobs(stage, status);
  339. CREATE INDEX IF NOT EXISTS idx_pipeline_run_events_run ON creation_knowledge.pipeline_run_events(pipeline_run_id, created_at);
  340. CREATE INDEX IF NOT EXISTS idx_pipeline_run_events_acq_run ON creation_knowledge.pipeline_run_events(acquisition_run_id);
  341. CREATE INDEX IF NOT EXISTS idx_pipeline_run_events_query ON creation_knowledge.pipeline_run_events(query_id);
  342. CREATE INDEX IF NOT EXISTS idx_pipeline_run_events_item ON creation_knowledge.pipeline_run_events(item_id);
  343. CREATE INDEX IF NOT EXISTS idx_candidate_item_hits_pipeline_run ON creation_knowledge.candidate_item_hits(pipeline_run_id);
  344. CREATE INDEX IF NOT EXISTS idx_candidate_item_hits_acq_run ON creation_knowledge.candidate_item_hits(acquisition_run_id);
  345. CREATE INDEX IF NOT EXISTS idx_candidate_item_hits_query ON creation_knowledge.candidate_item_hits(query_id);
  346. CREATE INDEX IF NOT EXISTS idx_candidate_item_hits_item ON creation_knowledge.candidate_item_hits(item_id);
  347. CREATE INDEX IF NOT EXISTS idx_candidate_item_hits_unique_key ON creation_knowledge.candidate_item_hits(unique_key);
  348. CREATE INDEX IF NOT EXISTS idx_llm_call_traces_run_stage ON creation_knowledge.llm_call_traces(pipeline_run_id, stage, substage);
  349. CREATE INDEX IF NOT EXISTS idx_llm_call_traces_item ON creation_knowledge.llm_call_traces((trace_context ->> 'item_id'));
  350. CREATE INDEX IF NOT EXISTS idx_llm_call_traces_status ON creation_knowledge.llm_call_traces(status);
  351. CREATE INDEX IF NOT EXISTS idx_contract_artifacts_name_hash ON creation_knowledge.contract_artifacts(contract_name, contract_type, source_path, content_hash);
  352. CREATE INDEX IF NOT EXISTS idx_run_contract_artifacts_artifact ON creation_knowledge.run_contract_artifacts(contract_artifact_id);
  353. DO $$
  354. DECLARE
  355. table_name text;
  356. BEGIN
  357. FOREACH table_name IN ARRAY ARRAY[
  358. 'query_batches',
  359. 'queries',
  360. 'acquisition_runs',
  361. 'acquisition_jobs',
  362. 'candidate_items',
  363. 'media_assets',
  364. 'item_classifications',
  365. 'decode_jobs',
  366. 'decode_results',
  367. 'knowledge_particles',
  368. 'scope_results',
  369. 'payload_drafts',
  370. 'ingest_records',
  371. 'pipeline_runs',
  372. 'pipeline_jobs',
  373. 'contract_artifacts'
  374. ]
  375. LOOP
  376. EXECUTE format('DROP TRIGGER IF EXISTS trg_%I_touch_updated_at ON creation_knowledge.%I', table_name, table_name);
  377. EXECUTE format(
  378. 'CREATE TRIGGER trg_%I_touch_updated_at BEFORE UPDATE ON creation_knowledge.%I FOR EACH ROW EXECUTE FUNCTION creation_knowledge.touch_updated_at()',
  379. table_name,
  380. table_name
  381. );
  382. END LOOP;
  383. END;
  384. $$;
  385. DO $$
  386. BEGIN
  387. IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'ck_app') THEN
  388. GRANT CONNECT ON DATABASE creation_knowledge_prod TO ck_app;
  389. GRANT USAGE ON SCHEMA creation_knowledge TO ck_app;
  390. GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA creation_knowledge TO ck_app;
  391. GRANT USAGE, SELECT, UPDATE ON ALL SEQUENCES IN SCHEMA creation_knowledge TO ck_app;
  392. ALTER DEFAULT PRIVILEGES IN SCHEMA creation_knowledge
  393. GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO ck_app;
  394. ALTER DEFAULT PRIVILEGES IN SCHEMA creation_knowledge
  395. GRANT USAGE, SELECT, UPDATE ON SEQUENCES TO ck_app;
  396. ALTER ROLE ck_app IN DATABASE creation_knowledge_prod
  397. SET search_path = creation_knowledge, public;
  398. END IF;
  399. END;
  400. $$;
  401. INSERT INTO creation_knowledge.schema_migrations(version, description)
  402. VALUES ('001_creation_knowledge_schema', 'formal creation knowledge cloud schema')
  403. ON CONFLICT (version) DO UPDATE
  404. SET description = EXCLUDED.description,
  405. applied_at = now();