@storyshelf/db-postgres 0.9.0-next-7e51b98 → 0.9.0-next-3604136
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/dist/ddl.d.mts +1 -1
- package/dist/ddl.mjs +2 -0
- package/dist/ddl.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/migrate.mjs +11 -0
- package/dist/migrate.mjs.map +1 -1
- package/dist/neon-http.mjs +1 -1
- package/dist/neon.mjs +1 -1
- package/dist/pg.mjs +1 -1
- package/dist/pglite.mjs +1 -1
- package/dist/schema/project.d.mts +18 -0
- package/dist/schema/project.mjs +1 -0
- package/dist/schema/project.mjs.map +1 -1
- package/dist/schema/snapshot.d.mts +18 -0
- package/dist/schema/snapshot.mjs +1 -0
- package/dist/schema/snapshot.mjs.map +1 -1
- package/dist/vercel.mjs +1 -1
- package/package.json +2 -2
package/dist/ddl.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import __tsdown_shims_path from 'node:path';
|
|
2
2
|
import __tsdown_shims_url from 'node:url';
|
|
3
3
|
/** Canonical Postgres DDL for all StoryShelf tables and indexes. */
|
|
4
|
-
declare const DDL = "\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n slug TEXT NOT NULL UNIQUE,\n git_repository TEXT,\n git_default_branch TEXT NOT NULL DEFAULT 'main',\n pixel_threshold DOUBLE PRECISION NOT NULL DEFAULT 0.1,\n max_diff_ratio DOUBLE PRECISION NOT NULL DEFAULT 0.01,\n public_branch_regex TEXT,\n storybook_meta TEXT,\n execute_play BOOLEAN NOT NULL DEFAULT false,\n play_timeout_ms INTEGER NOT NULL DEFAULT 10000,\n run_a11y BOOLEAN NOT NULL DEFAULT true,\n run_tests BOOLEAN NOT NULL DEFAULT false,\n browser TEXT NOT NULL DEFAULT 'chromium',\n viewports TEXT,\n browsers TEXT,\n modes_allowlist TEXT,\n automigrate BOOLEAN NOT NULL DEFAULT false,\n ai_profile TEXT,\n review_enabled BOOLEAN NOT NULL DEFAULT true,\n review_approvals INTEGER NOT NULL DEFAULT 1,\n storybook_url_ttl_seconds INTEGER,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS builds (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n git_sha TEXT NOT NULL,\n git_branch TEXT NOT NULL,\n is_default BOOLEAN NOT NULL DEFAULT false,\n author_email TEXT,\n author_name TEXT,\n message TEXT,\n public BOOLEAN NOT NULL DEFAULT false,\n status TEXT NOT NULL DEFAULT 'pending',\n snapshot_count INTEGER NOT NULL DEFAULT 0,\n changed_count INTEGER NOT NULL DEFAULT 0,\n approved_count INTEGER NOT NULL DEFAULT 0,\n rejected_count INTEGER NOT NULL DEFAULT 0,\n inherited_count INTEGER NOT NULL DEFAULT 0,\n affected_only BOOLEAN NOT NULL DEFAULT true,\n baseline_sha TEXT,\n changed_files TEXT,\n affected_import_paths TEXT,\n test_results TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS builds_project_gitsha_idx ON builds (project_id, git_sha);\nCREATE INDEX IF NOT EXISTS builds_git_branch_idx ON builds (git_branch);\nCREATE TABLE IF NOT EXISTS capture_attempts (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n attempt_no INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued',\n error TEXT,\n req_id TEXT,\n story_count INTEGER NOT NULL DEFAULT 0,\n failed_count INTEGER NOT NULL DEFAULT 0,\n queued_at TIMESTAMPTZ NOT NULL,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS capture_attempts_build_no_idx ON capture_attempts (build_id, attempt_no);\nCREATE INDEX IF NOT EXISTS capture_attempts_build_id_idx ON capture_attempts (build_id);\nCREATE TABLE IF NOT EXISTS capture_shards (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n kind TEXT NOT NULL,\n ordinal INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n attempt_id TEXT,\n payload TEXT,\n result TEXT,\n error TEXT,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS capture_shards_build_kind_ordinal_idx ON capture_shards (build_id, kind, ordinal);\nCREATE INDEX IF NOT EXISTS capture_shards_build_id_idx ON capture_shards (build_id);\nCREATE TABLE IF NOT EXISTS capture_jobs (\n id TEXT PRIMARY KEY,\n entry TEXT NOT NULL,\n job_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n build_id TEXT,\n shard_id TEXT,\n attempt INTEGER NOT NULL DEFAULT 0,\n max_attempts INTEGER NOT NULL DEFAULT 3,\n status TEXT NOT NULL,\n visible_at TIMESTAMPTZ,\n owner TEXT,\n payload TEXT,\n cancel_requested_at TIMESTAMPTZ,\n error TEXT,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS capture_jobs_poll_idx ON capture_jobs (kind, visible_at, status);\nCREATE INDEX IF NOT EXISTS capture_jobs_job_id_idx ON capture_jobs (job_id);\nCREATE INDEX IF NOT EXISTS capture_jobs_build_id_idx ON capture_jobs (build_id);\nCREATE INDEX IF NOT EXISTS capture_jobs_entry_created_idx ON capture_jobs (entry, created_at);\nCREATE TABLE IF NOT EXISTS site_settings (\n id TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_by TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS build_components (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n import_path TEXT NOT NULL,\n title TEXT NOT NULL,\n story_count INTEGER NOT NULL DEFAULT 0,\n hash TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_components_build_id_idx ON build_components (build_id);\nCREATE INDEX IF NOT EXISTS build_components_project_import_path_idx ON build_components (project_id, import_path);\nCREATE TABLE IF NOT EXISTS capture_logs (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n attempt_id TEXT NOT NULL REFERENCES capture_attempts(id) ON DELETE CASCADE,\n seq INTEGER NOT NULL,\n level TEXT NOT NULL DEFAULT 'info',\n message TEXT NOT NULL,\n fields TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS capture_logs_attempt_seq_idx ON capture_logs (attempt_id, seq);\nCREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n story_name TEXT NOT NULL,\n story_title TEXT NOT NULL,\n story_import_path TEXT,\n design_url TEXT,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n viewport_width INTEGER NOT NULL DEFAULT 1280,\n viewport_height INTEGER NOT NULL DEFAULT 720,\n screenshot_path TEXT NOT NULL,\n diff_path TEXT,\n diff_pixels INTEGER,\n diff_ratio DOUBLE PRECISION,\n diff_passed BOOLEAN,\n status TEXT NOT NULL DEFAULT 'pending',\n reviewed_by TEXT,\n reviewed_at TIMESTAMPTZ,\n infra_hash TEXT,\n env_change TEXT,\n inherited BOOLEAN NOT NULL DEFAULT false,\n baseline_id TEXT,\n baseline_version TEXT,\n source_build_id TEXT,\n comparison_image_path TEXT,\n comparison_metadata TEXT,\n mode TEXT,\n browser TEXT NOT NULL DEFAULT 'chromium',\n duration_ms INTEGER,\n a11y_violations TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS snapshots_build_id_idx ON snapshots (build_id);\nCREATE INDEX IF NOT EXISTS snapshots_project_import_path_idx ON snapshots (project_id, story_import_path);\nCREATE TABLE IF NOT EXISTS baselines (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n branch TEXT NOT NULL,\n snapshot_id TEXT,\n source_build_id TEXT,\n screenshot_path TEXT NOT NULL,\n infra_hash TEXT,\n fingerprint TEXT,\n mode TEXT,\n browser TEXT NOT NULL DEFAULT 'chromium',\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS baselines_project_story_idx ON baselines (project_id, story_id);\nCREATE TABLE IF NOT EXISTS users (\n id TEXT PRIMARY KEY,\n email TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n avatar_url TEXT,\n role TEXT NOT NULL DEFAULT 'member',\n last_login_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n password_hash TEXT,\n display_name_override TEXT,\n auth_provider TEXT NOT NULL DEFAULT 'oidc',\n disabled BOOLEAN NOT NULL DEFAULT false\n);\nCREATE TABLE IF NOT EXISTS user_connections (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n service TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n refresh_token_encrypted TEXT,\n expires_at TIMESTAMPTZ,\n status TEXT NOT NULL DEFAULT 'ok',\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS user_connections_user_service_idx ON user_connections (user_id, service);\nCREATE TABLE IF NOT EXISTS comments (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n snapshot_id TEXT REFERENCES snapshots(id) ON DELETE CASCADE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n body TEXT NOT NULL,\n parent_id TEXT,\n resolved BOOLEAN NOT NULL DEFAULT false,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL,\n story_id TEXT\n);\nCREATE INDEX IF NOT EXISTS comments_build_id_idx ON comments (build_id);\nCREATE TABLE IF NOT EXISTS build_reviews (\n id TEXT PRIMARY KEY,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n verdict TEXT NOT NULL,\n body TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_reviews_build_id_idx ON build_reviews (build_id);\nCREATE TABLE IF NOT EXISTS label_types (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n key TEXT NOT NULL,\n name TEXT NOT NULL,\n link_template TEXT,\n color TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS label_types_project_key_idx ON label_types (project_id, key);\nCREATE TABLE IF NOT EXISTS build_labels (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n type_key TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS build_labels_build_type_value_idx ON build_labels (build_id, type_key, value);\nCREATE TABLE IF NOT EXISTS project_links (\n id TEXT PRIMARY KEY,\n downstream_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n upstream_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n package_name TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_links_downstream_package_idx ON project_links (downstream_id, package_name);\nCREATE TABLE IF NOT EXISTS design_links (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n import_path TEXT,\n label TEXT,\n url TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS design_links_project_id_idx ON design_links (project_id);\nCREATE TABLE IF NOT EXISTS design_credentials (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'unknown',\n checked_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS design_credentials_project_provider_idx ON design_credentials (project_id, provider);\nCREATE TABLE IF NOT EXISTS design_nodes (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n viewer_id TEXT NOT NULL DEFAULT '',\n file_key TEXT NOT NULL,\n node_id TEXT NOT NULL DEFAULT '',\n name TEXT,\n version TEXT,\n last_modified TEXT,\n state TEXT NOT NULL DEFAULT 'ok',\n render_path TEXT,\n render_version TEXT,\n notified_version TEXT,\n fetched_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS design_nodes_project_file_node_idx ON design_nodes (project_id, provider, viewer_id, file_key, node_id);\nCREATE TABLE IF NOT EXISTS build_package_usage (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_import_path TEXT NOT NULL,\n package_name TEXT NOT NULL,\n module_path TEXT NOT NULL,\n version TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_package_usage_build_id_idx ON build_package_usage (build_id);\nCREATE TABLE IF NOT EXISTS tokens (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n hash TEXT NOT NULL UNIQUE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n last_used_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS webhooks (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n url TEXT NOT NULL,\n secret_encrypted TEXT NOT NULL,\n events TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS notification_channels (\n id TEXT PRIMARY KEY,\n project_id TEXT REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n config TEXT NOT NULL,\n secret_encrypted TEXT,\n events TEXT,\n enabled BOOLEAN NOT NULL DEFAULT TRUE,\n last_error TEXT,\n last_error_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS notification_channels_project_id_idx ON notification_channels (project_id);\nCREATE TABLE IF NOT EXISTS notification_subscriptions (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n events TEXT,\n via TEXT,\n enabled BOOLEAN NOT NULL DEFAULT TRUE,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS notification_subscriptions_project_user_idx ON notification_subscriptions (project_id, user_id);\nCREATE TABLE IF NOT EXISTS insights (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT REFERENCES builds(id) ON DELETE CASCADE,\n kind TEXT NOT NULL,\n window_key TEXT,\n input_hash TEXT NOT NULL,\n status TEXT NOT NULL,\n profile TEXT NOT NULL,\n model TEXT NOT NULL,\n prompt_version TEXT NOT NULL,\n verdict TEXT,\n summary TEXT,\n result TEXT,\n error_code TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ\n);\nCREATE INDEX IF NOT EXISTS insights_project_build_idx ON insights (project_id, build_id);\nCREATE INDEX IF NOT EXISTS insights_created_at_idx ON insights (created_at);\nCREATE UNIQUE INDEX IF NOT EXISTS insights_triage_unique_idx ON insights (project_id, build_id, kind, input_hash);\nCREATE UNIQUE INDEX IF NOT EXISTS insights_health_unique_idx ON insights (project_id, kind, window_key);\nCREATE TABLE IF NOT EXISTS ai_usage (\n id TEXT PRIMARY KEY,\n insight_id TEXT,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n profile TEXT NOT NULL,\n task TEXT NOT NULL,\n model TEXT NOT NULL,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n estimated BOOLEAN NOT NULL DEFAULT false,\n images INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS ai_usage_created_at_idx ON ai_usage (created_at);\nCREATE INDEX IF NOT EXISTS ai_usage_project_created_idx ON ai_usage (project_id, created_at);\nCREATE TABLE IF NOT EXISTS ai_budget_alerts (\n id TEXT PRIMARY KEY,\n day TEXT NOT NULL,\n threshold INTEGER NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS user_invite_tokens (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n token_hash TEXT NOT NULL UNIQUE,\n expires_at TIMESTAMPTZ NOT NULL,\n used_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_members (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n role TEXT NOT NULL DEFAULT 'viewer',\n source TEXT NOT NULL DEFAULT 'manual',\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_members_project_user_idx ON project_members (project_id, user_id);\nCREATE TABLE IF NOT EXISTS project_group_mappings (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n group_name TEXT NOT NULL,\n role TEXT NOT NULL DEFAULT 'viewer',\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_group_mappings_project_group_idx ON project_group_mappings (project_id, group_name);\nCREATE TABLE IF NOT EXISTS content_refs (\n hash TEXT PRIMARY KEY,\n ref_count INTEGER NOT NULL DEFAULT 1,\n last_seen_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS \"user\" (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT NOT NULL UNIQUE,\n email_verified BOOLEAN NOT NULL DEFAULT false,\n image TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS session (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n token TEXT NOT NULL UNIQUE,\n expires_at TIMESTAMPTZ NOT NULL,\n ip_address TEXT,\n user_agent TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS session_token_idx ON session (token);\nCREATE INDEX IF NOT EXISTS session_user_id_idx ON session (user_id);\nCREATE TABLE IF NOT EXISTS account (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n account_id TEXT NOT NULL,\n provider_id TEXT NOT NULL,\n access_token TEXT,\n refresh_token TEXT,\n id_token TEXT,\n access_token_expires_at TIMESTAMPTZ,\n refresh_token_expires_at TIMESTAMPTZ,\n scope TEXT,\n expires_at TIMESTAMPTZ,\n password TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS account_user_id_idx ON account (user_id);\nCREATE TABLE IF NOT EXISTS verification (\n id TEXT PRIMARY KEY,\n identifier TEXT NOT NULL,\n value TEXT NOT NULL,\n expires_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS verification_identifier_idx ON verification (identifier);\nCREATE TABLE IF NOT EXISTS passkey (\n id TEXT PRIMARY KEY,\n name TEXT,\n public_key TEXT NOT NULL,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n credential_id TEXT NOT NULL,\n counter INTEGER NOT NULL,\n device_type TEXT NOT NULL,\n backed_up BOOLEAN NOT NULL DEFAULT false,\n transports TEXT,\n aaguid TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ\n);\nCREATE INDEX IF NOT EXISTS passkey_user_id_idx ON passkey (user_id);\nCREATE INDEX IF NOT EXISTS passkey_credential_id_idx ON passkey (credential_id);\nCREATE TABLE IF NOT EXISTS \"ssoProvider\" (\n id TEXT PRIMARY KEY,\n issuer TEXT NOT NULL,\n oidc_config TEXT,\n saml_config TEXT,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n provider_id TEXT NOT NULL UNIQUE,\n organization_id TEXT,\n domain TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS ssoprovider_domain_idx ON \"ssoProvider\" (domain);\n";
|
|
4
|
+
declare const DDL = "\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n slug TEXT NOT NULL UNIQUE,\n git_repository TEXT,\n git_default_branch TEXT NOT NULL DEFAULT 'main',\n pixel_threshold DOUBLE PRECISION NOT NULL DEFAULT 0.1,\n max_diff_ratio DOUBLE PRECISION NOT NULL DEFAULT 0.01,\n public_branch_regex TEXT,\n storybook_meta TEXT,\n execute_play BOOLEAN NOT NULL DEFAULT false,\n play_timeout_ms INTEGER NOT NULL DEFAULT 10000,\n run_a11y BOOLEAN NOT NULL DEFAULT true,\n run_tests BOOLEAN NOT NULL DEFAULT false,\n detect_unstable BOOLEAN NOT NULL DEFAULT true,\n browser TEXT NOT NULL DEFAULT 'chromium',\n viewports TEXT,\n browsers TEXT,\n modes_allowlist TEXT,\n automigrate BOOLEAN NOT NULL DEFAULT false,\n ai_profile TEXT,\n review_enabled BOOLEAN NOT NULL DEFAULT true,\n review_approvals INTEGER NOT NULL DEFAULT 1,\n storybook_url_ttl_seconds INTEGER,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS builds (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n git_sha TEXT NOT NULL,\n git_branch TEXT NOT NULL,\n is_default BOOLEAN NOT NULL DEFAULT false,\n author_email TEXT,\n author_name TEXT,\n message TEXT,\n public BOOLEAN NOT NULL DEFAULT false,\n status TEXT NOT NULL DEFAULT 'pending',\n snapshot_count INTEGER NOT NULL DEFAULT 0,\n changed_count INTEGER NOT NULL DEFAULT 0,\n approved_count INTEGER NOT NULL DEFAULT 0,\n rejected_count INTEGER NOT NULL DEFAULT 0,\n inherited_count INTEGER NOT NULL DEFAULT 0,\n affected_only BOOLEAN NOT NULL DEFAULT true,\n baseline_sha TEXT,\n changed_files TEXT,\n affected_import_paths TEXT,\n test_results TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS builds_project_gitsha_idx ON builds (project_id, git_sha);\nCREATE INDEX IF NOT EXISTS builds_git_branch_idx ON builds (git_branch);\nCREATE TABLE IF NOT EXISTS capture_attempts (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n attempt_no INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued',\n error TEXT,\n req_id TEXT,\n story_count INTEGER NOT NULL DEFAULT 0,\n failed_count INTEGER NOT NULL DEFAULT 0,\n queued_at TIMESTAMPTZ NOT NULL,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS capture_attempts_build_no_idx ON capture_attempts (build_id, attempt_no);\nCREATE INDEX IF NOT EXISTS capture_attempts_build_id_idx ON capture_attempts (build_id);\nCREATE TABLE IF NOT EXISTS capture_shards (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n kind TEXT NOT NULL,\n ordinal INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n attempt_id TEXT,\n payload TEXT,\n result TEXT,\n error TEXT,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS capture_shards_build_kind_ordinal_idx ON capture_shards (build_id, kind, ordinal);\nCREATE INDEX IF NOT EXISTS capture_shards_build_id_idx ON capture_shards (build_id);\nCREATE TABLE IF NOT EXISTS capture_jobs (\n id TEXT PRIMARY KEY,\n entry TEXT NOT NULL,\n job_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n build_id TEXT,\n shard_id TEXT,\n attempt INTEGER NOT NULL DEFAULT 0,\n max_attempts INTEGER NOT NULL DEFAULT 3,\n status TEXT NOT NULL,\n visible_at TIMESTAMPTZ,\n owner TEXT,\n payload TEXT,\n cancel_requested_at TIMESTAMPTZ,\n error TEXT,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS capture_jobs_poll_idx ON capture_jobs (kind, visible_at, status);\nCREATE INDEX IF NOT EXISTS capture_jobs_job_id_idx ON capture_jobs (job_id);\nCREATE INDEX IF NOT EXISTS capture_jobs_build_id_idx ON capture_jobs (build_id);\nCREATE INDEX IF NOT EXISTS capture_jobs_entry_created_idx ON capture_jobs (entry, created_at);\nCREATE TABLE IF NOT EXISTS site_settings (\n id TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_by TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS build_components (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n import_path TEXT NOT NULL,\n title TEXT NOT NULL,\n story_count INTEGER NOT NULL DEFAULT 0,\n hash TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_components_build_id_idx ON build_components (build_id);\nCREATE INDEX IF NOT EXISTS build_components_project_import_path_idx ON build_components (project_id, import_path);\nCREATE TABLE IF NOT EXISTS capture_logs (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n attempt_id TEXT NOT NULL REFERENCES capture_attempts(id) ON DELETE CASCADE,\n seq INTEGER NOT NULL,\n level TEXT NOT NULL DEFAULT 'info',\n message TEXT NOT NULL,\n fields TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS capture_logs_attempt_seq_idx ON capture_logs (attempt_id, seq);\nCREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n story_name TEXT NOT NULL,\n story_title TEXT NOT NULL,\n story_import_path TEXT,\n design_url TEXT,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n viewport_width INTEGER NOT NULL DEFAULT 1280,\n viewport_height INTEGER NOT NULL DEFAULT 720,\n screenshot_path TEXT NOT NULL,\n diff_path TEXT,\n diff_pixels INTEGER,\n diff_ratio DOUBLE PRECISION,\n diff_passed BOOLEAN,\n status TEXT NOT NULL DEFAULT 'pending',\n reviewed_by TEXT,\n reviewed_at TIMESTAMPTZ,\n infra_hash TEXT,\n env_change TEXT,\n inherited BOOLEAN NOT NULL DEFAULT false,\n baseline_id TEXT,\n baseline_version TEXT,\n source_build_id TEXT,\n comparison_image_path TEXT,\n comparison_metadata TEXT,\n mode TEXT,\n browser TEXT NOT NULL DEFAULT 'chromium',\n duration_ms INTEGER,\n a11y_violations TEXT,\n unstable BOOLEAN,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS snapshots_build_id_idx ON snapshots (build_id);\nCREATE INDEX IF NOT EXISTS snapshots_project_import_path_idx ON snapshots (project_id, story_import_path);\nCREATE TABLE IF NOT EXISTS baselines (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n branch TEXT NOT NULL,\n snapshot_id TEXT,\n source_build_id TEXT,\n screenshot_path TEXT NOT NULL,\n infra_hash TEXT,\n fingerprint TEXT,\n mode TEXT,\n browser TEXT NOT NULL DEFAULT 'chromium',\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS baselines_project_story_idx ON baselines (project_id, story_id);\nCREATE TABLE IF NOT EXISTS users (\n id TEXT PRIMARY KEY,\n email TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n avatar_url TEXT,\n role TEXT NOT NULL DEFAULT 'member',\n last_login_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n password_hash TEXT,\n display_name_override TEXT,\n auth_provider TEXT NOT NULL DEFAULT 'oidc',\n disabled BOOLEAN NOT NULL DEFAULT false\n);\nCREATE TABLE IF NOT EXISTS user_connections (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n service TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n refresh_token_encrypted TEXT,\n expires_at TIMESTAMPTZ,\n status TEXT NOT NULL DEFAULT 'ok',\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS user_connections_user_service_idx ON user_connections (user_id, service);\nCREATE TABLE IF NOT EXISTS comments (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n snapshot_id TEXT REFERENCES snapshots(id) ON DELETE CASCADE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n body TEXT NOT NULL,\n parent_id TEXT,\n resolved BOOLEAN NOT NULL DEFAULT false,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL,\n story_id TEXT\n);\nCREATE INDEX IF NOT EXISTS comments_build_id_idx ON comments (build_id);\nCREATE TABLE IF NOT EXISTS build_reviews (\n id TEXT PRIMARY KEY,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n verdict TEXT NOT NULL,\n body TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_reviews_build_id_idx ON build_reviews (build_id);\nCREATE TABLE IF NOT EXISTS label_types (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n key TEXT NOT NULL,\n name TEXT NOT NULL,\n link_template TEXT,\n color TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS label_types_project_key_idx ON label_types (project_id, key);\nCREATE TABLE IF NOT EXISTS build_labels (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n type_key TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS build_labels_build_type_value_idx ON build_labels (build_id, type_key, value);\nCREATE TABLE IF NOT EXISTS project_links (\n id TEXT PRIMARY KEY,\n downstream_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n upstream_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n package_name TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_links_downstream_package_idx ON project_links (downstream_id, package_name);\nCREATE TABLE IF NOT EXISTS design_links (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n import_path TEXT,\n label TEXT,\n url TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS design_links_project_id_idx ON design_links (project_id);\nCREATE TABLE IF NOT EXISTS design_credentials (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'unknown',\n checked_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS design_credentials_project_provider_idx ON design_credentials (project_id, provider);\nCREATE TABLE IF NOT EXISTS design_nodes (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n viewer_id TEXT NOT NULL DEFAULT '',\n file_key TEXT NOT NULL,\n node_id TEXT NOT NULL DEFAULT '',\n name TEXT,\n version TEXT,\n last_modified TEXT,\n state TEXT NOT NULL DEFAULT 'ok',\n render_path TEXT,\n render_version TEXT,\n notified_version TEXT,\n fetched_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS design_nodes_project_file_node_idx ON design_nodes (project_id, provider, viewer_id, file_key, node_id);\nCREATE TABLE IF NOT EXISTS build_package_usage (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_import_path TEXT NOT NULL,\n package_name TEXT NOT NULL,\n module_path TEXT NOT NULL,\n version TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_package_usage_build_id_idx ON build_package_usage (build_id);\nCREATE TABLE IF NOT EXISTS tokens (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n hash TEXT NOT NULL UNIQUE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n last_used_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS webhooks (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n url TEXT NOT NULL,\n secret_encrypted TEXT NOT NULL,\n events TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS notification_channels (\n id TEXT PRIMARY KEY,\n project_id TEXT REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n config TEXT NOT NULL,\n secret_encrypted TEXT,\n events TEXT,\n enabled BOOLEAN NOT NULL DEFAULT TRUE,\n last_error TEXT,\n last_error_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS notification_channels_project_id_idx ON notification_channels (project_id);\nCREATE TABLE IF NOT EXISTS notification_subscriptions (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n events TEXT,\n via TEXT,\n enabled BOOLEAN NOT NULL DEFAULT TRUE,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS notification_subscriptions_project_user_idx ON notification_subscriptions (project_id, user_id);\nCREATE TABLE IF NOT EXISTS insights (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT REFERENCES builds(id) ON DELETE CASCADE,\n kind TEXT NOT NULL,\n window_key TEXT,\n input_hash TEXT NOT NULL,\n status TEXT NOT NULL,\n profile TEXT NOT NULL,\n model TEXT NOT NULL,\n prompt_version TEXT NOT NULL,\n verdict TEXT,\n summary TEXT,\n result TEXT,\n error_code TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ\n);\nCREATE INDEX IF NOT EXISTS insights_project_build_idx ON insights (project_id, build_id);\nCREATE INDEX IF NOT EXISTS insights_created_at_idx ON insights (created_at);\nCREATE UNIQUE INDEX IF NOT EXISTS insights_triage_unique_idx ON insights (project_id, build_id, kind, input_hash);\nCREATE UNIQUE INDEX IF NOT EXISTS insights_health_unique_idx ON insights (project_id, kind, window_key);\nCREATE TABLE IF NOT EXISTS ai_usage (\n id TEXT PRIMARY KEY,\n insight_id TEXT,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n profile TEXT NOT NULL,\n task TEXT NOT NULL,\n model TEXT NOT NULL,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n estimated BOOLEAN NOT NULL DEFAULT false,\n images INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS ai_usage_created_at_idx ON ai_usage (created_at);\nCREATE INDEX IF NOT EXISTS ai_usage_project_created_idx ON ai_usage (project_id, created_at);\nCREATE TABLE IF NOT EXISTS ai_budget_alerts (\n id TEXT PRIMARY KEY,\n day TEXT NOT NULL,\n threshold INTEGER NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS user_invite_tokens (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n token_hash TEXT NOT NULL UNIQUE,\n expires_at TIMESTAMPTZ NOT NULL,\n used_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_members (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n role TEXT NOT NULL DEFAULT 'viewer',\n source TEXT NOT NULL DEFAULT 'manual',\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_members_project_user_idx ON project_members (project_id, user_id);\nCREATE TABLE IF NOT EXISTS project_group_mappings (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n group_name TEXT NOT NULL,\n role TEXT NOT NULL DEFAULT 'viewer',\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_group_mappings_project_group_idx ON project_group_mappings (project_id, group_name);\nCREATE TABLE IF NOT EXISTS content_refs (\n hash TEXT PRIMARY KEY,\n ref_count INTEGER NOT NULL DEFAULT 1,\n last_seen_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS \"user\" (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT NOT NULL UNIQUE,\n email_verified BOOLEAN NOT NULL DEFAULT false,\n image TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS session (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n token TEXT NOT NULL UNIQUE,\n expires_at TIMESTAMPTZ NOT NULL,\n ip_address TEXT,\n user_agent TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS session_token_idx ON session (token);\nCREATE INDEX IF NOT EXISTS session_user_id_idx ON session (user_id);\nCREATE TABLE IF NOT EXISTS account (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n account_id TEXT NOT NULL,\n provider_id TEXT NOT NULL,\n access_token TEXT,\n refresh_token TEXT,\n id_token TEXT,\n access_token_expires_at TIMESTAMPTZ,\n refresh_token_expires_at TIMESTAMPTZ,\n scope TEXT,\n expires_at TIMESTAMPTZ,\n password TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS account_user_id_idx ON account (user_id);\nCREATE TABLE IF NOT EXISTS verification (\n id TEXT PRIMARY KEY,\n identifier TEXT NOT NULL,\n value TEXT NOT NULL,\n expires_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS verification_identifier_idx ON verification (identifier);\nCREATE TABLE IF NOT EXISTS passkey (\n id TEXT PRIMARY KEY,\n name TEXT,\n public_key TEXT NOT NULL,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n credential_id TEXT NOT NULL,\n counter INTEGER NOT NULL,\n device_type TEXT NOT NULL,\n backed_up BOOLEAN NOT NULL DEFAULT false,\n transports TEXT,\n aaguid TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ\n);\nCREATE INDEX IF NOT EXISTS passkey_user_id_idx ON passkey (user_id);\nCREATE INDEX IF NOT EXISTS passkey_credential_id_idx ON passkey (credential_id);\nCREATE TABLE IF NOT EXISTS \"ssoProvider\" (\n id TEXT PRIMARY KEY,\n issuer TEXT NOT NULL,\n oidc_config TEXT,\n saml_config TEXT,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n provider_id TEXT NOT NULL UNIQUE,\n organization_id TEXT,\n domain TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS ssoprovider_domain_idx ON \"ssoProvider\" (domain);\n";
|
|
5
5
|
export { DDL };
|
|
6
6
|
//# sourceMappingURL=ddl.d.mts.map
|
package/dist/ddl.mjs
CHANGED
|
@@ -18,6 +18,7 @@ CREATE TABLE IF NOT EXISTS projects (
|
|
|
18
18
|
play_timeout_ms INTEGER NOT NULL DEFAULT 10000,
|
|
19
19
|
run_a11y BOOLEAN NOT NULL DEFAULT true,
|
|
20
20
|
run_tests BOOLEAN NOT NULL DEFAULT false,
|
|
21
|
+
detect_unstable BOOLEAN NOT NULL DEFAULT true,
|
|
21
22
|
browser TEXT NOT NULL DEFAULT 'chromium',
|
|
22
23
|
viewports TEXT,
|
|
23
24
|
browsers TEXT,
|
|
@@ -179,6 +180,7 @@ CREATE TABLE IF NOT EXISTS snapshots (
|
|
|
179
180
|
browser TEXT NOT NULL DEFAULT 'chromium',
|
|
180
181
|
duration_ms INTEGER,
|
|
181
182
|
a11y_violations TEXT,
|
|
183
|
+
unstable BOOLEAN,
|
|
182
184
|
created_at TIMESTAMPTZ NOT NULL,
|
|
183
185
|
updated_at TIMESTAMPTZ NOT NULL
|
|
184
186
|
);
|
package/dist/ddl.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ddl.mjs","names":[],"sources":["../src/ddl.ts"],"sourcesContent":["/** Canonical Postgres DDL for all StoryShelf tables and indexes. */\nexport const DDL = `\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n slug TEXT NOT NULL UNIQUE,\n git_repository TEXT,\n git_default_branch TEXT NOT NULL DEFAULT 'main',\n pixel_threshold DOUBLE PRECISION NOT NULL DEFAULT 0.1,\n max_diff_ratio DOUBLE PRECISION NOT NULL DEFAULT 0.01,\n public_branch_regex TEXT,\n storybook_meta TEXT,\n execute_play BOOLEAN NOT NULL DEFAULT false,\n play_timeout_ms INTEGER NOT NULL DEFAULT 10000,\n run_a11y BOOLEAN NOT NULL DEFAULT true,\n run_tests BOOLEAN NOT NULL DEFAULT false,\n browser TEXT NOT NULL DEFAULT 'chromium',\n viewports TEXT,\n browsers TEXT,\n modes_allowlist TEXT,\n automigrate BOOLEAN NOT NULL DEFAULT false,\n ai_profile TEXT,\n review_enabled BOOLEAN NOT NULL DEFAULT true,\n review_approvals INTEGER NOT NULL DEFAULT 1,\n storybook_url_ttl_seconds INTEGER,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS builds (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n git_sha TEXT NOT NULL,\n git_branch TEXT NOT NULL,\n is_default BOOLEAN NOT NULL DEFAULT false,\n author_email TEXT,\n author_name TEXT,\n message TEXT,\n public BOOLEAN NOT NULL DEFAULT false,\n status TEXT NOT NULL DEFAULT 'pending',\n snapshot_count INTEGER NOT NULL DEFAULT 0,\n changed_count INTEGER NOT NULL DEFAULT 0,\n approved_count INTEGER NOT NULL DEFAULT 0,\n rejected_count INTEGER NOT NULL DEFAULT 0,\n inherited_count INTEGER NOT NULL DEFAULT 0,\n affected_only BOOLEAN NOT NULL DEFAULT true,\n baseline_sha TEXT,\n changed_files TEXT,\n affected_import_paths TEXT,\n test_results TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS builds_project_gitsha_idx ON builds (project_id, git_sha);\nCREATE INDEX IF NOT EXISTS builds_git_branch_idx ON builds (git_branch);\nCREATE TABLE IF NOT EXISTS capture_attempts (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n attempt_no INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued',\n error TEXT,\n req_id TEXT,\n story_count INTEGER NOT NULL DEFAULT 0,\n failed_count INTEGER NOT NULL DEFAULT 0,\n queued_at TIMESTAMPTZ NOT NULL,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS capture_attempts_build_no_idx ON capture_attempts (build_id, attempt_no);\nCREATE INDEX IF NOT EXISTS capture_attempts_build_id_idx ON capture_attempts (build_id);\nCREATE TABLE IF NOT EXISTS capture_shards (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n kind TEXT NOT NULL,\n ordinal INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n attempt_id TEXT,\n payload TEXT,\n result TEXT,\n error TEXT,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS capture_shards_build_kind_ordinal_idx ON capture_shards (build_id, kind, ordinal);\nCREATE INDEX IF NOT EXISTS capture_shards_build_id_idx ON capture_shards (build_id);\nCREATE TABLE IF NOT EXISTS capture_jobs (\n id TEXT PRIMARY KEY,\n entry TEXT NOT NULL,\n job_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n build_id TEXT,\n shard_id TEXT,\n attempt INTEGER NOT NULL DEFAULT 0,\n max_attempts INTEGER NOT NULL DEFAULT 3,\n status TEXT NOT NULL,\n visible_at TIMESTAMPTZ,\n owner TEXT,\n payload TEXT,\n cancel_requested_at TIMESTAMPTZ,\n error TEXT,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS capture_jobs_poll_idx ON capture_jobs (kind, visible_at, status);\nCREATE INDEX IF NOT EXISTS capture_jobs_job_id_idx ON capture_jobs (job_id);\nCREATE INDEX IF NOT EXISTS capture_jobs_build_id_idx ON capture_jobs (build_id);\nCREATE INDEX IF NOT EXISTS capture_jobs_entry_created_idx ON capture_jobs (entry, created_at);\nCREATE TABLE IF NOT EXISTS site_settings (\n id TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_by TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS build_components (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n import_path TEXT NOT NULL,\n title TEXT NOT NULL,\n story_count INTEGER NOT NULL DEFAULT 0,\n hash TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_components_build_id_idx ON build_components (build_id);\nCREATE INDEX IF NOT EXISTS build_components_project_import_path_idx ON build_components (project_id, import_path);\nCREATE TABLE IF NOT EXISTS capture_logs (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n attempt_id TEXT NOT NULL REFERENCES capture_attempts(id) ON DELETE CASCADE,\n seq INTEGER NOT NULL,\n level TEXT NOT NULL DEFAULT 'info',\n message TEXT NOT NULL,\n fields TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS capture_logs_attempt_seq_idx ON capture_logs (attempt_id, seq);\nCREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n story_name TEXT NOT NULL,\n story_title TEXT NOT NULL,\n story_import_path TEXT,\n design_url TEXT,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n viewport_width INTEGER NOT NULL DEFAULT 1280,\n viewport_height INTEGER NOT NULL DEFAULT 720,\n screenshot_path TEXT NOT NULL,\n diff_path TEXT,\n diff_pixels INTEGER,\n diff_ratio DOUBLE PRECISION,\n diff_passed BOOLEAN,\n status TEXT NOT NULL DEFAULT 'pending',\n reviewed_by TEXT,\n reviewed_at TIMESTAMPTZ,\n infra_hash TEXT,\n env_change TEXT,\n inherited BOOLEAN NOT NULL DEFAULT false,\n baseline_id TEXT,\n baseline_version TEXT,\n source_build_id TEXT,\n comparison_image_path TEXT,\n comparison_metadata TEXT,\n mode TEXT,\n browser TEXT NOT NULL DEFAULT 'chromium',\n duration_ms INTEGER,\n a11y_violations TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS snapshots_build_id_idx ON snapshots (build_id);\nCREATE INDEX IF NOT EXISTS snapshots_project_import_path_idx ON snapshots (project_id, story_import_path);\nCREATE TABLE IF NOT EXISTS baselines (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n branch TEXT NOT NULL,\n snapshot_id TEXT,\n source_build_id TEXT,\n screenshot_path TEXT NOT NULL,\n infra_hash TEXT,\n fingerprint TEXT,\n mode TEXT,\n browser TEXT NOT NULL DEFAULT 'chromium',\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS baselines_project_story_idx ON baselines (project_id, story_id);\nCREATE TABLE IF NOT EXISTS users (\n id TEXT PRIMARY KEY,\n email TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n avatar_url TEXT,\n role TEXT NOT NULL DEFAULT 'member',\n last_login_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n password_hash TEXT,\n display_name_override TEXT,\n auth_provider TEXT NOT NULL DEFAULT 'oidc',\n disabled BOOLEAN NOT NULL DEFAULT false\n);\nCREATE TABLE IF NOT EXISTS user_connections (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n service TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n refresh_token_encrypted TEXT,\n expires_at TIMESTAMPTZ,\n status TEXT NOT NULL DEFAULT 'ok',\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS user_connections_user_service_idx ON user_connections (user_id, service);\nCREATE TABLE IF NOT EXISTS comments (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n snapshot_id TEXT REFERENCES snapshots(id) ON DELETE CASCADE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n body TEXT NOT NULL,\n parent_id TEXT,\n resolved BOOLEAN NOT NULL DEFAULT false,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL,\n story_id TEXT\n);\nCREATE INDEX IF NOT EXISTS comments_build_id_idx ON comments (build_id);\nCREATE TABLE IF NOT EXISTS build_reviews (\n id TEXT PRIMARY KEY,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n verdict TEXT NOT NULL,\n body TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_reviews_build_id_idx ON build_reviews (build_id);\nCREATE TABLE IF NOT EXISTS label_types (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n key TEXT NOT NULL,\n name TEXT NOT NULL,\n link_template TEXT,\n color TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS label_types_project_key_idx ON label_types (project_id, key);\nCREATE TABLE IF NOT EXISTS build_labels (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n type_key TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS build_labels_build_type_value_idx ON build_labels (build_id, type_key, value);\nCREATE TABLE IF NOT EXISTS project_links (\n id TEXT PRIMARY KEY,\n downstream_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n upstream_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n package_name TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_links_downstream_package_idx ON project_links (downstream_id, package_name);\nCREATE TABLE IF NOT EXISTS design_links (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n import_path TEXT,\n label TEXT,\n url TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS design_links_project_id_idx ON design_links (project_id);\nCREATE TABLE IF NOT EXISTS design_credentials (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'unknown',\n checked_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS design_credentials_project_provider_idx ON design_credentials (project_id, provider);\nCREATE TABLE IF NOT EXISTS design_nodes (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n viewer_id TEXT NOT NULL DEFAULT '',\n file_key TEXT NOT NULL,\n node_id TEXT NOT NULL DEFAULT '',\n name TEXT,\n version TEXT,\n last_modified TEXT,\n state TEXT NOT NULL DEFAULT 'ok',\n render_path TEXT,\n render_version TEXT,\n notified_version TEXT,\n fetched_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS design_nodes_project_file_node_idx ON design_nodes (project_id, provider, viewer_id, file_key, node_id);\nCREATE TABLE IF NOT EXISTS build_package_usage (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_import_path TEXT NOT NULL,\n package_name TEXT NOT NULL,\n module_path TEXT NOT NULL,\n version TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_package_usage_build_id_idx ON build_package_usage (build_id);\nCREATE TABLE IF NOT EXISTS tokens (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n hash TEXT NOT NULL UNIQUE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n last_used_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS webhooks (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n url TEXT NOT NULL,\n secret_encrypted TEXT NOT NULL,\n events TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS notification_channels (\n id TEXT PRIMARY KEY,\n project_id TEXT REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n config TEXT NOT NULL,\n secret_encrypted TEXT,\n events TEXT,\n enabled BOOLEAN NOT NULL DEFAULT TRUE,\n last_error TEXT,\n last_error_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS notification_channels_project_id_idx ON notification_channels (project_id);\nCREATE TABLE IF NOT EXISTS notification_subscriptions (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n events TEXT,\n via TEXT,\n enabled BOOLEAN NOT NULL DEFAULT TRUE,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS notification_subscriptions_project_user_idx ON notification_subscriptions (project_id, user_id);\nCREATE TABLE IF NOT EXISTS insights (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT REFERENCES builds(id) ON DELETE CASCADE,\n kind TEXT NOT NULL,\n window_key TEXT,\n input_hash TEXT NOT NULL,\n status TEXT NOT NULL,\n profile TEXT NOT NULL,\n model TEXT NOT NULL,\n prompt_version TEXT NOT NULL,\n verdict TEXT,\n summary TEXT,\n result TEXT,\n error_code TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ\n);\nCREATE INDEX IF NOT EXISTS insights_project_build_idx ON insights (project_id, build_id);\nCREATE INDEX IF NOT EXISTS insights_created_at_idx ON insights (created_at);\nCREATE UNIQUE INDEX IF NOT EXISTS insights_triage_unique_idx ON insights (project_id, build_id, kind, input_hash);\nCREATE UNIQUE INDEX IF NOT EXISTS insights_health_unique_idx ON insights (project_id, kind, window_key);\nCREATE TABLE IF NOT EXISTS ai_usage (\n id TEXT PRIMARY KEY,\n insight_id TEXT,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n profile TEXT NOT NULL,\n task TEXT NOT NULL,\n model TEXT NOT NULL,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n estimated BOOLEAN NOT NULL DEFAULT false,\n images INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS ai_usage_created_at_idx ON ai_usage (created_at);\nCREATE INDEX IF NOT EXISTS ai_usage_project_created_idx ON ai_usage (project_id, created_at);\nCREATE TABLE IF NOT EXISTS ai_budget_alerts (\n id TEXT PRIMARY KEY,\n day TEXT NOT NULL,\n threshold INTEGER NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS user_invite_tokens (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n token_hash TEXT NOT NULL UNIQUE,\n expires_at TIMESTAMPTZ NOT NULL,\n used_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_members (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n role TEXT NOT NULL DEFAULT 'viewer',\n source TEXT NOT NULL DEFAULT 'manual',\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_members_project_user_idx ON project_members (project_id, user_id);\nCREATE TABLE IF NOT EXISTS project_group_mappings (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n group_name TEXT NOT NULL,\n role TEXT NOT NULL DEFAULT 'viewer',\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_group_mappings_project_group_idx ON project_group_mappings (project_id, group_name);\nCREATE TABLE IF NOT EXISTS content_refs (\n hash TEXT PRIMARY KEY,\n ref_count INTEGER NOT NULL DEFAULT 1,\n last_seen_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS \"user\" (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT NOT NULL UNIQUE,\n email_verified BOOLEAN NOT NULL DEFAULT false,\n image TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS session (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n token TEXT NOT NULL UNIQUE,\n expires_at TIMESTAMPTZ NOT NULL,\n ip_address TEXT,\n user_agent TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS session_token_idx ON session (token);\nCREATE INDEX IF NOT EXISTS session_user_id_idx ON session (user_id);\nCREATE TABLE IF NOT EXISTS account (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n account_id TEXT NOT NULL,\n provider_id TEXT NOT NULL,\n access_token TEXT,\n refresh_token TEXT,\n id_token TEXT,\n access_token_expires_at TIMESTAMPTZ,\n refresh_token_expires_at TIMESTAMPTZ,\n scope TEXT,\n expires_at TIMESTAMPTZ,\n password TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS account_user_id_idx ON account (user_id);\nCREATE TABLE IF NOT EXISTS verification (\n id TEXT PRIMARY KEY,\n identifier TEXT NOT NULL,\n value TEXT NOT NULL,\n expires_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS verification_identifier_idx ON verification (identifier);\nCREATE TABLE IF NOT EXISTS passkey (\n id TEXT PRIMARY KEY,\n name TEXT,\n public_key TEXT NOT NULL,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n credential_id TEXT NOT NULL,\n counter INTEGER NOT NULL,\n device_type TEXT NOT NULL,\n backed_up BOOLEAN NOT NULL DEFAULT false,\n transports TEXT,\n aaguid TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ\n);\nCREATE INDEX IF NOT EXISTS passkey_user_id_idx ON passkey (user_id);\nCREATE INDEX IF NOT EXISTS passkey_credential_id_idx ON passkey (credential_id);\nCREATE TABLE IF NOT EXISTS \"ssoProvider\" (\n id TEXT PRIMARY KEY,\n issuer TEXT NOT NULL,\n oidc_config TEXT,\n saml_config TEXT,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n provider_id TEXT NOT NULL UNIQUE,\n organization_id TEXT,\n domain TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS ssoprovider_domain_idx ON \"ssoProvider\" (domain);\n`;\n"],"mappings":";;;;;AACA,MAAa,MAAM"}
|
|
1
|
+
{"version":3,"file":"ddl.mjs","names":[],"sources":["../src/ddl.ts"],"sourcesContent":["/** Canonical Postgres DDL for all StoryShelf tables and indexes. */\nexport const DDL = `\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n slug TEXT NOT NULL UNIQUE,\n git_repository TEXT,\n git_default_branch TEXT NOT NULL DEFAULT 'main',\n pixel_threshold DOUBLE PRECISION NOT NULL DEFAULT 0.1,\n max_diff_ratio DOUBLE PRECISION NOT NULL DEFAULT 0.01,\n public_branch_regex TEXT,\n storybook_meta TEXT,\n execute_play BOOLEAN NOT NULL DEFAULT false,\n play_timeout_ms INTEGER NOT NULL DEFAULT 10000,\n run_a11y BOOLEAN NOT NULL DEFAULT true,\n run_tests BOOLEAN NOT NULL DEFAULT false,\n detect_unstable BOOLEAN NOT NULL DEFAULT true,\n browser TEXT NOT NULL DEFAULT 'chromium',\n viewports TEXT,\n browsers TEXT,\n modes_allowlist TEXT,\n automigrate BOOLEAN NOT NULL DEFAULT false,\n ai_profile TEXT,\n review_enabled BOOLEAN NOT NULL DEFAULT true,\n review_approvals INTEGER NOT NULL DEFAULT 1,\n storybook_url_ttl_seconds INTEGER,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS builds (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n git_sha TEXT NOT NULL,\n git_branch TEXT NOT NULL,\n is_default BOOLEAN NOT NULL DEFAULT false,\n author_email TEXT,\n author_name TEXT,\n message TEXT,\n public BOOLEAN NOT NULL DEFAULT false,\n status TEXT NOT NULL DEFAULT 'pending',\n snapshot_count INTEGER NOT NULL DEFAULT 0,\n changed_count INTEGER NOT NULL DEFAULT 0,\n approved_count INTEGER NOT NULL DEFAULT 0,\n rejected_count INTEGER NOT NULL DEFAULT 0,\n inherited_count INTEGER NOT NULL DEFAULT 0,\n affected_only BOOLEAN NOT NULL DEFAULT true,\n baseline_sha TEXT,\n changed_files TEXT,\n affected_import_paths TEXT,\n test_results TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS builds_project_gitsha_idx ON builds (project_id, git_sha);\nCREATE INDEX IF NOT EXISTS builds_git_branch_idx ON builds (git_branch);\nCREATE TABLE IF NOT EXISTS capture_attempts (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n attempt_no INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued',\n error TEXT,\n req_id TEXT,\n story_count INTEGER NOT NULL DEFAULT 0,\n failed_count INTEGER NOT NULL DEFAULT 0,\n queued_at TIMESTAMPTZ NOT NULL,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS capture_attempts_build_no_idx ON capture_attempts (build_id, attempt_no);\nCREATE INDEX IF NOT EXISTS capture_attempts_build_id_idx ON capture_attempts (build_id);\nCREATE TABLE IF NOT EXISTS capture_shards (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n kind TEXT NOT NULL,\n ordinal INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n attempt_id TEXT,\n payload TEXT,\n result TEXT,\n error TEXT,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS capture_shards_build_kind_ordinal_idx ON capture_shards (build_id, kind, ordinal);\nCREATE INDEX IF NOT EXISTS capture_shards_build_id_idx ON capture_shards (build_id);\nCREATE TABLE IF NOT EXISTS capture_jobs (\n id TEXT PRIMARY KEY,\n entry TEXT NOT NULL,\n job_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n build_id TEXT,\n shard_id TEXT,\n attempt INTEGER NOT NULL DEFAULT 0,\n max_attempts INTEGER NOT NULL DEFAULT 3,\n status TEXT NOT NULL,\n visible_at TIMESTAMPTZ,\n owner TEXT,\n payload TEXT,\n cancel_requested_at TIMESTAMPTZ,\n error TEXT,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS capture_jobs_poll_idx ON capture_jobs (kind, visible_at, status);\nCREATE INDEX IF NOT EXISTS capture_jobs_job_id_idx ON capture_jobs (job_id);\nCREATE INDEX IF NOT EXISTS capture_jobs_build_id_idx ON capture_jobs (build_id);\nCREATE INDEX IF NOT EXISTS capture_jobs_entry_created_idx ON capture_jobs (entry, created_at);\nCREATE TABLE IF NOT EXISTS site_settings (\n id TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_by TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS build_components (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n import_path TEXT NOT NULL,\n title TEXT NOT NULL,\n story_count INTEGER NOT NULL DEFAULT 0,\n hash TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_components_build_id_idx ON build_components (build_id);\nCREATE INDEX IF NOT EXISTS build_components_project_import_path_idx ON build_components (project_id, import_path);\nCREATE TABLE IF NOT EXISTS capture_logs (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n attempt_id TEXT NOT NULL REFERENCES capture_attempts(id) ON DELETE CASCADE,\n seq INTEGER NOT NULL,\n level TEXT NOT NULL DEFAULT 'info',\n message TEXT NOT NULL,\n fields TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS capture_logs_attempt_seq_idx ON capture_logs (attempt_id, seq);\nCREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n story_name TEXT NOT NULL,\n story_title TEXT NOT NULL,\n story_import_path TEXT,\n design_url TEXT,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n viewport_width INTEGER NOT NULL DEFAULT 1280,\n viewport_height INTEGER NOT NULL DEFAULT 720,\n screenshot_path TEXT NOT NULL,\n diff_path TEXT,\n diff_pixels INTEGER,\n diff_ratio DOUBLE PRECISION,\n diff_passed BOOLEAN,\n status TEXT NOT NULL DEFAULT 'pending',\n reviewed_by TEXT,\n reviewed_at TIMESTAMPTZ,\n infra_hash TEXT,\n env_change TEXT,\n inherited BOOLEAN NOT NULL DEFAULT false,\n baseline_id TEXT,\n baseline_version TEXT,\n source_build_id TEXT,\n comparison_image_path TEXT,\n comparison_metadata TEXT,\n mode TEXT,\n browser TEXT NOT NULL DEFAULT 'chromium',\n duration_ms INTEGER,\n a11y_violations TEXT,\n unstable BOOLEAN,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS snapshots_build_id_idx ON snapshots (build_id);\nCREATE INDEX IF NOT EXISTS snapshots_project_import_path_idx ON snapshots (project_id, story_import_path);\nCREATE TABLE IF NOT EXISTS baselines (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n branch TEXT NOT NULL,\n snapshot_id TEXT,\n source_build_id TEXT,\n screenshot_path TEXT NOT NULL,\n infra_hash TEXT,\n fingerprint TEXT,\n mode TEXT,\n browser TEXT NOT NULL DEFAULT 'chromium',\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS baselines_project_story_idx ON baselines (project_id, story_id);\nCREATE TABLE IF NOT EXISTS users (\n id TEXT PRIMARY KEY,\n email TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n avatar_url TEXT,\n role TEXT NOT NULL DEFAULT 'member',\n last_login_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n password_hash TEXT,\n display_name_override TEXT,\n auth_provider TEXT NOT NULL DEFAULT 'oidc',\n disabled BOOLEAN NOT NULL DEFAULT false\n);\nCREATE TABLE IF NOT EXISTS user_connections (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n service TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n refresh_token_encrypted TEXT,\n expires_at TIMESTAMPTZ,\n status TEXT NOT NULL DEFAULT 'ok',\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS user_connections_user_service_idx ON user_connections (user_id, service);\nCREATE TABLE IF NOT EXISTS comments (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n snapshot_id TEXT REFERENCES snapshots(id) ON DELETE CASCADE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n body TEXT NOT NULL,\n parent_id TEXT,\n resolved BOOLEAN NOT NULL DEFAULT false,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL,\n story_id TEXT\n);\nCREATE INDEX IF NOT EXISTS comments_build_id_idx ON comments (build_id);\nCREATE TABLE IF NOT EXISTS build_reviews (\n id TEXT PRIMARY KEY,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n verdict TEXT NOT NULL,\n body TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_reviews_build_id_idx ON build_reviews (build_id);\nCREATE TABLE IF NOT EXISTS label_types (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n key TEXT NOT NULL,\n name TEXT NOT NULL,\n link_template TEXT,\n color TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS label_types_project_key_idx ON label_types (project_id, key);\nCREATE TABLE IF NOT EXISTS build_labels (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n type_key TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS build_labels_build_type_value_idx ON build_labels (build_id, type_key, value);\nCREATE TABLE IF NOT EXISTS project_links (\n id TEXT PRIMARY KEY,\n downstream_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n upstream_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n package_name TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_links_downstream_package_idx ON project_links (downstream_id, package_name);\nCREATE TABLE IF NOT EXISTS design_links (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n import_path TEXT,\n label TEXT,\n url TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS design_links_project_id_idx ON design_links (project_id);\nCREATE TABLE IF NOT EXISTS design_credentials (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'unknown',\n checked_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS design_credentials_project_provider_idx ON design_credentials (project_id, provider);\nCREATE TABLE IF NOT EXISTS design_nodes (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n viewer_id TEXT NOT NULL DEFAULT '',\n file_key TEXT NOT NULL,\n node_id TEXT NOT NULL DEFAULT '',\n name TEXT,\n version TEXT,\n last_modified TEXT,\n state TEXT NOT NULL DEFAULT 'ok',\n render_path TEXT,\n render_version TEXT,\n notified_version TEXT,\n fetched_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS design_nodes_project_file_node_idx ON design_nodes (project_id, provider, viewer_id, file_key, node_id);\nCREATE TABLE IF NOT EXISTS build_package_usage (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_import_path TEXT NOT NULL,\n package_name TEXT NOT NULL,\n module_path TEXT NOT NULL,\n version TEXT,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS build_package_usage_build_id_idx ON build_package_usage (build_id);\nCREATE TABLE IF NOT EXISTS tokens (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n hash TEXT NOT NULL UNIQUE,\n user_id TEXT REFERENCES users(id) ON DELETE CASCADE,\n last_used_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS webhooks (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n url TEXT NOT NULL,\n secret_encrypted TEXT NOT NULL,\n events TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS notification_channels (\n id TEXT PRIMARY KEY,\n project_id TEXT REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n config TEXT NOT NULL,\n secret_encrypted TEXT,\n events TEXT,\n enabled BOOLEAN NOT NULL DEFAULT TRUE,\n last_error TEXT,\n last_error_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS notification_channels_project_id_idx ON notification_channels (project_id);\nCREATE TABLE IF NOT EXISTS notification_subscriptions (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n events TEXT,\n via TEXT,\n enabled BOOLEAN NOT NULL DEFAULT TRUE,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS notification_subscriptions_project_user_idx ON notification_subscriptions (project_id, user_id);\nCREATE TABLE IF NOT EXISTS insights (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT REFERENCES builds(id) ON DELETE CASCADE,\n kind TEXT NOT NULL,\n window_key TEXT,\n input_hash TEXT NOT NULL,\n status TEXT NOT NULL,\n profile TEXT NOT NULL,\n model TEXT NOT NULL,\n prompt_version TEXT NOT NULL,\n verdict TEXT,\n summary TEXT,\n result TEXT,\n error_code TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n started_at TIMESTAMPTZ,\n finished_at TIMESTAMPTZ\n);\nCREATE INDEX IF NOT EXISTS insights_project_build_idx ON insights (project_id, build_id);\nCREATE INDEX IF NOT EXISTS insights_created_at_idx ON insights (created_at);\nCREATE UNIQUE INDEX IF NOT EXISTS insights_triage_unique_idx ON insights (project_id, build_id, kind, input_hash);\nCREATE UNIQUE INDEX IF NOT EXISTS insights_health_unique_idx ON insights (project_id, kind, window_key);\nCREATE TABLE IF NOT EXISTS ai_usage (\n id TEXT PRIMARY KEY,\n insight_id TEXT,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n profile TEXT NOT NULL,\n task TEXT NOT NULL,\n model TEXT NOT NULL,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n estimated BOOLEAN NOT NULL DEFAULT false,\n images INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS ai_usage_created_at_idx ON ai_usage (created_at);\nCREATE INDEX IF NOT EXISTS ai_usage_project_created_idx ON ai_usage (project_id, created_at);\nCREATE TABLE IF NOT EXISTS ai_budget_alerts (\n id TEXT PRIMARY KEY,\n day TEXT NOT NULL,\n threshold INTEGER NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS user_invite_tokens (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n token_hash TEXT NOT NULL UNIQUE,\n expires_at TIMESTAMPTZ NOT NULL,\n used_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_members (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n role TEXT NOT NULL DEFAULT 'viewer',\n source TEXT NOT NULL DEFAULT 'manual',\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_members_project_user_idx ON project_members (project_id, user_id);\nCREATE TABLE IF NOT EXISTS project_group_mappings (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n group_name TEXT NOT NULL,\n role TEXT NOT NULL DEFAULT 'viewer',\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_group_mappings_project_group_idx ON project_group_mappings (project_id, group_name);\nCREATE TABLE IF NOT EXISTS content_refs (\n hash TEXT PRIMARY KEY,\n ref_count INTEGER NOT NULL DEFAULT 1,\n last_seen_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS \"user\" (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT NOT NULL UNIQUE,\n email_verified BOOLEAN NOT NULL DEFAULT false,\n image TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE TABLE IF NOT EXISTS session (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n token TEXT NOT NULL UNIQUE,\n expires_at TIMESTAMPTZ NOT NULL,\n ip_address TEXT,\n user_agent TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS session_token_idx ON session (token);\nCREATE INDEX IF NOT EXISTS session_user_id_idx ON session (user_id);\nCREATE TABLE IF NOT EXISTS account (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n account_id TEXT NOT NULL,\n provider_id TEXT NOT NULL,\n access_token TEXT,\n refresh_token TEXT,\n id_token TEXT,\n access_token_expires_at TIMESTAMPTZ,\n refresh_token_expires_at TIMESTAMPTZ,\n scope TEXT,\n expires_at TIMESTAMPTZ,\n password TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS account_user_id_idx ON account (user_id);\nCREATE TABLE IF NOT EXISTS verification (\n id TEXT PRIMARY KEY,\n identifier TEXT NOT NULL,\n value TEXT NOT NULL,\n expires_at TIMESTAMPTZ NOT NULL,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL\n);\nCREATE INDEX IF NOT EXISTS verification_identifier_idx ON verification (identifier);\nCREATE TABLE IF NOT EXISTS passkey (\n id TEXT PRIMARY KEY,\n name TEXT,\n public_key TEXT NOT NULL,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n credential_id TEXT NOT NULL,\n counter INTEGER NOT NULL,\n device_type TEXT NOT NULL,\n backed_up BOOLEAN NOT NULL DEFAULT false,\n transports TEXT,\n aaguid TEXT,\n created_at TIMESTAMPTZ NOT NULL,\n updated_at TIMESTAMPTZ\n);\nCREATE INDEX IF NOT EXISTS passkey_user_id_idx ON passkey (user_id);\nCREATE INDEX IF NOT EXISTS passkey_credential_id_idx ON passkey (credential_id);\nCREATE TABLE IF NOT EXISTS \"ssoProvider\" (\n id TEXT PRIMARY KEY,\n issuer TEXT NOT NULL,\n oidc_config TEXT,\n saml_config TEXT,\n user_id TEXT NOT NULL REFERENCES \"user\"(id) ON DELETE CASCADE,\n provider_id TEXT NOT NULL UNIQUE,\n organization_id TEXT,\n domain TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS ssoprovider_domain_idx ON \"ssoProvider\" (domain);\n`;\n"],"mappings":";;;;;AACA,MAAa,MAAM"}
|
package/dist/index.mjs
CHANGED
|
@@ -28,7 +28,7 @@ function createPostgresDatabase(options) {
|
|
|
28
28
|
return createDrizzlePgAdapter(db, {
|
|
29
29
|
metadata: {
|
|
30
30
|
name: "Postgres",
|
|
31
|
-
version: "0.9.0-next-
|
|
31
|
+
version: "0.9.0-next-3604136",
|
|
32
32
|
description: "Postgres database adapter (postgres.js + Drizzle)",
|
|
33
33
|
kind: "postgres",
|
|
34
34
|
category: "database"
|
package/dist/migrate.mjs
CHANGED
|
@@ -46,6 +46,8 @@ const BUILD_CHANGED_FILES_ALTER = "ALTER TABLE builds ADD COLUMN IF NOT EXISTS c
|
|
|
46
46
|
const BUILD_AFFECTED_PATHS_ALTER = "ALTER TABLE builds ADD COLUMN IF NOT EXISTS affected_import_paths TEXT";
|
|
47
47
|
const BUILD_INHERITED_COUNT_ALTER = "ALTER TABLE builds ADD COLUMN IF NOT EXISTS inherited_count INTEGER NOT NULL DEFAULT 0";
|
|
48
48
|
const BUILD_TEST_RESULTS_ALTER = "ALTER TABLE builds ADD COLUMN IF NOT EXISTS test_results TEXT";
|
|
49
|
+
const SNAPSHOT_UNSTABLE_ALTER = "ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS unstable BOOLEAN";
|
|
50
|
+
const DETECT_UNSTABLE_ALTER = "ALTER TABLE projects ADD COLUMN IF NOT EXISTS detect_unstable BOOLEAN NOT NULL DEFAULT true";
|
|
49
51
|
const RUN_TESTS_ALTER = "ALTER TABLE projects ADD COLUMN IF NOT EXISTS run_tests BOOLEAN NOT NULL DEFAULT false";
|
|
50
52
|
const WEBHOOK_SECRET_ALTER = "ALTER TABLE webhooks ADD COLUMN IF NOT EXISTS secret_encrypted TEXT NOT NULL DEFAULT ''";
|
|
51
53
|
const WEBHOOK_SECRET_DROP = "ALTER TABLE webhooks DROP COLUMN IF EXISTS secret";
|
|
@@ -128,7 +130,16 @@ async function migrateProjectExtras(run) {
|
|
|
128
130
|
await migrateBaselineColumns(run);
|
|
129
131
|
await migrateBuildColumns(run);
|
|
130
132
|
await execIgnore(run, RUN_TESTS_ALTER);
|
|
133
|
+
await migrateRecentColumns(run);
|
|
134
|
+
}
|
|
135
|
+
/** Columns added after the first adapter release; each is an idempotent `ADD COLUMN IF NOT EXISTS`. */
|
|
136
|
+
async function migrateRecentColumns(run) {
|
|
131
137
|
await migrateDesignColumns(run);
|
|
138
|
+
await migrateUnstableColumns(run);
|
|
139
|
+
}
|
|
140
|
+
async function migrateUnstableColumns(run) {
|
|
141
|
+
await execIgnore(run, SNAPSHOT_UNSTABLE_ALTER);
|
|
142
|
+
await execIgnore(run, DETECT_UNSTABLE_ALTER);
|
|
132
143
|
}
|
|
133
144
|
async function migrateDesignColumns(run) {
|
|
134
145
|
await execIgnore(run, DESIGN_NODE_NOTIFIED_ALTER);
|
package/dist/migrate.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.mjs","names":[],"sources":["../src/migrate.ts"],"sourcesContent":["/**\n * Shared Postgres migrations for every `db-postgres` preset.\n *\n * The DDL plus idempotent follow-up ALTERs run through a minimal row-query\n * runner so all drivers (`postgres.js`, `node-postgres`, Neon, …) share one\n * migration path instead of drifting per preset.\n */\nimport { DDL } from \"./ddl.ts\";\n\n/** Minimal row-query surface a migration runner needs. */\nexport type MigrationRunner = (sql: string) => Promise<unknown[]>;\n\nconst STORYBOOK_META_ALTER = \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS storybook_meta TEXT\";\nconst EXECUTE_PLAY_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS execute_play BOOLEAN NOT NULL DEFAULT false\";\nconst PLAY_TIMEOUT_MS_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS play_timeout_ms INTEGER NOT NULL DEFAULT 10000\";\nconst RUN_A11Y_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS run_a11y BOOLEAN NOT NULL DEFAULT true\";\nconst RUN_A11Y_DEFAULT_ALTER = \"ALTER TABLE projects ALTER COLUMN run_a11y SET DEFAULT true\";\nconst PROJECT_BROWSER_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS browser TEXT NOT NULL DEFAULT 'chromium'\";\nconst PROJECT_VIEWPORTS_ALTER = \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS viewports TEXT\";\nconst PROJECT_AUTOMIGRATE_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS automigrate BOOLEAN NOT NULL DEFAULT false\";\nconst PROJECT_AI_PROFILE_ALTER = \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS ai_profile TEXT\";\nconst PROJECT_REVIEW_ENABLED_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS review_enabled BOOLEAN NOT NULL DEFAULT true\";\nconst PROJECT_REVIEW_APPROVALS_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS review_approvals INTEGER NOT NULL DEFAULT 1\";\nconst PROJECT_STORYBOOK_URL_TTL_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS storybook_url_ttl_seconds INTEGER\";\nconst SNAPSHOT_INFRA_HASH_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS infra_hash TEXT\";\nconst SNAPSHOT_INHERITED_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS inherited BOOLEAN NOT NULL DEFAULT false\";\nconst SNAPSHOT_BASELINE_ID_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS baseline_id TEXT\";\nconst SNAPSHOT_BASELINE_VERSION_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS baseline_version TEXT\";\nconst SNAPSHOT_COMPARISON_IMAGE_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS comparison_image_path TEXT\";\nconst SNAPSHOT_COMPARISON_METADATA_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS comparison_metadata TEXT\";\nconst SNAPSHOT_SOURCE_BUILD_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS source_build_id TEXT\";\nconst BASELINE_SOURCE_BUILD_ALTER =\n \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS source_build_id TEXT\";\nconst SNAPSHOT_ENV_CHANGE_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS env_change TEXT\";\nconst SNAPSHOT_DESIGN_URL_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS design_url TEXT\";\nconst SNAPSHOT_DURATION_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS duration_ms INTEGER\";\nconst SNAPSHOT_A11Y_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS a11y_violations TEXT\";\nconst DESIGN_NODE_NOTIFIED_ALTER =\n \"ALTER TABLE design_nodes ADD COLUMN IF NOT EXISTS notified_version TEXT\";\nconst DESIGN_LINKS_UNIQUE_INDEX =\n \"CREATE UNIQUE INDEX IF NOT EXISTS design_links_project_import_path_idx ON design_links (project_id, import_path)\";\n/** Pre-adapter Figma tables (replaced by design_nodes / design_credentials; no data is carried over). */\nconst LEGACY_DESIGN_DROPS = [\n \"DROP TABLE IF EXISTS figma_nodes\",\n \"DROP TABLE IF EXISTS design_tokens\",\n];\nconst BASELINE_FINGERPRINT_ALTER =\n \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS fingerprint TEXT\";\nconst BASELINE_INFRA_HASH_ALTER = \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS infra_hash TEXT\";\nconst BUILD_AFFECTED_ONLY_ALTER =\n \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS affected_only BOOLEAN NOT NULL DEFAULT true\";\nconst BUILD_BASELINE_SHA_ALTER = \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS baseline_sha TEXT\";\nconst BUILD_CHANGED_FILES_ALTER = \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS changed_files TEXT\";\nconst BUILD_AFFECTED_PATHS_ALTER =\n \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS affected_import_paths TEXT\";\nconst BUILD_INHERITED_COUNT_ALTER =\n \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS inherited_count INTEGER NOT NULL DEFAULT 0\";\nconst BUILD_TEST_RESULTS_ALTER = \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS test_results TEXT\";\nconst RUN_TESTS_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS run_tests BOOLEAN NOT NULL DEFAULT false\";\nconst WEBHOOK_SECRET_ALTER =\n \"ALTER TABLE webhooks ADD COLUMN IF NOT EXISTS secret_encrypted TEXT NOT NULL DEFAULT ''\";\nconst WEBHOOK_SECRET_DROP = \"ALTER TABLE webhooks DROP COLUMN IF EXISTS secret\";\nconst TOKEN_USER_ALTER =\n \"ALTER TABLE tokens ADD COLUMN IF NOT EXISTS user_id TEXT REFERENCES users(id) ON DELETE CASCADE\";\nconst MEMBER_SOURCE_ALTER =\n \"ALTER TABLE project_members ADD COLUMN IF NOT EXISTS source TEXT NOT NULL DEFAULT 'manual'\";\n/**\n * Auth columns the SQLite `users` table always had. Without them the Drizzle model cannot store\n * `disabled` (an admin disabling a user fails) or the auth provider and display-name override.\n */\nconst USER_AUTH_ALTERS = [\n \"ALTER TABLE users ADD COLUMN IF NOT EXISTS password_hash TEXT\",\n \"ALTER TABLE users ADD COLUMN IF NOT EXISTS display_name_override TEXT\",\n \"ALTER TABLE users ADD COLUMN IF NOT EXISTS auth_provider TEXT NOT NULL DEFAULT 'oidc'\",\n \"ALTER TABLE users ADD COLUMN IF NOT EXISTS disabled BOOLEAN NOT NULL DEFAULT false\",\n];\nconst COMMENT_STORY_ID_ALTER = \"ALTER TABLE comments ADD COLUMN IF NOT EXISTS story_id TEXT\";\nconst NOTIFICATION_LAST_ERROR_ALTER =\n \"ALTER TABLE notification_channels ADD COLUMN IF NOT EXISTS last_error TEXT\";\nconst NOTIFICATION_LAST_ERROR_AT_ALTER =\n \"ALTER TABLE notification_channels ADD COLUMN IF NOT EXISTS last_error_at TIMESTAMPTZ\";\n/**\n * Re-runs share `(project_id, git_sha)` by design (ULID build ids), so the\n * lookup index must not be unique. Existing databases created it UNIQUE —\n * drop and recreate it plain.\n */\nconst BUILDS_GITSHA_DEDUP = \"DROP INDEX IF EXISTS builds_project_gitsha_idx\";\nconst BUILDS_GITSHA_INDEX =\n \"CREATE INDEX IF NOT EXISTS builds_project_gitsha_idx ON builds (project_id, git_sha)\";\n\nconst PROJECT_BROWSERS_ALTER = \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS browsers TEXT\";\nconst PROJECT_MODES_ALLOWLIST_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS modes_allowlist TEXT\";\nconst SNAPSHOT_MODE_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS mode TEXT\";\nconst SNAPSHOT_BROWSER_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS browser TEXT NOT NULL DEFAULT 'chromium'\";\nconst BASELINE_MODE_ALTER = \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS mode TEXT\";\nconst BASELINE_BROWSER_ALTER =\n \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS browser TEXT NOT NULL DEFAULT 'chromium'\";\n/** Swap the viewport-only unique indexes for the browser-aware ones (rows default to chromium). */\nconst IDENTITY_STATEMENTS = [\n \"DROP INDEX IF EXISTS snapshots_build_story_viewport_idx\",\n \"DROP INDEX IF EXISTS baselines_project_story_viewport_branch_idx\",\n \"CREATE UNIQUE INDEX IF NOT EXISTS snapshots_build_story_mode_browser_idx ON snapshots (build_id, story_id, viewport_name, browser)\",\n \"CREATE UNIQUE INDEX IF NOT EXISTS baselines_project_story_mode_browser_branch_idx ON baselines (project_id, story_id, viewport_name, browser, branch)\",\n];\n\nasync function migrateSnapshotColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, SNAPSHOT_INFRA_HASH_ALTER);\n await execIgnore(run, SNAPSHOT_INHERITED_ALTER);\n await execIgnore(run, SNAPSHOT_BASELINE_ID_ALTER);\n await execIgnore(run, SNAPSHOT_BASELINE_VERSION_ALTER);\n await migrateComparisonColumns(run);\n await execIgnore(run, SNAPSHOT_DESIGN_URL_ALTER);\n await execIgnore(run, SNAPSHOT_ENV_CHANGE_ALTER);\n await execIgnore(run, SNAPSHOT_DURATION_ALTER);\n await execIgnore(run, SNAPSHOT_A11Y_ALTER);\n await migrateCaptureIdentityColumns(run);\n}\n\nasync function migrateComparisonColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, SNAPSHOT_SOURCE_BUILD_ALTER);\n await execIgnore(run, SNAPSHOT_COMPARISON_IMAGE_ALTER);\n await execIgnore(run, SNAPSHOT_COMPARISON_METADATA_ALTER);\n}\n\nasync function migrateCaptureIdentityColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, SNAPSHOT_MODE_ALTER);\n await execIgnore(run, SNAPSHOT_BROWSER_ALTER);\n await execIgnore(run, BASELINE_MODE_ALTER);\n await execIgnore(run, BASELINE_BROWSER_ALTER);\n await execIgnore(run, PROJECT_BROWSERS_ALTER);\n await execIgnore(run, PROJECT_MODES_ALLOWLIST_ALTER);\n await execIgnore(run, DESIGN_LINKS_UNIQUE_INDEX);\n await Promise.all(\n LEGACY_DESIGN_DROPS.map(async (statement) => {\n await execIgnore(run, statement);\n }),\n );\n}\n\nasync function migrateBaselineColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, BASELINE_INFRA_HASH_ALTER);\n await execIgnore(run, BASELINE_FINGERPRINT_ALTER);\n await execIgnore(run, BASELINE_SOURCE_BUILD_ALTER);\n}\n\nasync function migrateProjectExtras(run: MigrationRunner): Promise<void> {\n await execIgnore(run, EXECUTE_PLAY_ALTER);\n await execIgnore(run, PLAY_TIMEOUT_MS_ALTER);\n await execIgnore(run, PROJECT_AUTOMIGRATE_ALTER);\n await execIgnore(run, PROJECT_AI_PROFILE_ALTER);\n await migrateProjectReviewColumns(run);\n await migrateSnapshotColumns(run);\n await migrateBaselineColumns(run);\n await migrateBuildColumns(run);\n await execIgnore(run, RUN_TESTS_ALTER);\n await migrateDesignColumns(run);\n}\n\nasync function migrateDesignColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, DESIGN_NODE_NOTIFIED_ALTER);\n}\n\nasync function migrateProjectReviewColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, PROJECT_REVIEW_ENABLED_ALTER);\n await execIgnore(run, PROJECT_REVIEW_APPROVALS_ALTER);\n await execIgnore(run, PROJECT_STORYBOOK_URL_TTL_ALTER);\n}\n\nasync function migrateBuildColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, BUILD_AFFECTED_ONLY_ALTER);\n await execIgnore(run, BUILD_BASELINE_SHA_ALTER);\n await execIgnore(run, BUILD_CHANGED_FILES_ALTER);\n await execIgnore(run, BUILD_AFFECTED_PATHS_ALTER);\n await execIgnore(run, BUILD_INHERITED_COUNT_ALTER);\n await execIgnore(run, BUILD_TEST_RESULTS_ALTER);\n}\n\n/** Run the full migration set through any row-query runner. */\nexport async function runMigrations(run: MigrationRunner): Promise<void> {\n await run(DDL);\n await migrateCoreColumns(run);\n await migrateUserAuthColumns(run);\n await migrateProjectExtras(run);\n await applyIdentityStatements(run);\n await migrateCommentsTable(run);\n await migrateNotificationColumns(run);\n}\n\n/**\n * Unlike the other follow-up ALTERs this one is not swallowed: if the columns cannot be added the\n * boot must fail loudly, because a missing `disabled` column means access control silently does\n * not work. `ADD COLUMN IF NOT EXISTS` is already idempotent, so there is no \"already done\" error\n * to ignore.\n */\nasync function migrateUserAuthColumns(run: MigrationRunner): Promise<void> {\n for (const statement of USER_AUTH_ALTERS) {\n // oxlint-disable-next-line no-await-in-loop -- ordered, and a failure must stop the boot\n await run(statement);\n }\n}\n\nasync function migrateRunA11yDefault(run: MigrationRunner): Promise<void> {\n await execIgnore(run, RUN_A11Y_ALTER);\n await execIgnore(run, RUN_A11Y_DEFAULT_ALTER);\n}\n\nasync function migrateCoreColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, STORYBOOK_META_ALTER);\n await migrateRunA11yDefault(run);\n await execIgnore(run, PROJECT_BROWSER_ALTER);\n await execIgnore(run, PROJECT_VIEWPORTS_ALTER);\n await execIgnore(run, WEBHOOK_SECRET_ALTER);\n await execIgnore(run, WEBHOOK_SECRET_DROP);\n await execIgnore(run, TOKEN_USER_ALTER);\n await execIgnore(run, MEMBER_SOURCE_ALTER);\n await execIgnore(run, BUILDS_GITSHA_DEDUP);\n await execIgnore(run, BUILDS_GITSHA_INDEX);\n}\n\nasync function applyIdentityStatements(run: MigrationRunner): Promise<void> {\n for (const statement of IDENTITY_STATEMENTS) {\n // oxlint-disable-next-line no-await-in-loop -- ordered: drop old indexes, then create new\n await execIgnore(run, statement);\n }\n}\n\nasync function execIgnore(run: MigrationRunner, sql: string): Promise<void> {\n try {\n await run(sql);\n } catch {\n // idempotent — already migrated\n }\n}\n\nasync function migrateNotificationColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, NOTIFICATION_LAST_ERROR_ALTER);\n await execIgnore(run, NOTIFICATION_LAST_ERROR_AT_ALTER);\n}\n\nasync function migrateCommentsTable(run: MigrationRunner): Promise<void> {\n await execIgnore(run, COMMENT_STORY_ID_ALTER);\n try {\n const rows = (await run(\n \"SELECT is_nullable FROM information_schema.columns WHERE table_name='comments' AND column_name='user_id'\",\n )) as { is_nullable: string }[];\n const isNullable = rows[0]?.is_nullable;\n if (isNullable === \"YES\" || isNullable === undefined) {\n return;\n }\n await run(\"ALTER TABLE comments ALTER COLUMN user_id DROP NOT NULL\");\n } catch {\n // already nullable or table missing — ignore\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"migrate.mjs","names":[],"sources":["../src/migrate.ts"],"sourcesContent":["/**\n * Shared Postgres migrations for every `db-postgres` preset.\n *\n * The DDL plus idempotent follow-up ALTERs run through a minimal row-query\n * runner so all drivers (`postgres.js`, `node-postgres`, Neon, …) share one\n * migration path instead of drifting per preset.\n */\nimport { DDL } from \"./ddl.ts\";\n\n/** Minimal row-query surface a migration runner needs. */\nexport type MigrationRunner = (sql: string) => Promise<unknown[]>;\n\nconst STORYBOOK_META_ALTER = \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS storybook_meta TEXT\";\nconst EXECUTE_PLAY_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS execute_play BOOLEAN NOT NULL DEFAULT false\";\nconst PLAY_TIMEOUT_MS_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS play_timeout_ms INTEGER NOT NULL DEFAULT 10000\";\nconst RUN_A11Y_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS run_a11y BOOLEAN NOT NULL DEFAULT true\";\nconst RUN_A11Y_DEFAULT_ALTER = \"ALTER TABLE projects ALTER COLUMN run_a11y SET DEFAULT true\";\nconst PROJECT_BROWSER_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS browser TEXT NOT NULL DEFAULT 'chromium'\";\nconst PROJECT_VIEWPORTS_ALTER = \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS viewports TEXT\";\nconst PROJECT_AUTOMIGRATE_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS automigrate BOOLEAN NOT NULL DEFAULT false\";\nconst PROJECT_AI_PROFILE_ALTER = \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS ai_profile TEXT\";\nconst PROJECT_REVIEW_ENABLED_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS review_enabled BOOLEAN NOT NULL DEFAULT true\";\nconst PROJECT_REVIEW_APPROVALS_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS review_approvals INTEGER NOT NULL DEFAULT 1\";\nconst PROJECT_STORYBOOK_URL_TTL_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS storybook_url_ttl_seconds INTEGER\";\nconst SNAPSHOT_INFRA_HASH_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS infra_hash TEXT\";\nconst SNAPSHOT_INHERITED_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS inherited BOOLEAN NOT NULL DEFAULT false\";\nconst SNAPSHOT_BASELINE_ID_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS baseline_id TEXT\";\nconst SNAPSHOT_BASELINE_VERSION_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS baseline_version TEXT\";\nconst SNAPSHOT_COMPARISON_IMAGE_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS comparison_image_path TEXT\";\nconst SNAPSHOT_COMPARISON_METADATA_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS comparison_metadata TEXT\";\nconst SNAPSHOT_SOURCE_BUILD_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS source_build_id TEXT\";\nconst BASELINE_SOURCE_BUILD_ALTER =\n \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS source_build_id TEXT\";\nconst SNAPSHOT_ENV_CHANGE_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS env_change TEXT\";\nconst SNAPSHOT_DESIGN_URL_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS design_url TEXT\";\nconst SNAPSHOT_DURATION_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS duration_ms INTEGER\";\nconst SNAPSHOT_A11Y_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS a11y_violations TEXT\";\nconst DESIGN_NODE_NOTIFIED_ALTER =\n \"ALTER TABLE design_nodes ADD COLUMN IF NOT EXISTS notified_version TEXT\";\nconst DESIGN_LINKS_UNIQUE_INDEX =\n \"CREATE UNIQUE INDEX IF NOT EXISTS design_links_project_import_path_idx ON design_links (project_id, import_path)\";\n/** Pre-adapter Figma tables (replaced by design_nodes / design_credentials; no data is carried over). */\nconst LEGACY_DESIGN_DROPS = [\n \"DROP TABLE IF EXISTS figma_nodes\",\n \"DROP TABLE IF EXISTS design_tokens\",\n];\nconst BASELINE_FINGERPRINT_ALTER =\n \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS fingerprint TEXT\";\nconst BASELINE_INFRA_HASH_ALTER = \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS infra_hash TEXT\";\nconst BUILD_AFFECTED_ONLY_ALTER =\n \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS affected_only BOOLEAN NOT NULL DEFAULT true\";\nconst BUILD_BASELINE_SHA_ALTER = \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS baseline_sha TEXT\";\nconst BUILD_CHANGED_FILES_ALTER = \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS changed_files TEXT\";\nconst BUILD_AFFECTED_PATHS_ALTER =\n \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS affected_import_paths TEXT\";\nconst BUILD_INHERITED_COUNT_ALTER =\n \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS inherited_count INTEGER NOT NULL DEFAULT 0\";\nconst BUILD_TEST_RESULTS_ALTER = \"ALTER TABLE builds ADD COLUMN IF NOT EXISTS test_results TEXT\";\nconst SNAPSHOT_UNSTABLE_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS unstable BOOLEAN\";\nconst DETECT_UNSTABLE_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS detect_unstable BOOLEAN NOT NULL DEFAULT true\";\nconst RUN_TESTS_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS run_tests BOOLEAN NOT NULL DEFAULT false\";\nconst WEBHOOK_SECRET_ALTER =\n \"ALTER TABLE webhooks ADD COLUMN IF NOT EXISTS secret_encrypted TEXT NOT NULL DEFAULT ''\";\nconst WEBHOOK_SECRET_DROP = \"ALTER TABLE webhooks DROP COLUMN IF EXISTS secret\";\nconst TOKEN_USER_ALTER =\n \"ALTER TABLE tokens ADD COLUMN IF NOT EXISTS user_id TEXT REFERENCES users(id) ON DELETE CASCADE\";\nconst MEMBER_SOURCE_ALTER =\n \"ALTER TABLE project_members ADD COLUMN IF NOT EXISTS source TEXT NOT NULL DEFAULT 'manual'\";\n/**\n * Auth columns the SQLite `users` table always had. Without them the Drizzle model cannot store\n * `disabled` (an admin disabling a user fails) or the auth provider and display-name override.\n */\nconst USER_AUTH_ALTERS = [\n \"ALTER TABLE users ADD COLUMN IF NOT EXISTS password_hash TEXT\",\n \"ALTER TABLE users ADD COLUMN IF NOT EXISTS display_name_override TEXT\",\n \"ALTER TABLE users ADD COLUMN IF NOT EXISTS auth_provider TEXT NOT NULL DEFAULT 'oidc'\",\n \"ALTER TABLE users ADD COLUMN IF NOT EXISTS disabled BOOLEAN NOT NULL DEFAULT false\",\n];\nconst COMMENT_STORY_ID_ALTER = \"ALTER TABLE comments ADD COLUMN IF NOT EXISTS story_id TEXT\";\nconst NOTIFICATION_LAST_ERROR_ALTER =\n \"ALTER TABLE notification_channels ADD COLUMN IF NOT EXISTS last_error TEXT\";\nconst NOTIFICATION_LAST_ERROR_AT_ALTER =\n \"ALTER TABLE notification_channels ADD COLUMN IF NOT EXISTS last_error_at TIMESTAMPTZ\";\n/**\n * Re-runs share `(project_id, git_sha)` by design (ULID build ids), so the\n * lookup index must not be unique. Existing databases created it UNIQUE —\n * drop and recreate it plain.\n */\nconst BUILDS_GITSHA_DEDUP = \"DROP INDEX IF EXISTS builds_project_gitsha_idx\";\nconst BUILDS_GITSHA_INDEX =\n \"CREATE INDEX IF NOT EXISTS builds_project_gitsha_idx ON builds (project_id, git_sha)\";\n\nconst PROJECT_BROWSERS_ALTER = \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS browsers TEXT\";\nconst PROJECT_MODES_ALLOWLIST_ALTER =\n \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS modes_allowlist TEXT\";\nconst SNAPSHOT_MODE_ALTER = \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS mode TEXT\";\nconst SNAPSHOT_BROWSER_ALTER =\n \"ALTER TABLE snapshots ADD COLUMN IF NOT EXISTS browser TEXT NOT NULL DEFAULT 'chromium'\";\nconst BASELINE_MODE_ALTER = \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS mode TEXT\";\nconst BASELINE_BROWSER_ALTER =\n \"ALTER TABLE baselines ADD COLUMN IF NOT EXISTS browser TEXT NOT NULL DEFAULT 'chromium'\";\n/** Swap the viewport-only unique indexes for the browser-aware ones (rows default to chromium). */\nconst IDENTITY_STATEMENTS = [\n \"DROP INDEX IF EXISTS snapshots_build_story_viewport_idx\",\n \"DROP INDEX IF EXISTS baselines_project_story_viewport_branch_idx\",\n \"CREATE UNIQUE INDEX IF NOT EXISTS snapshots_build_story_mode_browser_idx ON snapshots (build_id, story_id, viewport_name, browser)\",\n \"CREATE UNIQUE INDEX IF NOT EXISTS baselines_project_story_mode_browser_branch_idx ON baselines (project_id, story_id, viewport_name, browser, branch)\",\n];\n\nasync function migrateSnapshotColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, SNAPSHOT_INFRA_HASH_ALTER);\n await execIgnore(run, SNAPSHOT_INHERITED_ALTER);\n await execIgnore(run, SNAPSHOT_BASELINE_ID_ALTER);\n await execIgnore(run, SNAPSHOT_BASELINE_VERSION_ALTER);\n await migrateComparisonColumns(run);\n await execIgnore(run, SNAPSHOT_DESIGN_URL_ALTER);\n await execIgnore(run, SNAPSHOT_ENV_CHANGE_ALTER);\n await execIgnore(run, SNAPSHOT_DURATION_ALTER);\n await execIgnore(run, SNAPSHOT_A11Y_ALTER);\n await migrateCaptureIdentityColumns(run);\n}\n\nasync function migrateComparisonColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, SNAPSHOT_SOURCE_BUILD_ALTER);\n await execIgnore(run, SNAPSHOT_COMPARISON_IMAGE_ALTER);\n await execIgnore(run, SNAPSHOT_COMPARISON_METADATA_ALTER);\n}\n\nasync function migrateCaptureIdentityColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, SNAPSHOT_MODE_ALTER);\n await execIgnore(run, SNAPSHOT_BROWSER_ALTER);\n await execIgnore(run, BASELINE_MODE_ALTER);\n await execIgnore(run, BASELINE_BROWSER_ALTER);\n await execIgnore(run, PROJECT_BROWSERS_ALTER);\n await execIgnore(run, PROJECT_MODES_ALLOWLIST_ALTER);\n await execIgnore(run, DESIGN_LINKS_UNIQUE_INDEX);\n await Promise.all(\n LEGACY_DESIGN_DROPS.map(async (statement) => {\n await execIgnore(run, statement);\n }),\n );\n}\n\nasync function migrateBaselineColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, BASELINE_INFRA_HASH_ALTER);\n await execIgnore(run, BASELINE_FINGERPRINT_ALTER);\n await execIgnore(run, BASELINE_SOURCE_BUILD_ALTER);\n}\n\nasync function migrateProjectExtras(run: MigrationRunner): Promise<void> {\n await execIgnore(run, EXECUTE_PLAY_ALTER);\n await execIgnore(run, PLAY_TIMEOUT_MS_ALTER);\n await execIgnore(run, PROJECT_AUTOMIGRATE_ALTER);\n await execIgnore(run, PROJECT_AI_PROFILE_ALTER);\n await migrateProjectReviewColumns(run);\n await migrateSnapshotColumns(run);\n await migrateBaselineColumns(run);\n await migrateBuildColumns(run);\n await execIgnore(run, RUN_TESTS_ALTER);\n await migrateRecentColumns(run);\n}\n\n/** Columns added after the first adapter release; each is an idempotent `ADD COLUMN IF NOT EXISTS`. */\nasync function migrateRecentColumns(run: MigrationRunner): Promise<void> {\n await migrateDesignColumns(run);\n await migrateUnstableColumns(run);\n}\n\nasync function migrateUnstableColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, SNAPSHOT_UNSTABLE_ALTER);\n await execIgnore(run, DETECT_UNSTABLE_ALTER);\n}\n\nasync function migrateDesignColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, DESIGN_NODE_NOTIFIED_ALTER);\n}\n\nasync function migrateProjectReviewColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, PROJECT_REVIEW_ENABLED_ALTER);\n await execIgnore(run, PROJECT_REVIEW_APPROVALS_ALTER);\n await execIgnore(run, PROJECT_STORYBOOK_URL_TTL_ALTER);\n}\n\nasync function migrateBuildColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, BUILD_AFFECTED_ONLY_ALTER);\n await execIgnore(run, BUILD_BASELINE_SHA_ALTER);\n await execIgnore(run, BUILD_CHANGED_FILES_ALTER);\n await execIgnore(run, BUILD_AFFECTED_PATHS_ALTER);\n await execIgnore(run, BUILD_INHERITED_COUNT_ALTER);\n await execIgnore(run, BUILD_TEST_RESULTS_ALTER);\n}\n\n/** Run the full migration set through any row-query runner. */\nexport async function runMigrations(run: MigrationRunner): Promise<void> {\n await run(DDL);\n await migrateCoreColumns(run);\n await migrateUserAuthColumns(run);\n await migrateProjectExtras(run);\n await applyIdentityStatements(run);\n await migrateCommentsTable(run);\n await migrateNotificationColumns(run);\n}\n\n/**\n * Unlike the other follow-up ALTERs this one is not swallowed: if the columns cannot be added the\n * boot must fail loudly, because a missing `disabled` column means access control silently does\n * not work. `ADD COLUMN IF NOT EXISTS` is already idempotent, so there is no \"already done\" error\n * to ignore.\n */\nasync function migrateUserAuthColumns(run: MigrationRunner): Promise<void> {\n for (const statement of USER_AUTH_ALTERS) {\n // oxlint-disable-next-line no-await-in-loop -- ordered, and a failure must stop the boot\n await run(statement);\n }\n}\n\nasync function migrateRunA11yDefault(run: MigrationRunner): Promise<void> {\n await execIgnore(run, RUN_A11Y_ALTER);\n await execIgnore(run, RUN_A11Y_DEFAULT_ALTER);\n}\n\nasync function migrateCoreColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, STORYBOOK_META_ALTER);\n await migrateRunA11yDefault(run);\n await execIgnore(run, PROJECT_BROWSER_ALTER);\n await execIgnore(run, PROJECT_VIEWPORTS_ALTER);\n await execIgnore(run, WEBHOOK_SECRET_ALTER);\n await execIgnore(run, WEBHOOK_SECRET_DROP);\n await execIgnore(run, TOKEN_USER_ALTER);\n await execIgnore(run, MEMBER_SOURCE_ALTER);\n await execIgnore(run, BUILDS_GITSHA_DEDUP);\n await execIgnore(run, BUILDS_GITSHA_INDEX);\n}\n\nasync function applyIdentityStatements(run: MigrationRunner): Promise<void> {\n for (const statement of IDENTITY_STATEMENTS) {\n // oxlint-disable-next-line no-await-in-loop -- ordered: drop old indexes, then create new\n await execIgnore(run, statement);\n }\n}\n\nasync function execIgnore(run: MigrationRunner, sql: string): Promise<void> {\n try {\n await run(sql);\n } catch {\n // idempotent — already migrated\n }\n}\n\nasync function migrateNotificationColumns(run: MigrationRunner): Promise<void> {\n await execIgnore(run, NOTIFICATION_LAST_ERROR_ALTER);\n await execIgnore(run, NOTIFICATION_LAST_ERROR_AT_ALTER);\n}\n\nasync function migrateCommentsTable(run: MigrationRunner): Promise<void> {\n await execIgnore(run, COMMENT_STORY_ID_ALTER);\n try {\n const rows = (await run(\n \"SELECT is_nullable FROM information_schema.columns WHERE table_name='comments' AND column_name='user_id'\",\n )) as { is_nullable: string }[];\n const isNullable = rows[0]?.is_nullable;\n if (isNullable === \"YES\" || isNullable === undefined) {\n return;\n }\n await run(\"ALTER TABLE comments ALTER COLUMN user_id DROP NOT NULL\");\n } catch {\n // already nullable or table missing — ignore\n }\n}\n"],"mappings":"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"}
|
package/dist/neon-http.mjs
CHANGED
|
@@ -32,7 +32,7 @@ function createNeonHttpDatabase(options) {
|
|
|
32
32
|
return createDrizzlePgAdapter(db, {
|
|
33
33
|
metadata: {
|
|
34
34
|
name: "Neon HTTP",
|
|
35
|
-
version: "0.9.0-next-
|
|
35
|
+
version: "0.9.0-next-3604136",
|
|
36
36
|
description: "Neon Postgres database adapter (HTTP driver + Drizzle)",
|
|
37
37
|
kind: "neon-http",
|
|
38
38
|
category: "database"
|
package/dist/neon.mjs
CHANGED
|
@@ -31,7 +31,7 @@ function createNeonDatabase(options) {
|
|
|
31
31
|
return createDrizzlePgAdapter(db, {
|
|
32
32
|
metadata: {
|
|
33
33
|
name: "Neon",
|
|
34
|
-
version: "0.9.0-next-
|
|
34
|
+
version: "0.9.0-next-3604136",
|
|
35
35
|
description: "Neon Postgres database adapter (serverless driver + Drizzle)",
|
|
36
36
|
kind: "neon",
|
|
37
37
|
category: "database"
|
package/dist/pg.mjs
CHANGED
|
@@ -29,7 +29,7 @@ function createPgDatabase(options) {
|
|
|
29
29
|
return createDrizzlePgAdapter(db, {
|
|
30
30
|
metadata: {
|
|
31
31
|
name: "Postgres (pg)",
|
|
32
|
-
version: "0.9.0-next-
|
|
32
|
+
version: "0.9.0-next-3604136",
|
|
33
33
|
description: "Postgres database adapter (node-postgres + Drizzle)",
|
|
34
34
|
kind: "pg",
|
|
35
35
|
category: "database"
|
package/dist/pglite.mjs
CHANGED
|
@@ -29,7 +29,7 @@ function createPgliteDatabase(options = {}) {
|
|
|
29
29
|
return createDrizzlePgAdapter(db, {
|
|
30
30
|
metadata: {
|
|
31
31
|
name: "PGlite",
|
|
32
|
-
version: "0.9.0-next-
|
|
32
|
+
version: "0.9.0-next-3604136",
|
|
33
33
|
description: "PGlite database adapter (embedded Postgres/WASM + Drizzle)",
|
|
34
34
|
kind: "pglite",
|
|
35
35
|
category: "database"
|
|
@@ -228,6 +228,23 @@ declare const projects: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
228
228
|
identity: undefined;
|
|
229
229
|
generated: undefined;
|
|
230
230
|
}, {}, {}>;
|
|
231
|
+
detectUnstable: import("drizzle-orm/pg-core").PgColumn<{
|
|
232
|
+
name: "detect_unstable";
|
|
233
|
+
tableName: "projects";
|
|
234
|
+
dataType: "boolean";
|
|
235
|
+
columnType: "PgBoolean";
|
|
236
|
+
data: boolean;
|
|
237
|
+
driverParam: boolean;
|
|
238
|
+
notNull: true;
|
|
239
|
+
hasDefault: true;
|
|
240
|
+
isPrimaryKey: false;
|
|
241
|
+
isAutoincrement: false;
|
|
242
|
+
hasRuntimeDefault: false;
|
|
243
|
+
enumValues: undefined;
|
|
244
|
+
baseColumn: never;
|
|
245
|
+
identity: undefined;
|
|
246
|
+
generated: undefined;
|
|
247
|
+
}, {}, {}>;
|
|
231
248
|
browser: import("drizzle-orm/pg-core").PgColumn<{
|
|
232
249
|
name: "browser";
|
|
233
250
|
tableName: "projects";
|
|
@@ -433,6 +450,7 @@ interface Project {
|
|
|
433
450
|
playTimeoutMs: number;
|
|
434
451
|
runA11y?: boolean;
|
|
435
452
|
runTests?: boolean;
|
|
453
|
+
detectUnstable?: boolean;
|
|
436
454
|
browser?: string;
|
|
437
455
|
viewports?: string | null;
|
|
438
456
|
browsers?: string | null;
|
package/dist/schema/project.mjs
CHANGED
|
@@ -18,6 +18,7 @@ const projects = pgTable("projects", {
|
|
|
18
18
|
playTimeoutMs: integer("play_timeout_ms").notNull().default(1e4),
|
|
19
19
|
runA11y: boolean("run_a11y").notNull().default(true),
|
|
20
20
|
runTests: boolean("run_tests").notNull().default(false),
|
|
21
|
+
detectUnstable: boolean("detect_unstable").notNull().default(true),
|
|
21
22
|
browser: text("browser").notNull().default("chromium"),
|
|
22
23
|
viewports: text("viewports"),
|
|
23
24
|
browsers: text("browsers"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.mjs","names":[],"sources":["../../src/schema/project.ts"],"sourcesContent":["import { boolean, doublePrecision, integer, pgTable, text, timestamp } from \"drizzle-orm/pg-core\";\n\n/** Narrow `projects` table definition. */\nexport const projects = pgTable(\"projects\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n slug: text(\"slug\").notNull(),\n gitRepository: text(\"git_repository\"),\n gitDefaultBranch: text(\"git_default_branch\").notNull().default(\"main\"),\n pixelThreshold: doublePrecision(\"pixel_threshold\").notNull().default(0.1),\n maxDiffRatio: doublePrecision(\"max_diff_ratio\").notNull().default(0.01),\n publicBranchRegex: text(\"public_branch_regex\"),\n storybookMeta: text(\"storybook_meta\").$type<string | null | undefined>().default(null),\n executePlay: boolean(\"execute_play\").notNull().default(false),\n playTimeoutMs: integer(\"play_timeout_ms\").notNull().default(10_000),\n runA11y: boolean(\"run_a11y\").notNull().default(true),\n runTests: boolean(\"run_tests\").notNull().default(false),\n browser: text(\"browser\").notNull().default(\"chromium\"),\n viewports: text(\"viewports\"),\n browsers: text(\"browsers\"),\n modesAllowlist: text(\"modes_allowlist\"),\n automigrate: boolean(\"automigrate\").notNull().default(false),\n aiProfile: text(\"ai_profile\"),\n reviewEnabled: boolean(\"review_enabled\").notNull().default(true),\n reviewApprovals: integer(\"review_approvals\").notNull().default(1),\n storybookUrlTtlSeconds: integer(\"storybook_url_ttl_seconds\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n});\n\n/** A project row. */\nexport interface Project {\n id: string;\n name: string;\n slug: string;\n gitRepository: string | null;\n gitDefaultBranch: string;\n pixelThreshold: number;\n maxDiffRatio: number;\n publicBranchRegex: string | null;\n storybookMeta: string | null | undefined;\n executePlay: boolean;\n playTimeoutMs: number;\n runA11y?: boolean;\n runTests?: boolean;\n browser?: string;\n viewports?: string | null;\n browsers?: string | null;\n modesAllowlist?: string | null;\n automigrate: boolean;\n aiProfile: string | null;\n reviewEnabled: boolean;\n reviewApprovals: number;\n storybookUrlTtlSeconds: number | null;\n createdAt: string;\n updatedAt: string;\n}\n\n/** Storybook metadata synced from a project's published Storybook. */\nexport interface StorybookMeta {\n framework?: { name?: string; options?: unknown };\n addons?: string[];\n storiesGlobs?: string[];\n staticDirs?: string[];\n packagePath?: string;\n previewParameters?: Record<string, unknown>;\n}\n"],"mappings":";;;;;;AAGA,MAAa,WAAW,QAAQ,YAAY;CAC1C,IAAI,KAAK,IAAI,CAAC,CAAC,WAAW;CAC1B,MAAM,KAAK,MAAM,CAAC,CAAC,QAAQ;CAC3B,MAAM,KAAK,MAAM,CAAC,CAAC,QAAQ;CAC3B,eAAe,KAAK,gBAAgB;CACpC,kBAAkB,KAAK,oBAAoB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,MAAM;CACrE,gBAAgB,gBAAgB,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAG;CACxE,cAAc,gBAAgB,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,GAAI;CACtE,mBAAmB,KAAK,qBAAqB;CAC7C,eAAe,KAAK,gBAAgB,CAAC,CAAC,MAAiC,CAAC,CAAC,QAAQ,IAAI;CACrF,aAAa,QAAQ,cAAc,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CAC5D,eAAe,QAAQ,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,GAAM;CAClE,SAAS,QAAQ,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI;CACnD,UAAU,QAAQ,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CACtD,SAAS,KAAK,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,UAAU;CACrD,WAAW,KAAK,WAAW;CAC3B,UAAU,KAAK,UAAU;CACzB,gBAAgB,KAAK,iBAAiB;CACtC,aAAa,QAAQ,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CAC3D,WAAW,KAAK,YAAY;CAC5B,eAAe,QAAQ,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI;CAC/D,iBAAiB,QAAQ,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;CAChE,wBAAwB,QAAQ,2BAA2B;CAC3D,WAAW,UAAU,cAAc;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC,CAAC,CAAC,QAAQ;CACnF,WAAW,UAAU,cAAc;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC,CAAC,CAAC,QAAQ;AACrF,CAAC"}
|
|
1
|
+
{"version":3,"file":"project.mjs","names":[],"sources":["../../src/schema/project.ts"],"sourcesContent":["import { boolean, doublePrecision, integer, pgTable, text, timestamp } from \"drizzle-orm/pg-core\";\n\n/** Narrow `projects` table definition. */\nexport const projects = pgTable(\"projects\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n slug: text(\"slug\").notNull(),\n gitRepository: text(\"git_repository\"),\n gitDefaultBranch: text(\"git_default_branch\").notNull().default(\"main\"),\n pixelThreshold: doublePrecision(\"pixel_threshold\").notNull().default(0.1),\n maxDiffRatio: doublePrecision(\"max_diff_ratio\").notNull().default(0.01),\n publicBranchRegex: text(\"public_branch_regex\"),\n storybookMeta: text(\"storybook_meta\").$type<string | null | undefined>().default(null),\n executePlay: boolean(\"execute_play\").notNull().default(false),\n playTimeoutMs: integer(\"play_timeout_ms\").notNull().default(10_000),\n runA11y: boolean(\"run_a11y\").notNull().default(true),\n runTests: boolean(\"run_tests\").notNull().default(false),\n detectUnstable: boolean(\"detect_unstable\").notNull().default(true),\n browser: text(\"browser\").notNull().default(\"chromium\"),\n viewports: text(\"viewports\"),\n browsers: text(\"browsers\"),\n modesAllowlist: text(\"modes_allowlist\"),\n automigrate: boolean(\"automigrate\").notNull().default(false),\n aiProfile: text(\"ai_profile\"),\n reviewEnabled: boolean(\"review_enabled\").notNull().default(true),\n reviewApprovals: integer(\"review_approvals\").notNull().default(1),\n storybookUrlTtlSeconds: integer(\"storybook_url_ttl_seconds\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n});\n\n/** A project row. */\nexport interface Project {\n id: string;\n name: string;\n slug: string;\n gitRepository: string | null;\n gitDefaultBranch: string;\n pixelThreshold: number;\n maxDiffRatio: number;\n publicBranchRegex: string | null;\n storybookMeta: string | null | undefined;\n executePlay: boolean;\n playTimeoutMs: number;\n runA11y?: boolean;\n runTests?: boolean;\n detectUnstable?: boolean;\n browser?: string;\n viewports?: string | null;\n browsers?: string | null;\n modesAllowlist?: string | null;\n automigrate: boolean;\n aiProfile: string | null;\n reviewEnabled: boolean;\n reviewApprovals: number;\n storybookUrlTtlSeconds: number | null;\n createdAt: string;\n updatedAt: string;\n}\n\n/** Storybook metadata synced from a project's published Storybook. */\nexport interface StorybookMeta {\n framework?: { name?: string; options?: unknown };\n addons?: string[];\n storiesGlobs?: string[];\n staticDirs?: string[];\n packagePath?: string;\n previewParameters?: Record<string, unknown>;\n}\n"],"mappings":";;;;;;AAGA,MAAa,WAAW,QAAQ,YAAY;CAC1C,IAAI,KAAK,IAAI,CAAC,CAAC,WAAW;CAC1B,MAAM,KAAK,MAAM,CAAC,CAAC,QAAQ;CAC3B,MAAM,KAAK,MAAM,CAAC,CAAC,QAAQ;CAC3B,eAAe,KAAK,gBAAgB;CACpC,kBAAkB,KAAK,oBAAoB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,MAAM;CACrE,gBAAgB,gBAAgB,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAG;CACxE,cAAc,gBAAgB,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,GAAI;CACtE,mBAAmB,KAAK,qBAAqB;CAC7C,eAAe,KAAK,gBAAgB,CAAC,CAAC,MAAiC,CAAC,CAAC,QAAQ,IAAI;CACrF,aAAa,QAAQ,cAAc,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CAC5D,eAAe,QAAQ,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,GAAM;CAClE,SAAS,QAAQ,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI;CACnD,UAAU,QAAQ,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CACtD,gBAAgB,QAAQ,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI;CACjE,SAAS,KAAK,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,UAAU;CACrD,WAAW,KAAK,WAAW;CAC3B,UAAU,KAAK,UAAU;CACzB,gBAAgB,KAAK,iBAAiB;CACtC,aAAa,QAAQ,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CAC3D,WAAW,KAAK,YAAY;CAC5B,eAAe,QAAQ,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI;CAC/D,iBAAiB,QAAQ,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;CAChE,wBAAwB,QAAQ,2BAA2B;CAC3D,WAAW,UAAU,cAAc;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC,CAAC,CAAC,QAAQ;CACnF,WAAW,UAAU,cAAc;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC,CAAC,CAAC,QAAQ;AACrF,CAAC"}
|
|
@@ -535,6 +535,23 @@ declare const snapshots: import("drizzle-orm/pg-core/table.js").PgTableWithColum
|
|
|
535
535
|
identity: undefined;
|
|
536
536
|
generated: undefined;
|
|
537
537
|
}, {}, {}>;
|
|
538
|
+
unstable: import("drizzle-orm/pg-core/index.js").PgColumn<{
|
|
539
|
+
name: "unstable";
|
|
540
|
+
tableName: "snapshots";
|
|
541
|
+
dataType: "boolean";
|
|
542
|
+
columnType: "PgBoolean";
|
|
543
|
+
data: boolean;
|
|
544
|
+
driverParam: boolean;
|
|
545
|
+
notNull: false;
|
|
546
|
+
hasDefault: false;
|
|
547
|
+
isPrimaryKey: false;
|
|
548
|
+
isAutoincrement: false;
|
|
549
|
+
hasRuntimeDefault: false;
|
|
550
|
+
enumValues: undefined;
|
|
551
|
+
baseColumn: never;
|
|
552
|
+
identity: undefined;
|
|
553
|
+
generated: undefined;
|
|
554
|
+
}, {}, {}>;
|
|
538
555
|
createdAt: import("drizzle-orm/pg-core/index.js").PgColumn<{
|
|
539
556
|
name: "created_at";
|
|
540
557
|
tableName: "snapshots";
|
|
@@ -605,6 +622,7 @@ interface Snapshot {
|
|
|
605
622
|
browser?: string;
|
|
606
623
|
durationMs: number | null;
|
|
607
624
|
a11yViolations: string | null;
|
|
625
|
+
unstable: boolean | null;
|
|
608
626
|
createdAt: string;
|
|
609
627
|
updatedAt: string;
|
|
610
628
|
}
|
package/dist/schema/snapshot.mjs
CHANGED
|
@@ -41,6 +41,7 @@ const snapshots = pgTable("snapshots", {
|
|
|
41
41
|
browser: text("browser").notNull().default("chromium"),
|
|
42
42
|
durationMs: integer("duration_ms"),
|
|
43
43
|
a11yViolations: text("a11y_violations"),
|
|
44
|
+
unstable: boolean("unstable"),
|
|
44
45
|
createdAt: timestamp("created_at", {
|
|
45
46
|
withTimezone: true,
|
|
46
47
|
mode: "string"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.mjs","names":[],"sources":["../../src/schema/snapshot.ts"],"sourcesContent":["import type { SnapshotStatus } from \"@storyshelf/core/types\";\nimport {\n boolean,\n doublePrecision,\n index,\n integer,\n pgTable,\n text,\n timestamp,\n uniqueIndex,\n} from \"drizzle-orm/pg-core\";\nimport { builds } from \"./build.ts\";\nimport { projects } from \"./project.ts\";\n\n/** Narrow `snapshots` table definition. */\nexport const snapshots = pgTable(\n \"snapshots\",\n {\n id: text(\"id\").primaryKey(),\n projectId: text(\"project_id\")\n .notNull()\n .references(() => projects.id, { onDelete: \"cascade\" }),\n buildId: text(\"build_id\")\n .notNull()\n .references(() => builds.id, { onDelete: \"cascade\" }),\n storyId: text(\"story_id\").notNull(),\n storyName: text(\"story_name\").notNull(),\n storyTitle: text(\"story_title\").notNull(),\n storyImportPath: text(\"story_import_path\"),\n designUrl: text(\"design_url\"),\n viewportName: text(\"viewport_name\").notNull().default(\"desktop\"),\n viewportWidth: integer(\"viewport_width\").notNull().default(1280),\n viewportHeight: integer(\"viewport_height\").notNull().default(720),\n screenshotPath: text(\"screenshot_path\").notNull(),\n diffPath: text(\"diff_path\"),\n diffPixels: integer(\"diff_pixels\"),\n diffRatio: doublePrecision(\"diff_ratio\"),\n diffPassed: boolean(\"diff_passed\"),\n status: text(\"status\").$type<SnapshotStatus>().notNull().default(\"pending\"),\n reviewedBy: text(\"reviewed_by\"),\n reviewedAt: timestamp(\"reviewed_at\", { withTimezone: true, mode: \"string\" }),\n infraHash: text(\"infra_hash\"),\n envChange: text(\"env_change\"),\n inherited: boolean(\"inherited\").notNull().default(false),\n baselineId: text(\"baseline_id\"),\n baselineVersion: text(\"baseline_version\"),\n sourceBuildId: text(\"source_build_id\"),\n comparisonImagePath: text(\"comparison_image_path\"),\n comparisonMetadata: text(\"comparison_metadata\"),\n mode: text(\"mode\"),\n browser: text(\"browser\").notNull().default(\"chromium\"),\n durationMs: integer(\"duration_ms\"),\n a11yViolations: text(\"a11y_violations\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n },\n (t) => [\n uniqueIndex(\"snapshots_build_story_mode_browser_idx\").on(\n t.buildId,\n t.storyId,\n t.viewportName,\n t.browser,\n ),\n index(\"snapshots_build_id_idx\").on(t.buildId),\n index(\"snapshots_project_import_path_idx\").on(t.projectId, t.storyImportPath),\n ],\n);\n\n/** A snapshot row. */\nexport interface Snapshot {\n id: string;\n projectId: string;\n buildId: string;\n storyId: string;\n storyName: string;\n storyTitle: string;\n storyImportPath: string | null;\n designUrl: string | null;\n viewportName: string;\n viewportWidth: number;\n viewportHeight: number;\n screenshotPath: string;\n diffPath: string | null;\n diffPixels: number | null;\n diffRatio: number | null;\n diffPassed: boolean | null;\n status: SnapshotStatus;\n reviewedBy: string | null;\n reviewedAt: string | null;\n infraHash: string | null;\n envChange: string | null;\n inherited: boolean;\n baselineId: string | null;\n baselineVersion: string | null;\n sourceBuildId: string | null;\n comparisonImagePath: string | null;\n comparisonMetadata: string | null;\n mode?: string | null;\n browser?: string;\n durationMs: number | null;\n a11yViolations: string | null;\n createdAt: string;\n updatedAt: string;\n}\n"],"mappings":";;;;;;;;AAeA,MAAa,YAAY,QACvB,aACA;CACE,IAAI,KAAK,IAAI,CAAC,CAAC,WAAW;CAC1B,WAAW,KAAK,YAAY,CAAC,CAC1B,QAAQ,CAAC,CACT,iBAAiB,SAAS,IAAI,EAAE,UAAU,UAAU,CAAC;CACxD,SAAS,KAAK,UAAU,CAAC,CACtB,QAAQ,CAAC,CACT,iBAAiB,OAAO,IAAI,EAAE,UAAU,UAAU,CAAC;CACtD,SAAS,KAAK,UAAU,CAAC,CAAC,QAAQ;CAClC,WAAW,KAAK,YAAY,CAAC,CAAC,QAAQ;CACtC,YAAY,KAAK,aAAa,CAAC,CAAC,QAAQ;CACxC,iBAAiB,KAAK,mBAAmB;CACzC,WAAW,KAAK,YAAY;CAC5B,cAAc,KAAK,eAAe,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,SAAS;CAC/D,eAAe,QAAQ,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI;CAC/D,gBAAgB,QAAQ,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,GAAG;CAChE,gBAAgB,KAAK,iBAAiB,CAAC,CAAC,QAAQ;CAChD,UAAU,KAAK,WAAW;CAC1B,YAAY,QAAQ,aAAa;CACjC,WAAW,gBAAgB,YAAY;CACvC,YAAY,QAAQ,aAAa;CACjC,QAAQ,KAAK,QAAQ,CAAC,CAAC,MAAsB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,SAAS;CAC1E,YAAY,KAAK,aAAa;CAC9B,YAAY,UAAU,eAAe;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC;CAC3E,WAAW,KAAK,YAAY;CAC5B,WAAW,KAAK,YAAY;CAC5B,WAAW,QAAQ,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CACvD,YAAY,KAAK,aAAa;CAC9B,iBAAiB,KAAK,kBAAkB;CACxC,eAAe,KAAK,iBAAiB;CACrC,qBAAqB,KAAK,uBAAuB;CACjD,oBAAoB,KAAK,qBAAqB;CAC9C,MAAM,KAAK,MAAM;CACjB,SAAS,KAAK,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,UAAU;CACrD,YAAY,QAAQ,aAAa;CACjC,gBAAgB,KAAK,iBAAiB;CACtC,WAAW,UAAU,cAAc;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC,CAAC,CAAC,QAAQ;CACnF,WAAW,UAAU,cAAc;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC,CAAC,CAAC,QAAQ;AACrF,IACC,MAAM;CACL,YAAY,wCAAwC,CAAC,CAAC,GACpD,EAAE,SACF,EAAE,SACF,EAAE,cACF,EAAE,OACJ;CACA,MAAM,wBAAwB,CAAC,CAAC,GAAG,EAAE,OAAO;CAC5C,MAAM,mCAAmC,CAAC,CAAC,GAAG,EAAE,WAAW,EAAE,eAAe;AAC9E,CACF"}
|
|
1
|
+
{"version":3,"file":"snapshot.mjs","names":[],"sources":["../../src/schema/snapshot.ts"],"sourcesContent":["import type { SnapshotStatus } from \"@storyshelf/core/types\";\nimport {\n boolean,\n doublePrecision,\n index,\n integer,\n pgTable,\n text,\n timestamp,\n uniqueIndex,\n} from \"drizzle-orm/pg-core\";\nimport { builds } from \"./build.ts\";\nimport { projects } from \"./project.ts\";\n\n/** Narrow `snapshots` table definition. */\nexport const snapshots = pgTable(\n \"snapshots\",\n {\n id: text(\"id\").primaryKey(),\n projectId: text(\"project_id\")\n .notNull()\n .references(() => projects.id, { onDelete: \"cascade\" }),\n buildId: text(\"build_id\")\n .notNull()\n .references(() => builds.id, { onDelete: \"cascade\" }),\n storyId: text(\"story_id\").notNull(),\n storyName: text(\"story_name\").notNull(),\n storyTitle: text(\"story_title\").notNull(),\n storyImportPath: text(\"story_import_path\"),\n designUrl: text(\"design_url\"),\n viewportName: text(\"viewport_name\").notNull().default(\"desktop\"),\n viewportWidth: integer(\"viewport_width\").notNull().default(1280),\n viewportHeight: integer(\"viewport_height\").notNull().default(720),\n screenshotPath: text(\"screenshot_path\").notNull(),\n diffPath: text(\"diff_path\"),\n diffPixels: integer(\"diff_pixels\"),\n diffRatio: doublePrecision(\"diff_ratio\"),\n diffPassed: boolean(\"diff_passed\"),\n status: text(\"status\").$type<SnapshotStatus>().notNull().default(\"pending\"),\n reviewedBy: text(\"reviewed_by\"),\n reviewedAt: timestamp(\"reviewed_at\", { withTimezone: true, mode: \"string\" }),\n infraHash: text(\"infra_hash\"),\n envChange: text(\"env_change\"),\n inherited: boolean(\"inherited\").notNull().default(false),\n baselineId: text(\"baseline_id\"),\n baselineVersion: text(\"baseline_version\"),\n sourceBuildId: text(\"source_build_id\"),\n comparisonImagePath: text(\"comparison_image_path\"),\n comparisonMetadata: text(\"comparison_metadata\"),\n mode: text(\"mode\"),\n browser: text(\"browser\").notNull().default(\"chromium\"),\n durationMs: integer(\"duration_ms\"),\n a11yViolations: text(\"a11y_violations\"),\n unstable: boolean(\"unstable\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n },\n (t) => [\n uniqueIndex(\"snapshots_build_story_mode_browser_idx\").on(\n t.buildId,\n t.storyId,\n t.viewportName,\n t.browser,\n ),\n index(\"snapshots_build_id_idx\").on(t.buildId),\n index(\"snapshots_project_import_path_idx\").on(t.projectId, t.storyImportPath),\n ],\n);\n\n/** A snapshot row. */\nexport interface Snapshot {\n id: string;\n projectId: string;\n buildId: string;\n storyId: string;\n storyName: string;\n storyTitle: string;\n storyImportPath: string | null;\n designUrl: string | null;\n viewportName: string;\n viewportWidth: number;\n viewportHeight: number;\n screenshotPath: string;\n diffPath: string | null;\n diffPixels: number | null;\n diffRatio: number | null;\n diffPassed: boolean | null;\n status: SnapshotStatus;\n reviewedBy: string | null;\n reviewedAt: string | null;\n infraHash: string | null;\n envChange: string | null;\n inherited: boolean;\n baselineId: string | null;\n baselineVersion: string | null;\n sourceBuildId: string | null;\n comparisonImagePath: string | null;\n comparisonMetadata: string | null;\n mode?: string | null;\n browser?: string;\n durationMs: number | null;\n a11yViolations: string | null;\n unstable: boolean | null;\n createdAt: string;\n updatedAt: string;\n}\n"],"mappings":";;;;;;;;AAeA,MAAa,YAAY,QACvB,aACA;CACE,IAAI,KAAK,IAAI,CAAC,CAAC,WAAW;CAC1B,WAAW,KAAK,YAAY,CAAC,CAC1B,QAAQ,CAAC,CACT,iBAAiB,SAAS,IAAI,EAAE,UAAU,UAAU,CAAC;CACxD,SAAS,KAAK,UAAU,CAAC,CACtB,QAAQ,CAAC,CACT,iBAAiB,OAAO,IAAI,EAAE,UAAU,UAAU,CAAC;CACtD,SAAS,KAAK,UAAU,CAAC,CAAC,QAAQ;CAClC,WAAW,KAAK,YAAY,CAAC,CAAC,QAAQ;CACtC,YAAY,KAAK,aAAa,CAAC,CAAC,QAAQ;CACxC,iBAAiB,KAAK,mBAAmB;CACzC,WAAW,KAAK,YAAY;CAC5B,cAAc,KAAK,eAAe,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,SAAS;CAC/D,eAAe,QAAQ,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI;CAC/D,gBAAgB,QAAQ,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,GAAG;CAChE,gBAAgB,KAAK,iBAAiB,CAAC,CAAC,QAAQ;CAChD,UAAU,KAAK,WAAW;CAC1B,YAAY,QAAQ,aAAa;CACjC,WAAW,gBAAgB,YAAY;CACvC,YAAY,QAAQ,aAAa;CACjC,QAAQ,KAAK,QAAQ,CAAC,CAAC,MAAsB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,SAAS;CAC1E,YAAY,KAAK,aAAa;CAC9B,YAAY,UAAU,eAAe;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC;CAC3E,WAAW,KAAK,YAAY;CAC5B,WAAW,KAAK,YAAY;CAC5B,WAAW,QAAQ,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CACvD,YAAY,KAAK,aAAa;CAC9B,iBAAiB,KAAK,kBAAkB;CACxC,eAAe,KAAK,iBAAiB;CACrC,qBAAqB,KAAK,uBAAuB;CACjD,oBAAoB,KAAK,qBAAqB;CAC9C,MAAM,KAAK,MAAM;CACjB,SAAS,KAAK,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,UAAU;CACrD,YAAY,QAAQ,aAAa;CACjC,gBAAgB,KAAK,iBAAiB;CACtC,UAAU,QAAQ,UAAU;CAC5B,WAAW,UAAU,cAAc;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC,CAAC,CAAC,QAAQ;CACnF,WAAW,UAAU,cAAc;EAAE,cAAc;EAAM,MAAM;CAAS,CAAC,CAAC,CAAC,QAAQ;AACrF,IACC,MAAM;CACL,YAAY,wCAAwC,CAAC,CAAC,GACpD,EAAE,SACF,EAAE,SACF,EAAE,cACF,EAAE,OACJ;CACA,MAAM,wBAAwB,CAAC,CAAC,GAAG,EAAE,OAAO;CAC5C,MAAM,mCAAmC,CAAC,CAAC,GAAG,EAAE,WAAW,EAAE,eAAe;AAC9E,CACF"}
|
package/dist/vercel.mjs
CHANGED
|
@@ -27,7 +27,7 @@ function createVercelDatabase(options = {}) {
|
|
|
27
27
|
return createDrizzlePgAdapter(db, {
|
|
28
28
|
metadata: {
|
|
29
29
|
name: "Vercel Postgres",
|
|
30
|
-
version: "0.9.0-next-
|
|
30
|
+
version: "0.9.0-next-3604136",
|
|
31
31
|
description: "Vercel Postgres database adapter (@vercel/postgres + Drizzle)",
|
|
32
32
|
kind: "vercel",
|
|
33
33
|
category: "database"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyshelf/db-postgres",
|
|
3
|
-
"version": "0.9.0-next-
|
|
3
|
+
"version": "0.9.0-next-3604136",
|
|
4
4
|
"description": "Postgres database adapter for StoryShelf (postgres.js + Drizzle, RDS/Cloud SQL/Supabase/Neon compatible).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"database",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"prepublishOnly": "nub run build"
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@storyshelf/core": "0.9.0-next-
|
|
89
|
+
"@storyshelf/core": "0.9.0-next-3604136",
|
|
90
90
|
"drizzle-orm": "^0.45.4",
|
|
91
91
|
"postgres": "^3.4.0"
|
|
92
92
|
},
|