@taodigital/database 0.0.0-stage → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -2
- package/dist/index.d.ts +58 -0
- package/dist/index.js +209 -0
- package/package.json +29 -4
- package/prisma/migrations/0000_init/migration.sql +220 -0
- package/prisma/migrations/0001_tenant_isolation/migration.sql +43 -0
- package/prisma/migrations/0002_app_runtime_role/migration.sql +14 -0
- package/prisma/migrations/0003_skill_taxonomy/migration.sql +30 -0
- package/prisma/migrations/0004_extended_models/migration.sql +215 -0
- package/prisma/migrations/0005_enhanced_test_artifacts/migration.sql +24 -0
- package/prisma/migrations/0006_tenant_settings/migration.sql +28 -0
- package/prisma/migrations/0007_project_slug/migration.sql +11 -0
- package/prisma/migrations/0008_project_crawl_config/migration.sql +3 -0
- package/prisma/migrations/0009_tenant_slug/migration.sql +11 -0
- package/prisma/migrations/0010_user_password/migration.sql +3 -0
- package/prisma/migrations/0011_oauth_connections/migration.sql +78 -0
- package/prisma/migrations/0012_agent_webhooks/migration.sql +46 -0
- package/prisma/migrations/0013_project_artifacts/migration.sql +27 -0
- package/prisma/migrations/0014_knowledge_chunks/migration.sql +37 -0
- package/prisma/migrations/20260626022056_platform_job_migration/migration.sql +44 -0
- package/prisma/migrations/20260626053339_kag_schema_update/migration.sql +27 -0
- package/prisma/migrations/20260626053340_restore_bm25_index/migration.sql +13 -0
- package/prisma/migrations/20260626063704_token_optimisation/migration.sql +86 -0
- package/prisma/migrations/20260626080000_job_name/migration.sql +2 -0
- package/prisma/migrations/20260626090000_rls_missing_tables/migration.sql +39 -0
- package/prisma/migrations/20260626100000_token_budget/migration.sql +21 -0
- package/prisma/migrations/20260626110000_screen_groups/migration.sql +42 -0
- package/prisma/migrations/20260626120000_artifact_intelligence/migration.sql +5 -0
- package/prisma/migrations/20260626130000_notifications/migration.sql +34 -0
- package/prisma/migrations/20260627100000_element_viewport/migration.sql +2 -0
- package/prisma/migrations/20260627100000_screenshot_cloud_url/migration.sql +2 -0
- package/prisma/migrations/20260627110000_screenshot_index/migration.sql +2 -0
- package/prisma/migrations/20260627140000_artifact_storage_key/migration.sql +3 -0
- package/prisma/migrations/20260627150000_screen_lifecycle/migration.sql +5 -0
- package/prisma/migrations/20260627160000_native_app_support/migration.sql +41 -0
- package/prisma/migrations/20260627200000_rls_missing_tables/migration.sql +57 -0
- package/prisma/migrations/20260627210000_llmcalllog_tasktype/migration.sql +1 -0
- package/prisma/migrations/20260628100000_element_enrichment/migration.sql +7 -0
- package/prisma/migrations/20260628110000_element_hash/migration.sql +6 -0
- package/prisma/migrations/20260628120000_screen_diff/migration.sql +20 -0
- package/prisma/migrations/20260628130000_probe_observations/migration.sql +19 -0
- package/prisma/migrations/20260629100000_visual_baseline_masking/migration.sql +1 -0
- package/prisma/migrations/20260629110000_testcase_viewports/migration.sql +1 -0
- package/prisma/migrations/20260630100000_visual_baseline_element_snapshot/migration.sql +1 -0
- package/prisma/migrations/20260630110000_git_branched_baselines/migration.sql +11 -0
- package/prisma/migrations/20260630120000_testcase_viewport_constraint/migration.sql +1 -0
- package/prisma/migrations/20260630130000_test_case_runs/migration.sql +22 -0
- package/prisma/migrations/20260630140000_perf_env_comments/migration.sql +68 -0
- package/prisma/migrations/20260630150000_testcase_gen_at/migration.sql +2 -0
- package/prisma/migrations/20260630160000_rls_catchup_late_tables/migration.sql +41 -0
- package/prisma/migrations/20260701100000_skill_file_diff_approval/migration.sql +9 -0
- package/prisma/migrations/20260701200000_workspace_connector/migration.sql +20 -0
- package/prisma/migrations/20260701220000_screen_a11y_security/migration.sql +2 -0
- package/prisma/migrations/20260702100000_ci_threshold_root_cause/migration.sql +2 -0
- package/prisma/migrations/20260702120000_medium_priority_gaps/migration.sql +28 -0
- package/prisma/migrations/20260702140000_testcase_v2_technique/migration.sql +7 -0
- package/prisma/migrations/20260702150000_add_app_field/migration.sql +40 -0
- package/prisma/migrations/20260702160000_add_requirement_model/migration.sql +62 -0
- package/prisma/migrations/20260702180000_add_invitation_model/migration.sql +53 -0
- package/prisma/migrations/20260702190000_suite_hierarchy_artifact_trace/migration.sql +28 -0
- package/prisma/migrations/20260702200000_project_member_access/migration.sql +31 -0
- package/prisma/migrations/20260703000000_add_system_config/migration.sql +11 -0
- package/prisma/migrations/20260703000000_custom_roles/migration.sql +29 -0
- package/prisma/migrations/20260703100000_platform_admin/migration.sql +11 -0
- package/prisma/migrations/20260703110000_add_extension_models/migration.sql +106 -0
- package/prisma/migrations/20260703120000_project_restricted_column/migration.sql +1 -0
- package/prisma/migrations/20260703200000_system_config_category_index/migration.sql +1 -0
- package/prisma/migrations/20260703210000_workspace_layer/migration.sql +24 -0
- package/prisma/migrations/20260703230000_workspace_agent_tokens/migration.sql +2 -0
- package/prisma/migrations/20260704000000_requirement_rls_policy/migration.sql +35 -0
- package/prisma/migrations/20260704100000_fix_oauth_auditlog_cascade/migration.sql +9 -0
- package/prisma/migrations/20260704110000_skillfile_approval_status/migration.sql +2 -0
- package/prisma/migrations/20260704120000_scenario_suspect_workspace/migration.sql +35 -0
- package/prisma/migrations/20260704130000_testcase_traceto_suspect_indexes/migration.sql +5 -0
- package/prisma/migrations/20260704140000_workspace_rls/migration.sql +19 -0
- package/prisma/migrations/20260704150000_project_cascade_deletes/migration.sql +125 -0
- package/prisma/migrations/20260705100000_platform_job_worker_id/migration.sql +12 -0
- package/prisma/migrations/20260705110000_screen_discovery_method/migration.sql +7 -0
- package/prisma/migrations/20260705120000_webhook_delivery/migration.sql +32 -0
- package/prisma/migrations/20260705130000_tenant_feature_flags/migration.sql +23 -0
- package/prisma/migrations/20260705140000_auth_sessions/migration.sql +30 -0
- package/prisma/migrations/20260705150000_fix_rls_wrong_session_var/migration.sql +51 -0
- package/prisma/migrations/20260705160000_testcase_flaky_quarantine/migration.sql +14 -0
- package/prisma/migrations/20260705170000_testcaserun_browser/migration.sql +6 -0
- package/prisma/migrations/20260705180000_allow_custom_roles/migration.sql +22 -0
- package/prisma/migrations/20260706050000_screen_markdown_extraction/migration.sql +8 -0
- package/prisma/migrations/20260706090000_add_lighthouse_to_performance_snapshot/migration.sql +4 -0
- package/prisma/migrations/20260706100000_add_lighthouse_bp_and_job_index/migration.sql +5 -0
- package/prisma/migrations/20260706110000_add_visual_diff_ai_summary/migration.sql +2 -0
- package/prisma/migrations/20260707120000_script_bundles/migration.sql +25 -0
- package/prisma/migrations/20260707130000_requirement_source_section/migration.sql +4 -0
- package/prisma/migrations/20260707140000_structured_skill_metadata/migration.sql +8 -0
- package/prisma/migrations/20260707150000_crawler_platform_primitives/migration.sql +112 -0
- package/prisma/migrations/20260707160000_screen_group_versioning/migration.sql +9 -0
- package/prisma/migrations/20260707170000_add_mfa_fields/migration.sql +24 -0
- package/prisma/migrations/20260707180000_add_missing_tables/migration.sql +158 -0
- package/prisma/migrations/20260707190000_add_missing_columns/migration.sql +15 -0
- package/prisma/migrations/20260707200000_add_plan_sessions/migration.sql +1 -0
- package/prisma/migrations/20260708100000_missing_columns_comprehensive/migration.sql +15 -0
- package/prisma/migrations/20260708200000_testcase_dataset_column/migration.sql +16 -0
- package/prisma/migrations/20260709100000_add_filename_to_native_app_build/migration.sql +1 -0
- package/prisma/migrations/20260709200000_cloud_url_visual_artifacts/migration.sql +6 -0
- package/prisma/migrations/20260714200000_add_cached_scenarios_to_artifact/migration.sql +4 -0
- package/prisma/migrations/20260715200000_screen_markdown_content/migration.sql +2 -0
- package/prisma/migrations/20260716100000_github_repo_coverage_tables/migration.sql +114 -0
- package/prisma/migrations/20260716200000_github_pr_script_validation/migration.sql +48 -0
- package/prisma/migrations/20260716210000_s3_content_keys/migration.sql +20 -0
- package/prisma/migrations/20260717220000_ide_push_token/migration.sql +21 -0
- package/prisma/migrations/20260717230000_ide_push_script_ids/migration.sql +2 -0
- package/prisma/migrations/20260730040000_add_step_evidence_and_validation/migration.sql +93 -0
- package/prisma/migrations/20260803000000_add_tenantId_to_test_data_row/migration.sql +40 -0
- package/prisma/migrations/20260804000000_add_project_restricted/migration.sql +6 -0
- package/prisma/migrations/20260804000000_add_user_avatar_url/migration.sql +4 -0
- package/prisma/migrations/20260805000000_add_auditlog_ipaddress/migration.sql +2 -0
- package/prisma/migrations/20260807000000_add_test_data_classification/migration.sql +18 -0
- package/prisma/migrations/20260807000001_add_test_case_notes/migration.sql +5 -0
- package/prisma/migrations/20260807000002_add_visual_baseline_browser_structured_steps/migration.sql +11 -0
- package/prisma/migrations/20260807100000_add_tenant_plan_config/migration.sql +14 -0
- package/prisma/migrations/20260808000000_agent_token_missing_columns/migration.sql +22 -0
- package/prisma/migrations/20260808000001_visual_diff_image_and_threshold/migration.sql +8 -0
- package/prisma/migrations/20260808000002_ssoconfig_email_domains/migration.sql +7 -0
- package/prisma/migrations/20260808000003_project_status_description_updatedat/migration.sql +7 -0
- package/prisma/migrations/20260814000000_workspace_require_mfa/migration.sql +2 -0
- package/prisma/migrations/20260814000001_add_screenshot_dpr/migration.sql +2 -0
- package/prisma/migrations/20260818000000_add_content_hash_to_test_case/migration.sql +6 -0
- package/prisma/migrations/20260818000001_add_grounding_hash_to_test_case/migration.sql +3 -0
- package/prisma/migrations/20260819000000_coverage_mapping_cross_encoder_fields/migration.sql +3 -0
- package/prisma/migrations/20260820000000_add_locators_json_to_test_case/migration.sql +6 -0
- package/prisma/migrations/20260820000001_add_test_case_version/migration.sql +27 -0
- package/prisma/migrations/20260826000000_add_capture_step_screenshots/migration.sql +1 -0
- package/prisma/migrations/20260903000000_add_platform_job_dlq/migration.sql +10 -0
- package/prisma/migrations/20260903000002_add_versioning_tables/migration.sql +38 -0
- package/prisma/migrations/20260903000003_add_learning_models/migration.sql +71 -0
- package/prisma/migrations/20260903000004_add_workspace_agent_prompts/migration.sql +33 -0
- package/prisma/migrations/20260903000005_add_config_history/migration.sql +70 -0
- package/prisma/migrations/20260903000006_add_skill_file_config/migration.sql +24 -0
- package/prisma/migrations/20260904000000_add_agent_prompt_platform_table/migration.sql +23 -0
- package/prisma/migrations/20260904180424_rbac_role_configs_admin_roles/migration.sql +606 -0
- package/prisma/migrations/20260907000000_fix_testcase_timestamps/migration.sql +13 -0
- package/prisma/migrations/20260907000001_add_artifact_imported_suite_id/migration.sql +1 -0
- package/prisma/migrations/20260907000002_add_user_login_tracking/migration.sql +9 -0
- package/prisma/migrations/20260907000003_add_artifact_import_tracking/migration.sql +9 -0
- package/prisma/migrations/20260907000004_add_artifact_version_chain/migration.sql +18 -0
- package/prisma/migrations/20260908000000_add_project_vsa_enabled/migration.sql +2 -0
- package/prisma/migrations/20260908000001_rbac_migration_catchup/migration.sql +314 -0
- package/prisma/migrations/20260908000002_fix_role_configs_empty_permissions/migration.sql +22 -0
- package/prisma/migrations/20260908000003_sync_builtin_role_permissions/migration.sql +38 -0
- package/prisma/migrations/20260909000000_add_filepath_to_testscript/migration.sql +5 -0
- package/prisma/migrations/20260909000001_add_alignment_result_table/migration.sql +31 -0
- package/prisma/migrations/20260910000000_add_admin_mfa/migration.sql +35 -0
- package/prisma/migrations/20260910000000_add_dom_snapshot_cloud_url/migration.sql +2 -0
- package/prisma/migrations/20260910000001_add_requires_auth_to_screen/migration.sql +1 -0
- package/prisma/migrations/20260910000002_add_screen_requires_auth/migration.sql +2 -0
- package/prisma/migrations/20260910000003_add_admin_auth_sessions/migration.sql +17 -0
- package/prisma/migrations/20260916000001_add_admin_last_login/migration.sql +1 -0
- package/prisma/migrations/20260916000002_add_admin_failed_login/migration.sql +2 -0
- package/prisma/migrations/20260916000003_seed_system_tenant/migration.sql +6 -0
- package/prisma/migrations/20260918000000_fix_permissions_comprehensive/migration.sql +63 -0
- package/prisma/migrations/20260924000000_add_screen_role_access/migration.sql +2 -0
- package/prisma/migrations/20260928000000_add_navigation_graph/migration.sql +41 -0
- package/prisma/migrations/20260929000000_artifact_content_hash_suite_unique/migration.sql +25 -0
- package/prisma/migrations/20260929000000_navigation_graph_unique_constraint/migration.sql +5 -0
- package/prisma/migrations/20260929000001_add_membership_status/migration.sql +7 -0
- package/prisma/migrations/20260929000002_add_sso_config_scim_token_hash/migration.sql +8 -0
- package/prisma/migrations/20261005000001_jobs_workers_hardening/migration.sql +63 -0
- package/prisma/migrations/20261009000001_add_suite_category/migration.sql +2 -0
- package/prisma/migrations/20261009000002_add_testcase_approved_fields/migration.sql +3 -0
- package/prisma/migrations/20261012_auto_version_history/migration.sql +111 -0
- package/prisma/migrations/20261015000001_traceability_alignment_gaps/migration.sql +11 -0
- package/prisma/migrations/20261028000001_context_intelligence_p1_p7/migration.sql +76 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +2901 -0
- package/prisma/seed.ts +1262 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- RLS FOR MISSING TABLES — extends 0001_tenant_isolation
|
|
3
|
+
--
|
|
4
|
+
-- This migration applies Row-Level Security to tables that were added after
|
|
5
|
+
-- the initial tenant isolation migration (0001_tenant_isolation). All tables
|
|
6
|
+
-- listed here follow the same pattern: a "tenantId" column scoped to the
|
|
7
|
+
-- owning tenant, isolated via the app.current_tenant session variable.
|
|
8
|
+
--
|
|
9
|
+
-- Tables covered here (NOT in 0001_tenant_isolation):
|
|
10
|
+
-- PlatformJob, UserSession, LLMCallLog, TokenBudget, OAuthConnection,
|
|
11
|
+
-- ElementFingerprint, TestRun, TestResult, ProjectArtifact, VisualBaseline,
|
|
12
|
+
-- VisualDiff, HumanReviewItem, AgentToken, Webhook, KnowledgeChunk,
|
|
13
|
+
-- TenantSetting
|
|
14
|
+
-- ============================================================================
|
|
15
|
+
|
|
16
|
+
DO $$
|
|
17
|
+
DECLARE
|
|
18
|
+
t text;
|
|
19
|
+
tenant_tables text[] := ARRAY[
|
|
20
|
+
'PlatformJob','UserSession','LLMCallLog','TokenBudget','OAuthConnection',
|
|
21
|
+
'ElementFingerprint','TestRun','TestResult','ProjectArtifact','VisualBaseline',
|
|
22
|
+
'VisualDiff','HumanReviewItem','AgentToken','Webhook','KnowledgeChunk',
|
|
23
|
+
'TenantSetting'
|
|
24
|
+
];
|
|
25
|
+
BEGIN
|
|
26
|
+
FOREACH t IN ARRAY tenant_tables LOOP
|
|
27
|
+
EXECUTE format('ALTER TABLE "%s" ENABLE ROW LEVEL SECURITY;', t);
|
|
28
|
+
EXECUTE format('ALTER TABLE "%s" FORCE ROW LEVEL SECURITY;', t);
|
|
29
|
+
BEGIN
|
|
30
|
+
EXECUTE format($f$
|
|
31
|
+
CREATE POLICY tenant_isolation ON "%s"
|
|
32
|
+
USING ("tenantId" = current_setting('app.current_tenant', true))
|
|
33
|
+
WITH CHECK ("tenantId" = current_setting('app.current_tenant', true));
|
|
34
|
+
$f$, t);
|
|
35
|
+
EXCEPTION WHEN duplicate_object THEN
|
|
36
|
+
NULL; -- policy already exists, skip
|
|
37
|
+
END;
|
|
38
|
+
END LOOP;
|
|
39
|
+
END $$;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
-- TokenBudget: per-tenant monthly token and USD spending limits with running counters.
|
|
2
|
+
CREATE TABLE IF NOT EXISTS "TokenBudget" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"tenantId" TEXT NOT NULL,
|
|
5
|
+
"monthlyTokenCap" INTEGER,
|
|
6
|
+
"monthlyUsdCap" DOUBLE PRECISION,
|
|
7
|
+
"alertAtPercent" INTEGER NOT NULL DEFAULT 80,
|
|
8
|
+
"currentMonthTokens" INTEGER NOT NULL DEFAULT 0,
|
|
9
|
+
"currentMonthUsd" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
|
10
|
+
"lastResetAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
11
|
+
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
CONSTRAINT "TokenBudget_pkey" PRIMARY KEY ("id")
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "TokenBudget_tenantId_key" ON "TokenBudget"("tenantId");
|
|
16
|
+
|
|
17
|
+
DO $$ BEGIN
|
|
18
|
+
ALTER TABLE "TokenBudget" ADD CONSTRAINT "TokenBudget_tenantId_fkey"
|
|
19
|
+
FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
20
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
21
|
+
END $$;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
-- ScreenGroup: AI-generated semantic grouping of screens during post-crawl
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS "ScreenGroup" (
|
|
4
|
+
"id" TEXT NOT NULL,
|
|
5
|
+
"tenantId" TEXT NOT NULL,
|
|
6
|
+
"projectId" TEXT NOT NULL,
|
|
7
|
+
"name" TEXT NOT NULL,
|
|
8
|
+
"slug" TEXT NOT NULL,
|
|
9
|
+
"description" TEXT,
|
|
10
|
+
"color" TEXT NOT NULL DEFAULT '#6FD0E8',
|
|
11
|
+
"icon" TEXT NOT NULL DEFAULT '◈',
|
|
12
|
+
"order" INTEGER NOT NULL DEFAULT 0,
|
|
13
|
+
CONSTRAINT "ScreenGroup_pkey" PRIMARY KEY ("id")
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE INDEX IF NOT EXISTS "ScreenGroup_tenantId_projectId_idx" ON "ScreenGroup"("tenantId", "projectId");
|
|
17
|
+
|
|
18
|
+
-- FK: ScreenGroup → Project
|
|
19
|
+
DO $$ BEGIN
|
|
20
|
+
ALTER TABLE "ScreenGroup" ADD CONSTRAINT "ScreenGroup_projectId_fkey"
|
|
21
|
+
FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
22
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
23
|
+
END $$;
|
|
24
|
+
|
|
25
|
+
-- Add groupId to Screen
|
|
26
|
+
ALTER TABLE "Screen" ADD COLUMN IF NOT EXISTS "groupId" TEXT;
|
|
27
|
+
|
|
28
|
+
-- FK: Screen → ScreenGroup
|
|
29
|
+
DO $$ BEGIN
|
|
30
|
+
ALTER TABLE "Screen" ADD CONSTRAINT "Screen_groupId_fkey"
|
|
31
|
+
FOREIGN KEY ("groupId") REFERENCES "ScreenGroup"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
32
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
33
|
+
END $$;
|
|
34
|
+
|
|
35
|
+
-- RLS for ScreenGroup
|
|
36
|
+
ALTER TABLE "ScreenGroup" ENABLE ROW LEVEL SECURITY;
|
|
37
|
+
|
|
38
|
+
DO $$ BEGIN
|
|
39
|
+
CREATE POLICY "tenant_isolation" ON "ScreenGroup"
|
|
40
|
+
USING ("tenantId" = current_setting('app.tenant_id', true));
|
|
41
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
42
|
+
END $$;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- Add AI-generated intelligence fields to ProjectArtifact
|
|
2
|
+
ALTER TABLE "ProjectArtifact" ADD COLUMN IF NOT EXISTS "summary" TEXT;
|
|
3
|
+
ALTER TABLE "ProjectArtifact" ADD COLUMN IF NOT EXISTS "keywords" TEXT[] NOT NULL DEFAULT '{}';
|
|
4
|
+
ALTER TABLE "ProjectArtifact" ADD COLUMN IF NOT EXISTS "docType" TEXT;
|
|
5
|
+
ALTER TABLE "ProjectArtifact" ADD COLUMN IF NOT EXISTS "chunkCount" INTEGER NOT NULL DEFAULT 1;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- Add Notification and NotificationPreference tables
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS "Notification" (
|
|
4
|
+
"id" TEXT NOT NULL,
|
|
5
|
+
"tenantId" TEXT NOT NULL,
|
|
6
|
+
"userId" TEXT NOT NULL,
|
|
7
|
+
"type" TEXT NOT NULL,
|
|
8
|
+
"title" TEXT NOT NULL,
|
|
9
|
+
"body" TEXT NOT NULL,
|
|
10
|
+
"metadata" JSONB,
|
|
11
|
+
"read" BOOLEAN NOT NULL DEFAULT false,
|
|
12
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
13
|
+
CONSTRAINT "Notification_pkey" PRIMARY KEY ("id"),
|
|
14
|
+
CONSTRAINT "Notification_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE,
|
|
15
|
+
CONSTRAINT "Notification_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
CREATE INDEX IF NOT EXISTS "Notification_tenantId_userId_read_idx" ON "Notification"("tenantId", "userId", "read");
|
|
19
|
+
CREATE INDEX IF NOT EXISTS "Notification_tenantId_createdAt_idx" ON "Notification"("tenantId", "createdAt");
|
|
20
|
+
|
|
21
|
+
CREATE TABLE IF NOT EXISTS "NotificationPreference" (
|
|
22
|
+
"id" TEXT NOT NULL,
|
|
23
|
+
"tenantId" TEXT NOT NULL,
|
|
24
|
+
"userId" TEXT NOT NULL,
|
|
25
|
+
"eventType" TEXT NOT NULL,
|
|
26
|
+
"inApp" BOOLEAN NOT NULL DEFAULT true,
|
|
27
|
+
"email" BOOLEAN NOT NULL DEFAULT true,
|
|
28
|
+
CONSTRAINT "NotificationPreference_pkey" PRIMARY KEY ("id"),
|
|
29
|
+
CONSTRAINT "NotificationPreference_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE,
|
|
30
|
+
CONSTRAINT "NotificationPreference_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE,
|
|
31
|
+
CONSTRAINT "NotificationPreference_userId_tenantId_eventType_key" UNIQUE ("userId", "tenantId", "eventType")
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
CREATE INDEX IF NOT EXISTS "NotificationPreference_tenantId_userId_idx" ON "NotificationPreference"("tenantId", "userId");
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
ALTER TABLE "Screen" ADD COLUMN IF NOT EXISTS "status" TEXT NOT NULL DEFAULT 'ACTIVE';
|
|
2
|
+
ALTER TABLE "Screen" ADD COLUMN IF NOT EXISTS "lastCrawlJobId" TEXT;
|
|
3
|
+
ALTER TABLE "Screen" ADD COLUMN IF NOT EXISTS "removedAt" TIMESTAMP(3);
|
|
4
|
+
ALTER TABLE "Screen" ADD COLUMN IF NOT EXISTS "removalReason" TEXT;
|
|
5
|
+
CREATE INDEX IF NOT EXISTS "Screen_tenantId_projectId_status_idx" ON "Screen"("tenantId", "projectId", "status");
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Native app build upload support
|
|
2
|
+
|
|
3
|
+
-- Project.appType: web | android | ios | windows | macos | electron
|
|
4
|
+
ALTER TABLE "Project" ADD COLUMN IF NOT EXISTS "appType" TEXT;
|
|
5
|
+
|
|
6
|
+
-- PlatformJob device/Appium metadata columns
|
|
7
|
+
ALTER TABLE "PlatformJob" ADD COLUMN IF NOT EXISTS "deviceModel" TEXT;
|
|
8
|
+
ALTER TABLE "PlatformJob" ADD COLUMN IF NOT EXISTS "osVersion" TEXT;
|
|
9
|
+
ALTER TABLE "PlatformJob" ADD COLUMN IF NOT EXISTS "deviceFarm" TEXT;
|
|
10
|
+
ALTER TABLE "PlatformJob" ADD COLUMN IF NOT EXISTS "appiumSessionId" TEXT;
|
|
11
|
+
|
|
12
|
+
-- NativeAppBuild: stores upload metadata (S3 path, platform, file format, etc.)
|
|
13
|
+
CREATE TABLE IF NOT EXISTS "NativeAppBuild" (
|
|
14
|
+
"id" TEXT NOT NULL,
|
|
15
|
+
"tenantId" TEXT NOT NULL,
|
|
16
|
+
"projectId" TEXT NOT NULL,
|
|
17
|
+
"platform" TEXT NOT NULL,
|
|
18
|
+
"fileFormat" TEXT NOT NULL,
|
|
19
|
+
"s3Path" TEXT NOT NULL,
|
|
20
|
+
"packageName" TEXT,
|
|
21
|
+
"version" TEXT,
|
|
22
|
+
"uploadedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
23
|
+
CONSTRAINT "NativeAppBuild_pkey" PRIMARY KEY ("id"),
|
|
24
|
+
CONSTRAINT "NativeAppBuild_projectId_fkey"
|
|
25
|
+
FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE INDEX IF NOT EXISTS "NativeAppBuild_tenantId_projectId_idx" ON "NativeAppBuild"("tenantId", "projectId");
|
|
29
|
+
|
|
30
|
+
-- RLS: row-level security on NativeAppBuild (same pattern as other tables)
|
|
31
|
+
ALTER TABLE "NativeAppBuild" ENABLE ROW LEVEL SECURITY;
|
|
32
|
+
ALTER TABLE "NativeAppBuild" FORCE ROW LEVEL SECURITY;
|
|
33
|
+
|
|
34
|
+
DO $$
|
|
35
|
+
BEGIN
|
|
36
|
+
CREATE POLICY tenant_isolation ON "NativeAppBuild"
|
|
37
|
+
USING ("tenantId" = current_setting('app.current_tenant', true))
|
|
38
|
+
WITH CHECK ("tenantId" = current_setting('app.current_tenant', true));
|
|
39
|
+
EXCEPTION WHEN duplicate_object THEN
|
|
40
|
+
NULL;
|
|
41
|
+
END $$;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- RLS FOR MISSING TABLES — extends 20260626090000_rls_missing_tables
|
|
3
|
+
--
|
|
4
|
+
-- Applies Row-Level Security to tables that were added after the previous
|
|
5
|
+
-- RLS catch-up migration. All tables follow the same pattern used throughout
|
|
6
|
+
-- this project: a "tenantId" column scoped via the app.current_tenant
|
|
7
|
+
-- session variable.
|
|
8
|
+
--
|
|
9
|
+
-- Tables covered here:
|
|
10
|
+
-- ScreenDiff, ProbeObservation, TestCaseRun, Notification,
|
|
11
|
+
-- NotificationPreference
|
|
12
|
+
--
|
|
13
|
+
-- NOTE (fixed post-hoc): ScreenDiff, ProbeObservation, and TestCaseRun are
|
|
14
|
+
-- actually created by LATER migrations (20260628120000_screen_diff,
|
|
15
|
+
-- 20260628130000_probe_observations, 20260630130000_test_case_runs). On any
|
|
16
|
+
-- database that evolved incrementally in dev those tables already existed
|
|
17
|
+
-- by the time this ran, so it never failed there — but on a genuinely fresh
|
|
18
|
+
-- `prisma migrate deploy` this migration fails outright with
|
|
19
|
+
-- "relation does not exist" before those tables are ever created, which
|
|
20
|
+
-- breaks bootstrapping a brand-new environment/region from scratch.
|
|
21
|
+
-- Guarding each statement with a to_regclass() existence check makes this
|
|
22
|
+
-- migration a no-op for tables that don't exist yet without changing its
|
|
23
|
+
-- effect anywhere it already succeeded. RLS for the three later tables is
|
|
24
|
+
-- finished off for real in 20260630160000_rls_catchup_late_tables, once
|
|
25
|
+
-- they're guaranteed to exist.
|
|
26
|
+
--
|
|
27
|
+
-- If this migration's checksum was already recorded by `prisma migrate
|
|
28
|
+
-- deploy` against a database, applying this edited file will fail with a
|
|
29
|
+
-- "migration modified" error. Resolve with:
|
|
30
|
+
-- npx prisma migrate resolve --applied 20260627200000_rls_missing_tables
|
|
31
|
+
-- ============================================================================
|
|
32
|
+
|
|
33
|
+
DO $$
|
|
34
|
+
DECLARE
|
|
35
|
+
t text;
|
|
36
|
+
tenant_tables text[] := ARRAY[
|
|
37
|
+
'ScreenDiff','ProbeObservation','TestCaseRun','Notification',
|
|
38
|
+
'NotificationPreference'
|
|
39
|
+
];
|
|
40
|
+
BEGIN
|
|
41
|
+
FOREACH t IN ARRAY tenant_tables LOOP
|
|
42
|
+
IF to_regclass(format('"%s"', t)) IS NULL THEN
|
|
43
|
+
CONTINUE; -- table doesn't exist yet on a fresh deploy; caught up later
|
|
44
|
+
END IF;
|
|
45
|
+
EXECUTE format('ALTER TABLE "%s" ENABLE ROW LEVEL SECURITY;', t);
|
|
46
|
+
EXECUTE format('ALTER TABLE "%s" FORCE ROW LEVEL SECURITY;', t);
|
|
47
|
+
BEGIN
|
|
48
|
+
EXECUTE format($f$
|
|
49
|
+
CREATE POLICY tenant_isolation ON "%s"
|
|
50
|
+
USING ("tenantId" = current_setting('app.current_tenant', true))
|
|
51
|
+
WITH CHECK ("tenantId" = current_setting('app.current_tenant', true));
|
|
52
|
+
$f$, t);
|
|
53
|
+
EXCEPTION WHEN duplicate_object THEN
|
|
54
|
+
NULL; -- policy already exists, skip
|
|
55
|
+
END;
|
|
56
|
+
END LOOP;
|
|
57
|
+
END $$;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "LLMCallLog" ADD COLUMN IF NOT EXISTS "taskType" TEXT;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
-- Phase 1: Element model enrichment — bounding rect, aria state, parent landmark
|
|
2
|
+
ALTER TABLE "Element" ADD COLUMN IF NOT EXISTS "boundingRect" JSONB;
|
|
3
|
+
ALTER TABLE "Element" ADD COLUMN IF NOT EXISTS "ariaState" JSONB;
|
|
4
|
+
ALTER TABLE "Element" ADD COLUMN IF NOT EXISTS "parentLandmark" TEXT;
|
|
5
|
+
|
|
6
|
+
CREATE INDEX IF NOT EXISTS "Element_tenantId_screenId_parentLandmark_idx"
|
|
7
|
+
ON "Element"("tenantId", "screenId", "parentLandmark");
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- Phase 2: Element hash for stale-test detection
|
|
2
|
+
ALTER TABLE "Screen" ADD COLUMN IF NOT EXISTS "elementHash" TEXT;
|
|
3
|
+
ALTER TABLE "Screen" ADD COLUMN IF NOT EXISTS "elementHashChangedAt" TIMESTAMP(3);
|
|
4
|
+
|
|
5
|
+
CREATE INDEX IF NOT EXISTS "Screen_tenantId_projectId_elementHashChangedAt_idx"
|
|
6
|
+
ON "Screen"("tenantId", "projectId", "elementHashChangedAt");
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- Phase 3: Perceptual screenshot diff
|
|
2
|
+
CREATE TABLE IF NOT EXISTS "ScreenDiff" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"tenantId" TEXT NOT NULL,
|
|
5
|
+
"projectId" TEXT NOT NULL,
|
|
6
|
+
"screenId" TEXT NOT NULL,
|
|
7
|
+
"fromVersion" INTEGER NOT NULL,
|
|
8
|
+
"toVersion" INTEGER NOT NULL,
|
|
9
|
+
"pHashDistance" DOUBLE PRECISION NOT NULL,
|
|
10
|
+
"changeLevel" TEXT NOT NULL,
|
|
11
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
CONSTRAINT "ScreenDiff_pkey" PRIMARY KEY ("id"),
|
|
13
|
+
CONSTRAINT "ScreenDiff_screenId_fkey"
|
|
14
|
+
FOREIGN KEY ("screenId") REFERENCES "Screen"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
15
|
+
CONSTRAINT "ScreenDiff_screenId_fromVersion_toVersion_key"
|
|
16
|
+
UNIQUE ("screenId", "fromVersion", "toVersion")
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE INDEX IF NOT EXISTS "ScreenDiff_tenantId_projectId_idx" ON "ScreenDiff"("tenantId", "projectId");
|
|
20
|
+
CREATE INDEX IF NOT EXISTS "ScreenDiff_tenantId_screenId_idx" ON "ScreenDiff"("tenantId", "screenId");
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- Phase 5: Structured probe observations
|
|
2
|
+
CREATE TABLE IF NOT EXISTS "ProbeObservation" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"tenantId" TEXT NOT NULL,
|
|
5
|
+
"projectId" TEXT NOT NULL,
|
|
6
|
+
"screenId" TEXT NOT NULL,
|
|
7
|
+
"elementMeaning" TEXT NOT NULL,
|
|
8
|
+
"observationType" TEXT NOT NULL,
|
|
9
|
+
"observedText" TEXT NOT NULL,
|
|
10
|
+
"triggeredBy" TEXT NOT NULL,
|
|
11
|
+
"observedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
CONSTRAINT "ProbeObservation_pkey" PRIMARY KEY ("id"),
|
|
13
|
+
CONSTRAINT "ProbeObservation_screenId_fkey"
|
|
14
|
+
FOREIGN KEY ("screenId") REFERENCES "Screen"("id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
CREATE INDEX IF NOT EXISTS "ProbeObservation_tenantId_projectId_idx" ON "ProbeObservation"("tenantId", "projectId");
|
|
18
|
+
CREATE INDEX IF NOT EXISTS "ProbeObservation_tenantId_screenId_idx" ON "ProbeObservation"("tenantId", "screenId");
|
|
19
|
+
CREATE INDEX IF NOT EXISTS "ProbeObservation_tenantId_screenId_observationType_idx" ON "ProbeObservation"("tenantId", "screenId", "observationType");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "VisualBaseline" ADD COLUMN IF NOT EXISTS "ignoredRegions" JSONB NOT NULL DEFAULT '[]';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "TestCase" ADD COLUMN IF NOT EXISTS "viewports" JSONB NOT NULL DEFAULT '[]';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "VisualBaseline" ADD COLUMN "elementSnapshot" JSONB;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Add git branch/commit tracking to visual baselines
|
|
2
|
+
ALTER TABLE "VisualBaseline" ADD COLUMN "gitBranch" TEXT NOT NULL DEFAULT 'main';
|
|
3
|
+
ALTER TABLE "VisualBaseline" ADD COLUMN "gitCommit" TEXT;
|
|
4
|
+
ALTER TABLE "VisualBaseline" ADD COLUMN "domSnapshotPath" TEXT;
|
|
5
|
+
|
|
6
|
+
-- Add DOM snapshot path to Screen
|
|
7
|
+
ALTER TABLE "Screen" ADD COLUMN "domSnapshotPath" TEXT;
|
|
8
|
+
|
|
9
|
+
-- Drop old unique constraint and replace with branch-aware one
|
|
10
|
+
DROP INDEX IF EXISTS "VisualBaseline_screenId_viewport_key";
|
|
11
|
+
CREATE UNIQUE INDEX "VisualBaseline_screenId_viewport_gitBranch_key" ON "VisualBaseline"("screenId", "viewport", "gitBranch");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "TestCase" ADD COLUMN "viewportConstraint" TEXT NOT NULL DEFAULT 'ALL';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- CreateTable: per-test-case execution run (distinct from suite-level TestRun)
|
|
2
|
+
CREATE TABLE "TestCaseRun" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"testCaseId" TEXT NOT NULL,
|
|
5
|
+
"tenantId" TEXT NOT NULL,
|
|
6
|
+
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
|
7
|
+
"executionPlan" JSONB,
|
|
8
|
+
"stepResults" JSONB,
|
|
9
|
+
"totalDuration" INTEGER,
|
|
10
|
+
"errorStep" INTEGER,
|
|
11
|
+
"errorMessage" TEXT,
|
|
12
|
+
"screenshotPath" TEXT,
|
|
13
|
+
"viewport" TEXT NOT NULL DEFAULT 'DESKTOP',
|
|
14
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
15
|
+
"completedAt" TIMESTAMP(3),
|
|
16
|
+
CONSTRAINT "TestCaseRun_pkey" PRIMARY KEY ("id")
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
ALTER TABLE "TestCaseRun" ADD CONSTRAINT "TestCaseRun_testCaseId_fkey"
|
|
20
|
+
FOREIGN KEY ("testCaseId") REFERENCES "TestCase"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
21
|
+
|
|
22
|
+
CREATE INDEX "TestCaseRun_tenantId_testCaseId_idx" ON "TestCaseRun"("tenantId", "testCaseId");
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
-- CreateTable PerformanceSnapshot
|
|
2
|
+
CREATE TABLE "PerformanceSnapshot" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"tenantId" TEXT NOT NULL,
|
|
5
|
+
"screenId" TEXT NOT NULL,
|
|
6
|
+
"crawlJobId" TEXT NOT NULL,
|
|
7
|
+
"lcp" DOUBLE PRECISION,
|
|
8
|
+
"fcp" DOUBLE PRECISION,
|
|
9
|
+
"cls" DOUBLE PRECISION,
|
|
10
|
+
"ttfb" DOUBLE PRECISION,
|
|
11
|
+
"viewport" TEXT NOT NULL DEFAULT 'DESKTOP',
|
|
12
|
+
"capturedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
13
|
+
|
|
14
|
+
CONSTRAINT "PerformanceSnapshot_pkey" PRIMARY KEY ("id")
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
-- CreateTable ProjectEnvironment
|
|
18
|
+
CREATE TABLE "ProjectEnvironment" (
|
|
19
|
+
"id" TEXT NOT NULL,
|
|
20
|
+
"tenantId" TEXT NOT NULL,
|
|
21
|
+
"projectId" TEXT NOT NULL,
|
|
22
|
+
"name" TEXT NOT NULL,
|
|
23
|
+
"baseUrl" TEXT NOT NULL,
|
|
24
|
+
"credentials_enc" TEXT,
|
|
25
|
+
"isDefault" BOOLEAN NOT NULL DEFAULT false,
|
|
26
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
27
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
28
|
+
|
|
29
|
+
CONSTRAINT "ProjectEnvironment_pkey" PRIMARY KEY ("id")
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
-- CreateTable Comment
|
|
33
|
+
CREATE TABLE "Comment" (
|
|
34
|
+
"id" TEXT NOT NULL,
|
|
35
|
+
"tenantId" TEXT NOT NULL,
|
|
36
|
+
"parentType" TEXT NOT NULL,
|
|
37
|
+
"parentId" TEXT NOT NULL,
|
|
38
|
+
"userId" TEXT NOT NULL,
|
|
39
|
+
"body" TEXT NOT NULL,
|
|
40
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
41
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
42
|
+
|
|
43
|
+
CONSTRAINT "Comment_pkey" PRIMARY KEY ("id")
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
-- CreateIndex
|
|
47
|
+
CREATE INDEX "PerformanceSnapshot_tenantId_screenId_idx" ON "PerformanceSnapshot"("tenantId", "screenId");
|
|
48
|
+
CREATE INDEX "PerformanceSnapshot_tenantId_crawlJobId_idx" ON "PerformanceSnapshot"("tenantId", "crawlJobId");
|
|
49
|
+
|
|
50
|
+
-- CreateIndex
|
|
51
|
+
CREATE INDEX "ProjectEnvironment_tenantId_projectId_idx" ON "ProjectEnvironment"("tenantId", "projectId");
|
|
52
|
+
|
|
53
|
+
-- CreateIndex
|
|
54
|
+
CREATE INDEX "Comment_tenantId_parentType_parentId_idx" ON "Comment"("tenantId", "parentType", "parentId");
|
|
55
|
+
|
|
56
|
+
-- Enable RLS
|
|
57
|
+
ALTER TABLE "PerformanceSnapshot" ENABLE ROW LEVEL SECURITY;
|
|
58
|
+
ALTER TABLE "ProjectEnvironment" ENABLE ROW LEVEL SECURITY;
|
|
59
|
+
ALTER TABLE "Comment" ENABLE ROW LEVEL SECURITY;
|
|
60
|
+
|
|
61
|
+
CREATE POLICY "tenant_isolation_perf" ON "PerformanceSnapshot"
|
|
62
|
+
USING (current_setting('app.tenant_id', true) = "tenantId");
|
|
63
|
+
|
|
64
|
+
CREATE POLICY "tenant_isolation_env" ON "ProjectEnvironment"
|
|
65
|
+
USING (current_setting('app.tenant_id', true) = "tenantId");
|
|
66
|
+
|
|
67
|
+
CREATE POLICY "tenant_isolation_comment" ON "Comment"
|
|
68
|
+
USING (current_setting('app.tenant_id', true) = "tenantId");
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- RLS CATCH-UP FOR LATE TABLES — finishes what 20260627200000_rls_missing_tables
|
|
3
|
+
-- couldn't, for ScreenDiff, ProbeObservation, and TestCaseRun.
|
|
4
|
+
--
|
|
5
|
+
-- Those three tables are created by migrations that run AFTER
|
|
6
|
+
-- 20260627200000_rls_missing_tables (20260628120000_screen_diff,
|
|
7
|
+
-- 20260628130000_probe_observations, 20260630130000_test_case_runs), so the
|
|
8
|
+
-- earlier migration's attempt to enable RLS on them is now a guarded no-op
|
|
9
|
+
-- on a fresh database (see the note added there). This migration runs after
|
|
10
|
+
-- all three tables definitely exist and applies the same tenant-isolation
|
|
11
|
+
-- pattern used throughout the project.
|
|
12
|
+
--
|
|
13
|
+
-- Idempotent: safe to run even where 20260627200000 already succeeded in
|
|
14
|
+
-- applying RLS to these tables (e.g. a database that evolved incrementally
|
|
15
|
+
-- in dev, where the tables pre-existed) — ENABLE/FORCE ROW LEVEL SECURITY
|
|
16
|
+
-- are no-ops when already set, and policy creation is guarded against
|
|
17
|
+
-- duplicate_object.
|
|
18
|
+
-- ============================================================================
|
|
19
|
+
|
|
20
|
+
DO $$
|
|
21
|
+
DECLARE
|
|
22
|
+
t text;
|
|
23
|
+
tenant_tables text[] := ARRAY['ScreenDiff','ProbeObservation','TestCaseRun'];
|
|
24
|
+
BEGIN
|
|
25
|
+
FOREACH t IN ARRAY tenant_tables LOOP
|
|
26
|
+
IF to_regclass(format('"%s"', t)) IS NULL THEN
|
|
27
|
+
CONTINUE; -- defensive; should always exist by this point
|
|
28
|
+
END IF;
|
|
29
|
+
EXECUTE format('ALTER TABLE "%s" ENABLE ROW LEVEL SECURITY;', t);
|
|
30
|
+
EXECUTE format('ALTER TABLE "%s" FORCE ROW LEVEL SECURITY;', t);
|
|
31
|
+
BEGIN
|
|
32
|
+
EXECUTE format($f$
|
|
33
|
+
CREATE POLICY tenant_isolation ON "%s"
|
|
34
|
+
USING ("tenantId" = current_setting('app.current_tenant', true))
|
|
35
|
+
WITH CHECK ("tenantId" = current_setting('app.current_tenant', true));
|
|
36
|
+
$f$, t);
|
|
37
|
+
EXCEPTION WHEN duplicate_object THEN
|
|
38
|
+
NULL; -- policy already exists, skip
|
|
39
|
+
END;
|
|
40
|
+
END LOOP;
|
|
41
|
+
END $$;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- Add diff tracking and approval status fields to SkillFile
|
|
2
|
+
ALTER TABLE "SkillFile" ADD COLUMN "priorContent" TEXT;
|
|
3
|
+
ALTER TABLE "SkillFile" ADD COLUMN "priorVersion" INTEGER;
|
|
4
|
+
ALTER TABLE "SkillFile" ADD COLUMN "priorGeneratedAt" TIMESTAMP(3);
|
|
5
|
+
ALTER TABLE "SkillFile" ADD COLUMN "changesSummary" TEXT;
|
|
6
|
+
ALTER TABLE "SkillFile" ADD COLUMN "approvalStatus" TEXT NOT NULL DEFAULT 'PENDING';
|
|
7
|
+
|
|
8
|
+
-- Backfill: existing approved files
|
|
9
|
+
UPDATE "SkillFile" SET "approvalStatus" = 'APPROVED' WHERE "approvedBy" IS NOT NULL;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "WorkspaceConnector" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"tenantId" TEXT NOT NULL,
|
|
5
|
+
"kind" TEXT NOT NULL,
|
|
6
|
+
"secretRef" TEXT NOT NULL DEFAULT 'local-aes256',
|
|
7
|
+
"config" JSONB,
|
|
8
|
+
"testOk" BOOLEAN NOT NULL DEFAULT false,
|
|
9
|
+
"testedAt" TIMESTAMP(3),
|
|
10
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
11
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
12
|
+
|
|
13
|
+
CONSTRAINT "WorkspaceConnector_pkey" PRIMARY KEY ("id")
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
-- CreateIndex
|
|
17
|
+
CREATE UNIQUE INDEX "WorkspaceConnector_tenantId_kind_key" ON "WorkspaceConnector"("tenantId", "kind");
|
|
18
|
+
|
|
19
|
+
-- CreateIndex
|
|
20
|
+
CREATE INDEX "WorkspaceConnector_tenantId_idx" ON "WorkspaceConnector"("tenantId");
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-- TestSuite: owner assignment
|
|
2
|
+
ALTER TABLE "TestSuite" ADD COLUMN IF NOT EXISTS "ownerUserId" TEXT;
|
|
3
|
+
|
|
4
|
+
-- TestResult: network timings + data-driven row
|
|
5
|
+
ALTER TABLE "TestResult" ADD COLUMN IF NOT EXISTS "networkTimings" JSONB;
|
|
6
|
+
ALTER TABLE "TestResult" ADD COLUMN IF NOT EXISTS "dataRow" JSONB;
|
|
7
|
+
|
|
8
|
+
-- Project: SLA threshold
|
|
9
|
+
ALTER TABLE "Project" ADD COLUMN IF NOT EXISTS "slaThreshold" INTEGER;
|
|
10
|
+
|
|
11
|
+
-- PerformanceSnapshot: Lighthouse scores
|
|
12
|
+
ALTER TABLE "PerformanceSnapshot" ADD COLUMN IF NOT EXISTS "lighthousePerf" INTEGER;
|
|
13
|
+
ALTER TABLE "PerformanceSnapshot" ADD COLUMN IF NOT EXISTS "lighthouseA11y" INTEGER;
|
|
14
|
+
ALTER TABLE "PerformanceSnapshot" ADD COLUMN IF NOT EXISTS "lighthouseSEO" INTEGER;
|
|
15
|
+
ALTER TABLE "PerformanceSnapshot" ADD COLUMN IF NOT EXISTS "lighthouseBP" INTEGER;
|
|
16
|
+
ALTER TABLE "PerformanceSnapshot" ADD COLUMN IF NOT EXISTS "lighthouseReport" JSONB;
|
|
17
|
+
|
|
18
|
+
-- SharedRunToken: shareable signed links
|
|
19
|
+
CREATE TABLE IF NOT EXISTS "SharedRunToken" (
|
|
20
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
21
|
+
"tenantId" TEXT NOT NULL,
|
|
22
|
+
"runId" TEXT NOT NULL,
|
|
23
|
+
"token" TEXT NOT NULL UNIQUE,
|
|
24
|
+
"expiresAt" TIMESTAMPTZ NOT NULL,
|
|
25
|
+
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
26
|
+
);
|
|
27
|
+
CREATE INDEX IF NOT EXISTS "SharedRunToken_tenantId_idx" ON "SharedRunToken"("tenantId");
|
|
28
|
+
CREATE INDEX IF NOT EXISTS "SharedRunToken_token_idx" ON "SharedRunToken"("token");
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
-- TestCase: v2 technique-of-record field
|
|
2
|
+
ALTER TABLE "TestCase" ADD COLUMN IF NOT EXISTS "techniqueOfRecord" TEXT;
|
|
3
|
+
ALTER TABLE "TestCase" ADD COLUMN IF NOT EXISTS "traceTo" TEXT;
|
|
4
|
+
ALTER TABLE "TestCase" ADD COLUMN IF NOT EXISTS "testDataInline" JSONB;
|
|
5
|
+
|
|
6
|
+
-- TestSuite: coverage reporting
|
|
7
|
+
ALTER TABLE "TestSuite" ADD COLUMN IF NOT EXISTS "coverageReport" JSONB;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "AppField" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"tenantId" TEXT NOT NULL,
|
|
5
|
+
"projectId" TEXT NOT NULL,
|
|
6
|
+
"fieldKey" TEXT NOT NULL,
|
|
7
|
+
"label" TEXT NOT NULL,
|
|
8
|
+
"elementRole" TEXT NOT NULL,
|
|
9
|
+
"dataBearing" BOOLEAN NOT NULL DEFAULT true,
|
|
10
|
+
"dataType" TEXT NOT NULL,
|
|
11
|
+
"required" BOOLEAN NOT NULL DEFAULT false,
|
|
12
|
+
"minLength" INTEGER,
|
|
13
|
+
"maxLength" INTEGER,
|
|
14
|
+
"minValue" DOUBLE PRECISION,
|
|
15
|
+
"maxValue" DOUBLE PRECISION,
|
|
16
|
+
"precision" INTEGER,
|
|
17
|
+
"regex" TEXT,
|
|
18
|
+
"enumValues" JSONB,
|
|
19
|
+
"piiClass" TEXT NOT NULL DEFAULT 'none',
|
|
20
|
+
"exampleValue" TEXT,
|
|
21
|
+
"relationGroup" TEXT,
|
|
22
|
+
"notes" TEXT,
|
|
23
|
+
"status" TEXT NOT NULL DEFAULT 'unconfirmed',
|
|
24
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
25
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
26
|
+
|
|
27
|
+
CONSTRAINT "AppField_pkey" PRIMARY KEY ("id")
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
-- CreateIndex
|
|
31
|
+
CREATE UNIQUE INDEX "AppField_tenantId_projectId_fieldKey_key" ON "AppField"("tenantId", "projectId", "fieldKey");
|
|
32
|
+
|
|
33
|
+
-- CreateIndex
|
|
34
|
+
CREATE INDEX "AppField_tenantId_projectId_idx" ON "AppField"("tenantId", "projectId");
|
|
35
|
+
|
|
36
|
+
-- AddForeignKey
|
|
37
|
+
ALTER TABLE "AppField" ADD CONSTRAINT "AppField_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
38
|
+
|
|
39
|
+
-- RowLevelSecurity (matches tenant isolation pattern used by all other tables)
|
|
40
|
+
ALTER TABLE "AppField" ENABLE ROW LEVEL SECURITY;
|