diff --git a/drizzle/migrations/0001_showcase_placements.sql b/drizzle/migrations/0001_showcase_placements.sql new file mode 100644 index 000000000..1780504ea --- /dev/null +++ b/drizzle/migrations/0001_showcase_placements.sql @@ -0,0 +1,8 @@ +CREATE TYPE "public"."showcase_placement" AS ENUM('showcase', 'community', 'private');--> statement-breakpoint +ALTER TABLE "showcases" ADD COLUMN "placement" "showcase_placement";--> statement-breakpoint +-- Preserve existing visibility. Editorial decisions are applied separately. +UPDATE "showcases" SET "placement" = CASE WHEN "status" = 'approved' THEN 'showcase'::showcase_placement ELSE 'private'::showcase_placement END;--> statement-breakpoint +ALTER TABLE "showcases" ALTER COLUMN "placement" SET DEFAULT 'private';--> statement-breakpoint +ALTER TABLE "showcases" ALTER COLUMN "placement" SET NOT NULL;--> statement-breakpoint +ALTER TABLE "showcases" ADD COLUMN "review_reason" text;--> statement-breakpoint +CREATE INDEX "showcases_status_placement_idx" ON "showcases" USING btree ("status","placement"); \ No newline at end of file diff --git a/drizzle/migrations/meta/0001_snapshot.json b/drizzle/migrations/meta/0001_snapshot.json new file mode 100644 index 000000000..54bc09f8a --- /dev/null +++ b/drizzle/migrations/meta/0001_snapshot.json @@ -0,0 +1,5222 @@ +{ + "id": "87b28f50-b9fa-47c9-8230-b2c8121cb3ff", + "prevId": "4998503e-2f2a-4996-9758-66293fa31b76", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "audit_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(45)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_actor_id_idx": { + "name": "audit_logs_actor_id_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_action_idx": { + "name": "audit_logs_action_idx", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_target_type_idx": { + "name": "audit_logs_target_type_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_target_id_idx": { + "name": "audit_logs_target_id_idx", + "columns": [ + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_created_at_idx": { + "name": "audit_logs_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": ["actor_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.builder_project_events": { + "name": "builder_project_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thread_id": { + "name": "thread_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revision_id": { + "name": "revision_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "message_id": { + "name": "message_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "run_id": { + "name": "run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "client_event_id": { + "name": "client_event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "client_mutation_id": { + "name": "client_mutation_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "browser_session_id": { + "name": "browser_session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "builder_project_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "builder_project_events_project_created_at_idx": { + "name": "builder_project_events_project_created_at_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "builder_project_events_run_sequence_idx": { + "name": "builder_project_events_run_sequence_idx", + "columns": [ + { + "expression": "run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "builder_project_events_client_mutation_idx": { + "name": "builder_project_events_client_mutation_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "client_mutation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "builder_project_events_project_owner_fk": { + "name": "builder_project_events_project_owner_fk", + "tableFrom": "builder_project_events", + "tableTo": "builder_projects", + "columnsFrom": ["project_id", "owner_id"], + "columnsTo": ["id", "owner_id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_events_thread_fk": { + "name": "builder_project_events_thread_fk", + "tableFrom": "builder_project_events", + "tableTo": "builder_project_threads", + "columnsFrom": ["project_id", "thread_id"], + "columnsTo": ["project_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_events_revision_fk": { + "name": "builder_project_events_revision_fk", + "tableFrom": "builder_project_events", + "tableTo": "builder_project_revisions", + "columnsFrom": ["project_id", "revision_id"], + "columnsTo": ["project_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_events_message_fk": { + "name": "builder_project_events_message_fk", + "tableFrom": "builder_project_events", + "tableTo": "builder_project_messages", + "columnsFrom": ["project_id", "message_id"], + "columnsTo": ["project_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_events_run_fk": { + "name": "builder_project_events_run_fk", + "tableFrom": "builder_project_events", + "tableTo": "builder_project_runs", + "columnsFrom": ["project_id", "run_id"], + "columnsTo": ["project_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "builder_project_events_project_sequence_unique": { + "name": "builder_project_events_project_sequence_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "sequence"] + }, + "builder_project_events_project_client_event_unique": { + "name": "builder_project_events_project_client_event_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "client_event_id"] + } + }, + "policies": {}, + "checkConstraints": { + "builder_project_events_sequence_check": { + "name": "builder_project_events_sequence_check", + "value": "\"builder_project_events\".\"sequence\" BETWEEN 1 AND 9007199254740991" + }, + "builder_project_events_payload_check": { + "name": "builder_project_events_payload_check", + "value": "jsonb_typeof(\"builder_project_events\".\"payload\") = 'object' AND pg_column_size(\"builder_project_events\".\"payload\") <= 262144" + }, + "builder_project_events_entity_reference_check": { + "name": "builder_project_events_entity_reference_check", + "value": "((\"builder_project_events\".\"type\"::text NOT LIKE 'revision.%') OR \"builder_project_events\".\"revision_id\" IS NOT NULL)\n AND ((\"builder_project_events\".\"type\"::text NOT LIKE 'thread.%') OR \"builder_project_events\".\"thread_id\" IS NOT NULL)\n AND ((\"builder_project_events\".\"type\"::text NOT LIKE 'message.%') OR \"builder_project_events\".\"message_id\" IS NOT NULL)\n AND ((\"builder_project_events\".\"type\"::text NOT LIKE 'run.%') OR \"builder_project_events\".\"run_id\" IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.builder_project_legacy_imports": { + "name": "builder_project_legacy_imports", + "schema": "", + "columns": { + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "builder_project_legacy_imports_owner_id_users_id_fk": { + "name": "builder_project_legacy_imports_owner_id_users_id_fk", + "tableFrom": "builder_project_legacy_imports", + "tableTo": "users", + "columnsFrom": ["owner_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.builder_project_messages": { + "name": "builder_project_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thread_id": { + "name": "thread_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "run_id": { + "name": "run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "client_mutation_id": { + "name": "client_mutation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "builder_message_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "parts": { + "name": "parts", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "builder_project_messages_project_thread_created_at_idx": { + "name": "builder_project_messages_project_thread_created_at_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "builder_project_messages_run_id_idx": { + "name": "builder_project_messages_run_id_idx", + "columns": [ + { + "expression": "run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "builder_project_messages_project_owner_fk": { + "name": "builder_project_messages_project_owner_fk", + "tableFrom": "builder_project_messages", + "tableTo": "builder_projects", + "columnsFrom": ["project_id", "owner_id"], + "columnsTo": ["id", "owner_id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_messages_thread_fk": { + "name": "builder_project_messages_thread_fk", + "tableFrom": "builder_project_messages", + "tableTo": "builder_project_threads", + "columnsFrom": ["project_id", "thread_id"], + "columnsTo": ["project_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_messages_run_fk": { + "name": "builder_project_messages_run_fk", + "tableFrom": "builder_project_messages", + "tableTo": "builder_project_runs", + "columnsFrom": ["project_id", "thread_id", "run_id"], + "columnsTo": ["project_id", "thread_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "builder_project_messages_project_id_unique": { + "name": "builder_project_messages_project_id_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "id"] + }, + "builder_project_messages_project_mutation_unique": { + "name": "builder_project_messages_project_mutation_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "client_mutation_id"] + }, + "builder_project_messages_thread_position_unique": { + "name": "builder_project_messages_thread_position_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "thread_id", "position"] + } + }, + "policies": {}, + "checkConstraints": { + "builder_project_messages_parts_check": { + "name": "builder_project_messages_parts_check", + "value": "jsonb_typeof(\"builder_project_messages\".\"parts\") = 'array' AND pg_column_size(\"builder_project_messages\".\"parts\") <= 1048576" + }, + "builder_project_messages_content_size_check": { + "name": "builder_project_messages_content_size_check", + "value": "octet_length(\"builder_project_messages\".\"content\") <= 1048576" + }, + "builder_project_messages_position_check": { + "name": "builder_project_messages_position_check", + "value": "\"builder_project_messages\".\"position\" BETWEEN 1 AND 9007199254740991" + } + }, + "isRLSEnabled": false + }, + "public.builder_project_mutation_receipts": { + "name": "builder_project_mutation_receipts", + "schema": "", + "columns": { + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "client_mutation_id": { + "name": "client_mutation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "command_type": { + "name": "command_type", + "type": "varchar(40)", + "primaryKey": false, + "notNull": true + }, + "request_hash": { + "name": "request_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "builder_project_mutation_receipts_project_fk": { + "name": "builder_project_mutation_receipts_project_fk", + "tableFrom": "builder_project_mutation_receipts", + "tableTo": "builder_projects", + "columnsFrom": ["project_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "builder_project_mutation_receipts_pk": { + "name": "builder_project_mutation_receipts_pk", + "columns": ["project_id", "client_mutation_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "builder_project_mutation_receipts_command_type_check": { + "name": "builder_project_mutation_receipts_command_type_check", + "value": "\"builder_project_mutation_receipts\".\"command_type\" IN ('project.create', 'project.revise', 'project.delete', 'thread.create', 'run.enqueue', 'run.claim', 'run.cancel', 'run.finish', 'run.finish.fallback', 'transcript.import')" + }, + "builder_project_mutation_receipts_request_hash_check": { + "name": "builder_project_mutation_receipts_request_hash_check", + "value": "\"builder_project_mutation_receipts\".\"request_hash\" ~ '^[a-f0-9]{64}$'" + } + }, + "isRLSEnabled": false + }, + "public.builder_project_revisions": { + "name": "builder_project_revisions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "client_mutation_id": { + "name": "client_mutation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "parent_revision_id": { + "name": "parent_revision_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revision_number": { + "name": "revision_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "snapshot_hash": { + "name": "snapshot_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "builder_project_revisions_project_created_at_idx": { + "name": "builder_project_revisions_project_created_at_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "builder_project_revisions_snapshot_hash_idx": { + "name": "builder_project_revisions_snapshot_hash_idx", + "columns": [ + { + "expression": "snapshot_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "builder_project_revisions_project_owner_fk": { + "name": "builder_project_revisions_project_owner_fk", + "tableFrom": "builder_project_revisions", + "tableTo": "builder_projects", + "columnsFrom": ["project_id", "owner_id"], + "columnsTo": ["id", "owner_id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_revisions_parent_fk": { + "name": "builder_project_revisions_parent_fk", + "tableFrom": "builder_project_revisions", + "tableTo": "builder_project_revisions", + "columnsFrom": ["project_id", "parent_revision_id"], + "columnsTo": ["project_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_revisions_snapshot_hash_fk": { + "name": "builder_project_revisions_snapshot_hash_fk", + "tableFrom": "builder_project_revisions", + "tableTo": "builder_project_snapshots", + "columnsFrom": ["snapshot_hash"], + "columnsTo": ["hash"], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "builder_project_revisions_project_revision_unique": { + "name": "builder_project_revisions_project_revision_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "revision_number"] + }, + "builder_project_revisions_project_id_unique": { + "name": "builder_project_revisions_project_id_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "id"] + }, + "builder_project_revisions_project_mutation_unique": { + "name": "builder_project_revisions_project_mutation_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "client_mutation_id"] + } + }, + "policies": {}, + "checkConstraints": { + "builder_project_revisions_snapshot_hash_check": { + "name": "builder_project_revisions_snapshot_hash_check", + "value": "\"builder_project_revisions\".\"snapshot_hash\" ~ '^[a-f0-9]{64}$'" + }, + "builder_project_revisions_revision_number_check": { + "name": "builder_project_revisions_revision_number_check", + "value": "\"builder_project_revisions\".\"revision_number\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.builder_project_runs": { + "name": "builder_project_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thread_id": { + "name": "thread_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "client_mutation_id": { + "name": "client_mutation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "builder_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "queue_kind": { + "name": "queue_kind", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true, + "default": "'queue'" + }, + "provider": { + "name": "provider", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "base_revision_id": { + "name": "base_revision_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "result_revision_id": { + "name": "result_revision_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "lease_owner_id": { + "name": "lease_owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "lease_fencing_token": { + "name": "lease_fencing_token", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_heartbeat_at": { + "name": "last_heartbeat_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "activity": { + "name": "activity", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "builder_project_runs_project_thread_created_at_idx": { + "name": "builder_project_runs_project_thread_created_at_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "builder_project_runs_active_lease_idx": { + "name": "builder_project_runs_active_lease_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "lease_expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "builder_project_runs_active_project_unique": { + "name": "builder_project_runs_active_project_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"builder_project_runs\".\"status\" = 'running'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "builder_project_runs_project_owner_fk": { + "name": "builder_project_runs_project_owner_fk", + "tableFrom": "builder_project_runs", + "tableTo": "builder_projects", + "columnsFrom": ["project_id", "owner_id"], + "columnsTo": ["id", "owner_id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_runs_thread_fk": { + "name": "builder_project_runs_thread_fk", + "tableFrom": "builder_project_runs", + "tableTo": "builder_project_threads", + "columnsFrom": ["project_id", "thread_id"], + "columnsTo": ["project_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_runs_base_revision_fk": { + "name": "builder_project_runs_base_revision_fk", + "tableFrom": "builder_project_runs", + "tableTo": "builder_project_revisions", + "columnsFrom": ["project_id", "base_revision_id"], + "columnsTo": ["project_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_runs_result_revision_fk": { + "name": "builder_project_runs_result_revision_fk", + "tableFrom": "builder_project_runs", + "tableTo": "builder_project_revisions", + "columnsFrom": ["project_id", "result_revision_id"], + "columnsTo": ["project_id", "id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "builder_project_runs_project_id_unique": { + "name": "builder_project_runs_project_id_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "id"] + }, + "builder_project_runs_project_thread_id_unique": { + "name": "builder_project_runs_project_thread_id_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "thread_id", "id"] + }, + "builder_project_runs_project_mutation_unique": { + "name": "builder_project_runs_project_mutation_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "client_mutation_id"] + } + }, + "policies": {}, + "checkConstraints": { + "builder_project_runs_queue_kind_check": { + "name": "builder_project_runs_queue_kind_check", + "value": "\"builder_project_runs\".\"queue_kind\" IN ('queue', 'steer')" + }, + "builder_project_runs_fencing_token_check": { + "name": "builder_project_runs_fencing_token_check", + "value": "\"builder_project_runs\".\"lease_fencing_token\" BETWEEN 0 AND 9007199254740991" + }, + "builder_project_runs_lease_pair_check": { + "name": "builder_project_runs_lease_pair_check", + "value": "(\"builder_project_runs\".\"lease_owner_id\" IS NULL) = (\"builder_project_runs\".\"lease_expires_at\" IS NULL)" + }, + "builder_project_runs_running_lease_check": { + "name": "builder_project_runs_running_lease_check", + "value": "(\"builder_project_runs\".\"status\" = 'running') = (\"builder_project_runs\".\"lease_owner_id\" IS NOT NULL)" + }, + "builder_project_runs_terminal_state_check": { + "name": "builder_project_runs_terminal_state_check", + "value": "(\"builder_project_runs\".\"status\" IN ('interrupted', 'completed', 'failed', 'cancelled')) = (\"builder_project_runs\".\"completed_at\" IS NOT NULL)" + }, + "builder_project_runs_timestamp_order_check": { + "name": "builder_project_runs_timestamp_order_check", + "value": "\"builder_project_runs\".\"completed_at\" IS NULL OR \"builder_project_runs\".\"started_at\" IS NULL OR \"builder_project_runs\".\"completed_at\" >= \"builder_project_runs\".\"started_at\"" + }, + "builder_project_runs_activity_size_check": { + "name": "builder_project_runs_activity_size_check", + "value": "\"builder_project_runs\".\"activity\" IS NULL OR (jsonb_typeof(\"builder_project_runs\".\"activity\") = 'object' AND pg_column_size(\"builder_project_runs\".\"activity\") <= 262144)" + }, + "builder_project_runs_error_size_check": { + "name": "builder_project_runs_error_size_check", + "value": "\"builder_project_runs\".\"error\" IS NULL OR (jsonb_typeof(\"builder_project_runs\".\"error\") = 'object' AND pg_column_size(\"builder_project_runs\".\"error\") <= 262144)" + }, + "builder_project_runs_result_revision_check": { + "name": "builder_project_runs_result_revision_check", + "value": "\"builder_project_runs\".\"result_revision_id\" IS NULL OR \"builder_project_runs\".\"status\" = 'completed'" + } + }, + "isRLSEnabled": false + }, + "public.builder_project_snapshot_reservations": { + "name": "builder_project_snapshot_reservations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "snapshot_hash": { + "name": "snapshot_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "builder_project_snapshot_reservations_owner_created_at_idx": { + "name": "builder_project_snapshot_reservations_owner_created_at_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "builder_project_snapshot_reservations_snapshot_hash_idx": { + "name": "builder_project_snapshot_reservations_snapshot_hash_idx", + "columns": [ + { + "expression": "snapshot_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "builder_project_snapshot_reservations_owner_id_users_id_fk": { + "name": "builder_project_snapshot_reservations_owner_id_users_id_fk", + "tableFrom": "builder_project_snapshot_reservations", + "tableTo": "users", + "columnsFrom": ["owner_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "builder_project_snapshot_reservations_snapshot_hash_builder_project_snapshots_hash_fk": { + "name": "builder_project_snapshot_reservations_snapshot_hash_builder_project_snapshots_hash_fk", + "tableFrom": "builder_project_snapshot_reservations", + "tableTo": "builder_project_snapshots", + "columnsFrom": ["snapshot_hash"], + "columnsTo": ["hash"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "builder_project_snapshot_reservations_owner_snapshot_unique": { + "name": "builder_project_snapshot_reservations_owner_snapshot_unique", + "nullsNotDistinct": false, + "columns": ["owner_id", "snapshot_hash"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.builder_project_snapshots": { + "name": "builder_project_snapshots", + "schema": "", + "columns": { + "hash": { + "name": "hash", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "source_bytes": { + "name": "source_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "stored_at": { + "name": "stored_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "deleting_at": { + "name": "deleting_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "quarantined_at": { + "name": "quarantined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "builder_project_snapshots_stored_at_idx": { + "name": "builder_project_snapshots_stored_at_idx", + "columns": [ + { + "expression": "stored_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "builder_project_snapshots_hash_check": { + "name": "builder_project_snapshots_hash_check", + "value": "\"builder_project_snapshots\".\"hash\" ~ '^[a-f0-9]{64}$'" + }, + "builder_project_snapshots_source_bytes_check": { + "name": "builder_project_snapshots_source_bytes_check", + "value": "\"builder_project_snapshots\".\"source_bytes\" IS NULL OR \"builder_project_snapshots\".\"source_bytes\" BETWEEN 1 AND 1048576" + } + }, + "isRLSEnabled": false + }, + "public.builder_project_threads": { + "name": "builder_project_threads", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "client_mutation_id": { + "name": "client_mutation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "last_message_position": { + "name": "last_message_position", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "builder_project_threads_project_updated_at_idx": { + "name": "builder_project_threads_project_updated_at_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "builder_project_threads_project_owner_fk": { + "name": "builder_project_threads_project_owner_fk", + "tableFrom": "builder_project_threads", + "tableTo": "builder_projects", + "columnsFrom": ["project_id", "owner_id"], + "columnsTo": ["id", "owner_id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "builder_project_threads_project_id_unique": { + "name": "builder_project_threads_project_id_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "id"] + }, + "builder_project_threads_project_mutation_unique": { + "name": "builder_project_threads_project_mutation_unique", + "nullsNotDistinct": false, + "columns": ["project_id", "client_mutation_id"] + } + }, + "policies": {}, + "checkConstraints": { + "builder_project_threads_message_position_check": { + "name": "builder_project_threads_message_position_check", + "value": "\"builder_project_threads\".\"last_message_position\" BETWEEN 0 AND 9007199254740991" + } + }, + "isRLSEnabled": false + }, + "public.builder_project_tombstones": { + "name": "builder_project_tombstones", + "schema": "", + "columns": { + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "builder_project_tombstones_owner_deleted_at_idx": { + "name": "builder_project_tombstones_owner_deleted_at_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deleted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "builder_project_tombstones_owner_id_users_id_fk": { + "name": "builder_project_tombstones_owner_id_users_id_fk", + "tableFrom": "builder_project_tombstones", + "tableTo": "users", + "columnsFrom": ["owner_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.builder_project_usage": { + "name": "builder_project_usage", + "schema": "", + "columns": { + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "threads": { + "name": "threads", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "messages": { + "name": "messages", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "runs": { + "name": "runs", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "revisions": { + "name": "revisions", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "events": { + "name": "events", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "payload_bytes": { + "name": "payload_bytes", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "builder_project_usage_project_id_builder_projects_id_fk": { + "name": "builder_project_usage_project_id_builder_projects_id_fk", + "tableFrom": "builder_project_usage", + "tableTo": "builder_projects", + "columnsFrom": ["project_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "builder_project_usage_nonnegative_check": { + "name": "builder_project_usage_nonnegative_check", + "value": "\"builder_project_usage\".\"threads\" >= 0 AND \"builder_project_usage\".\"messages\" >= 0 AND \"builder_project_usage\".\"runs\" >= 0 AND \"builder_project_usage\".\"revisions\" >= 0 AND \"builder_project_usage\".\"events\" >= 0 AND \"builder_project_usage\".\"payload_bytes\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.builder_projects": { + "name": "builder_projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "client_mutation_id": { + "name": "client_mutation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "forked_from_id": { + "name": "forked_from_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar(1000)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "snapshot_hash": { + "name": "snapshot_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "current_revision_number": { + "name": "current_revision_number", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "last_event_sequence": { + "name": "last_event_sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_lease_fencing_token": { + "name": "last_lease_fencing_token", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "deleted_by_id": { + "name": "deleted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "builder_projects_owner_id_idx": { + "name": "builder_projects_owner_id_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "builder_projects_owner_updated_at_idx": { + "name": "builder_projects_owner_updated_at_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "builder_projects_deleted_at_idx": { + "name": "builder_projects_deleted_at_idx", + "columns": [ + { + "expression": "deleted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "builder_projects_owner_id_users_id_fk": { + "name": "builder_projects_owner_id_users_id_fk", + "tableFrom": "builder_projects", + "tableTo": "users", + "columnsFrom": ["owner_id"], + "columnsTo": ["id"], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "builder_projects_deleted_by_id_users_id_fk": { + "name": "builder_projects_deleted_by_id_users_id_fk", + "tableFrom": "builder_projects", + "tableTo": "users", + "columnsFrom": ["deleted_by_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "builder_projects_forked_from_fk": { + "name": "builder_projects_forked_from_fk", + "tableFrom": "builder_projects", + "tableTo": "builder_projects", + "columnsFrom": ["forked_from_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "builder_projects_snapshot_hash_fk": { + "name": "builder_projects_snapshot_hash_fk", + "tableFrom": "builder_projects", + "tableTo": "builder_project_snapshots", + "columnsFrom": ["snapshot_hash"], + "columnsTo": ["hash"], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "builder_projects_id_owner_unique": { + "name": "builder_projects_id_owner_unique", + "nullsNotDistinct": false, + "columns": ["id", "owner_id"] + }, + "builder_projects_owner_mutation_unique": { + "name": "builder_projects_owner_mutation_unique", + "nullsNotDistinct": false, + "columns": ["owner_id", "client_mutation_id"] + } + }, + "policies": {}, + "checkConstraints": { + "builder_projects_snapshot_hash_check": { + "name": "builder_projects_snapshot_hash_check", + "value": "\"builder_projects\".\"snapshot_hash\" ~ '^[a-f0-9]{64}$'" + }, + "builder_projects_revision_number_check": { + "name": "builder_projects_revision_number_check", + "value": "\"builder_projects\".\"current_revision_number\" > 0" + }, + "builder_projects_event_sequence_check": { + "name": "builder_projects_event_sequence_check", + "value": "\"builder_projects\".\"last_event_sequence\" BETWEEN 0 AND 9007199254740991" + }, + "builder_projects_lease_fencing_token_check": { + "name": "builder_projects_lease_fencing_token_check", + "value": "\"builder_projects\".\"last_lease_fencing_token\" BETWEEN 0 AND 9007199254740991" + } + }, + "isRLSEnabled": false + }, + "public.doc_feedback": { + "name": "doc_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "doc_feedback_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "character_count": { + "name": "character_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "page_path": { + "name": "page_path", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "library_id": { + "name": "library_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "library_version": { + "name": "library_version", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "block_selector": { + "name": "block_selector", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "block_content_hash": { + "name": "block_content_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "block_markdown": { + "name": "block_markdown", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "doc_feedback_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "is_detached": { + "name": "is_detached", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_collapsed": { + "name": "is_collapsed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "moderated_by": { + "name": "moderated_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "moderated_at": { + "name": "moderated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "moderation_note": { + "name": "moderation_note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "doc_feedback_user_id_idx": { + "name": "doc_feedback_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "doc_feedback_status_idx": { + "name": "doc_feedback_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "doc_feedback_library_idx": { + "name": "doc_feedback_library_idx", + "columns": [ + { + "expression": "library_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "doc_feedback_page_path_idx": { + "name": "doc_feedback_page_path_idx", + "columns": [ + { + "expression": "page_path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "doc_feedback_created_at_idx": { + "name": "doc_feedback_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "doc_feedback_is_detached_idx": { + "name": "doc_feedback_is_detached_idx", + "columns": [ + { + "expression": "is_detached", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "doc_feedback_moderated_by_idx": { + "name": "doc_feedback_moderated_by_idx", + "columns": [ + { + "expression": "moderated_by", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "doc_feedback_user_id_users_id_fk": { + "name": "doc_feedback_user_id_users_id_fk", + "tableFrom": "doc_feedback", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "doc_feedback_moderated_by_users_id_fk": { + "name": "doc_feedback_moderated_by_users_id_fk", + "tableFrom": "doc_feedback", + "tableTo": "users", + "columnsFrom": ["moderated_by"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.docs_artifact_cache": { + "name": "docs_artifact_cache", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "repo": { + "name": "repo", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "git_ref": { + "name": "git_ref", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "docs_root": { + "name": "docs_root", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "artifact_type": { + "name": "artifact_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "artifact_key": { + "name": "artifact_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "stale_at": { + "name": "stale_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "docs_artifact_cache_repo_ref_docs_root_idx": { + "name": "docs_artifact_cache_repo_ref_docs_root_idx", + "columns": [ + { + "expression": "repo", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "git_ref", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "docs_root", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "docs_artifact_cache_stale_at_idx": { + "name": "docs_artifact_cache_stale_at_idx", + "columns": [ + { + "expression": "stale_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "docs_artifact_cache_unique": { + "name": "docs_artifact_cache_unique", + "columns": [ + { + "expression": "repo", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "git_ref", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "docs_root", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "artifact_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "artifact_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.github_content_cache": { + "name": "github_content_cache", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "repo": { + "name": "repo", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "git_ref": { + "name": "git_ref", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "content_kind": { + "name": "content_kind", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar(1024)", + "primaryKey": false, + "notNull": true + }, + "is_present": { + "name": "is_present", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "text_content": { + "name": "text_content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "json_content": { + "name": "json_content", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "stale_at": { + "name": "stale_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "github_content_cache_repo_ref_idx": { + "name": "github_content_cache_repo_ref_idx", + "columns": [ + { + "expression": "repo", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "git_ref", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "github_content_cache_stale_at_idx": { + "name": "github_content_cache_stale_at_idx", + "columns": [ + { + "expression": "stale_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "github_content_cache_unique": { + "name": "github_content_cache_unique", + "columns": [ + { + "expression": "repo", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "git_ref", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "content_kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.github_stats_cache": { + "name": "github_stats_cache", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "stats": { + "name": "stats", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "previous_stats": { + "name": "previous_stats", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "github_stats_cache_key_idx": { + "name": "github_stats_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "github_stats_cache_expires_at_idx": { + "name": "github_stats_cache_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "github_stats_cache_cache_key_unique": { + "name": "github_stats_cache_cache_key_unique", + "nullsNotDistinct": false, + "columns": ["cache_key"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.intent_package_versions": { + "name": "intent_package_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "intent_package_versions_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "package_name": { + "name": "package_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "skill_count": { + "name": "skill_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "tarball_url": { + "name": "tarball_url", + "type": "varchar(1024)", + "primaryKey": false, + "notNull": false + }, + "sync_status": { + "name": "sync_status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "synced_at": { + "name": "synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failure_reason": { + "name": "failure_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "intent_package_versions_package_name_idx": { + "name": "intent_package_versions_package_name_idx", + "columns": [ + { + "expression": "package_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "intent_package_versions_sync_status_idx": { + "name": "intent_package_versions_sync_status_idx", + "columns": [ + { + "expression": "sync_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "intent_package_versions_package_version_unique": { + "name": "intent_package_versions_package_version_unique", + "columns": [ + { + "expression": "package_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "intent_package_versions_package_name_intent_packages_name_fk": { + "name": "intent_package_versions_package_name_intent_packages_name_fk", + "tableFrom": "intent_package_versions", + "tableTo": "intent_packages", + "columnsFrom": ["package_name"], + "columnsTo": ["name"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.intent_packages": { + "name": "intent_packages", + "schema": "", + "columns": { + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "verified": { + "name": "verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.intent_skill_content": { + "name": "intent_skill_content", + "schema": "", + "columns": { + "content_hash": { + "name": "content_hash", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.intent_skills": { + "name": "intent_skills", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "intent_skills_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "package_version_id": { + "name": "package_version_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "framework": { + "name": "framework", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "requires": { + "name": "requires", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "skill_path": { + "name": "skill_path", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "content_hash": { + "name": "content_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "line_count": { + "name": "line_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "intent_skills_package_version_id_idx": { + "name": "intent_skills_package_version_id_idx", + "columns": [ + { + "expression": "package_version_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "intent_skills_name_idx": { + "name": "intent_skills_name_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "intent_skills_framework_idx": { + "name": "intent_skills_framework_idx", + "columns": [ + { + "expression": "framework", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "intent_skills_type_idx": { + "name": "intent_skills_type_idx", + "columns": [ + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "intent_skills_package_version_skill_unique": { + "name": "intent_skills_package_version_skill_unique", + "columns": [ + { + "expression": "package_version_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "intent_skills_package_version_id_intent_package_versions_id_fk": { + "name": "intent_skills_package_version_id_intent_package_versions_id_fk", + "tableFrom": "intent_skills", + "tableTo": "intent_package_versions", + "columnsFrom": ["package_version_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "intent_skills_content_hash_intent_skill_content_content_hash_fk": { + "name": "intent_skills_content_hash_intent_skill_content_content_hash_fk", + "tableFrom": "intent_skills", + "tableTo": "intent_skill_content", + "columnsFrom": ["content_hash"], + "columnsTo": ["content_hash"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.login_history": { + "name": "login_history", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "oauth_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(45)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_new_user": { + "name": "is_new_user", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "login_history_user_id_idx": { + "name": "login_history_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "login_history_created_at_idx": { + "name": "login_history_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "login_history_provider_idx": { + "name": "login_history_provider_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "login_history_user_id_users_id_fk": { + "name": "login_history_user_id_users_id_fk", + "tableFrom": "login_history", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mcp_api_keys": { + "name": "mcp_api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "key_hash": { + "name": "key_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "key_prefix": { + "name": "key_prefix", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "rate_limit_per_minute": { + "name": "rate_limit_per_minute", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 200 + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "mcp_api_keys_key_hash_idx": { + "name": "mcp_api_keys_key_hash_idx", + "columns": [ + { + "expression": "key_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "mcp_api_keys_user_id_idx": { + "name": "mcp_api_keys_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "mcp_api_keys_is_active_idx": { + "name": "mcp_api_keys_is_active_idx", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "mcp_api_keys_user_id_users_id_fk": { + "name": "mcp_api_keys_user_id_users_id_fk", + "tableFrom": "mcp_api_keys", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "mcp_api_keys_key_hash_unique": { + "name": "mcp_api_keys_key_hash_unique", + "nullsNotDistinct": false, + "columns": ["key_hash"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mcp_rate_limits": { + "name": "mcp_rate_limits", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "identifier": { + "name": "identifier", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "identifier_type": { + "name": "identifier_type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "window_start": { + "name": "window_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + } + }, + "indexes": { + "mcp_rate_limits_identifier_window_unique": { + "name": "mcp_rate_limits_identifier_window_unique", + "columns": [ + { + "expression": "identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "window_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "mcp_rate_limits_identifier_idx": { + "name": "mcp_rate_limits_identifier_idx", + "columns": [ + { + "expression": "identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "mcp_rate_limits_window_start_idx": { + "name": "mcp_rate_limits_window_start_idx", + "columns": [ + { + "expression": "window_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.npm_download_chunks": { + "name": "npm_download_chunks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "package_name": { + "name": "package_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "date_from": { + "name": "date_from", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "date_to": { + "name": "date_to", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "bin_size": { + "name": "bin_size", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'daily'" + }, + "total_downloads": { + "name": "total_downloads", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "daily_data": { + "name": "daily_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "is_immutable": { + "name": "is_immutable", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "npm_download_chunks_package_date_bin_unique": { + "name": "npm_download_chunks_package_date_bin_unique", + "columns": [ + { + "expression": "package_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "date_from", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "date_to", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "bin_size", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "npm_download_chunks_package_name_idx": { + "name": "npm_download_chunks_package_name_idx", + "columns": [ + { + "expression": "package_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "npm_download_chunks_date_from_idx": { + "name": "npm_download_chunks_date_from_idx", + "columns": [ + { + "expression": "date_from", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "npm_download_chunks_date_to_idx": { + "name": "npm_download_chunks_date_to_idx", + "columns": [ + { + "expression": "date_to", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "npm_download_chunks_expires_at_idx": { + "name": "npm_download_chunks_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "npm_download_chunks_is_immutable_idx": { + "name": "npm_download_chunks_is_immutable_idx", + "columns": [ + { + "expression": "is_immutable", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oauth_mcp_access_tokens": { + "name": "oauth_mcp_access_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "token_hash": { + "name": "token_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'api'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "oauth_mcp_access_tokens_hash_idx": { + "name": "oauth_mcp_access_tokens_hash_idx", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "oauth_mcp_access_tokens_user_idx": { + "name": "oauth_mcp_access_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "oauth_mcp_access_tokens_expires_idx": { + "name": "oauth_mcp_access_tokens_expires_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "oauth_mcp_access_tokens_user_id_users_id_fk": { + "name": "oauth_mcp_access_tokens_user_id_users_id_fk", + "tableFrom": "oauth_mcp_access_tokens", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_mcp_access_tokens_token_hash_unique": { + "name": "oauth_mcp_access_tokens_token_hash_unique", + "nullsNotDistinct": false, + "columns": ["token_hash"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oauth_accounts": { + "name": "oauth_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "oauth_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_scope": { + "name": "token_scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "oauth_accounts_user_id_idx": { + "name": "oauth_accounts_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "oauth_accounts_provider_account_unique": { + "name": "oauth_accounts_provider_account_unique", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "oauth_accounts_provider_account_idx": { + "name": "oauth_accounts_provider_account_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "oauth_accounts_user_id_users_id_fk": { + "name": "oauth_accounts_user_id_users_id_fk", + "tableFrom": "oauth_accounts", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oauth_mcp_authorization_codes": { + "name": "oauth_mcp_authorization_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "code_hash": { + "name": "code_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "redirect_uri": { + "name": "redirect_uri", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "code_challenge": { + "name": "code_challenge", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "code_challenge_method": { + "name": "code_challenge_method", + "type": "varchar(8)", + "primaryKey": false, + "notNull": true, + "default": "'S256'" + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'api'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "oauth_mcp_auth_codes_hash_idx": { + "name": "oauth_mcp_auth_codes_hash_idx", + "columns": [ + { + "expression": "code_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "oauth_mcp_auth_codes_expires_idx": { + "name": "oauth_mcp_auth_codes_expires_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "oauth_mcp_authorization_codes_user_id_users_id_fk": { + "name": "oauth_mcp_authorization_codes_user_id_users_id_fk", + "tableFrom": "oauth_mcp_authorization_codes", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_mcp_authorization_codes_code_hash_unique": { + "name": "oauth_mcp_authorization_codes_code_hash_unique", + "nullsNotDistinct": false, + "columns": ["code_hash"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oauth_mcp_refresh_tokens": { + "name": "oauth_mcp_refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "token_hash": { + "name": "token_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "access_token_id": { + "name": "access_token_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "oauth_mcp_refresh_tokens_hash_idx": { + "name": "oauth_mcp_refresh_tokens_hash_idx", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "oauth_mcp_refresh_tokens_user_idx": { + "name": "oauth_mcp_refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "oauth_mcp_refresh_tokens_user_id_users_id_fk": { + "name": "oauth_mcp_refresh_tokens_user_id_users_id_fk", + "tableFrom": "oauth_mcp_refresh_tokens", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "oauth_mcp_refresh_tokens_access_token_id_oauth_mcp_access_tokens_id_fk": { + "name": "oauth_mcp_refresh_tokens_access_token_id_oauth_mcp_access_tokens_id_fk", + "tableFrom": "oauth_mcp_refresh_tokens", + "tableTo": "oauth_mcp_access_tokens", + "columnsFrom": ["access_token_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_mcp_refresh_tokens_token_hash_unique": { + "name": "oauth_mcp_refresh_tokens_token_hash_unique", + "nullsNotDistinct": false, + "columns": ["token_hash"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oss_stats_cache": { + "name": "oss_stats_cache", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "scope_type": { + "name": "scope_type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "scope_key": { + "name": "scope_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "github_star_count": { + "name": "github_star_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "github_contributor_count": { + "name": "github_contributor_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "github_dependent_count": { + "name": "github_dependent_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "github_fork_count": { + "name": "github_fork_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "github_repository_count": { + "name": "github_repository_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "github_delta_star_count": { + "name": "github_delta_star_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "github_delta_contributor_count": { + "name": "github_delta_contributor_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "github_delta_dependent_count": { + "name": "github_delta_dependent_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "github_delta_fork_count": { + "name": "github_delta_fork_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "github_updated_at": { + "name": "github_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "npm_total_downloads": { + "name": "npm_total_downloads", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "npm_rate_per_day": { + "name": "npm_rate_per_day", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "npm_package_count": { + "name": "npm_package_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "npm_updated_at": { + "name": "npm_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "time_delta_ms": { + "name": "time_delta_ms", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "oss_stats_cache_scope_unique": { + "name": "oss_stats_cache_scope_unique", + "columns": [ + { + "expression": "scope_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "oss_stats_cache_scope_type_idx": { + "name": "oss_stats_cache_scope_type_idx", + "columns": [ + { + "expression": "scope_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "oss_stats_cache_scope_key_idx": { + "name": "oss_stats_cache_scope_key_idx", + "columns": [ + { + "expression": "scope_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.role_assignments": { + "name": "role_assignments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "role_assignments_user_id_idx": { + "name": "role_assignments_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "role_assignments_role_id_idx": { + "name": "role_assignments_role_id_idx", + "columns": [ + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "role_assignments_user_role_unique": { + "name": "role_assignments_user_role_unique", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "role_assignments_user_id_users_id_fk": { + "name": "role_assignments_user_id_users_id_fk", + "tableFrom": "role_assignments", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "role_assignments_role_id_roles_id_fk": { + "name": "role_assignments_role_id_roles_id_fk", + "tableFrom": "role_assignments", + "tableTo": "roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.roles": { + "name": "roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "capabilities": { + "name": "capabilities", + "type": "capability[]", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "roles_name_idx": { + "name": "roles_name_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "roles_name_unique": { + "name": "roles_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sessions": { + "name": "sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "token": { + "name": "token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(45)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "sessions_token_idx": { + "name": "sessions_token_idx", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_user_id_idx": { + "name": "sessions_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_expires_at_idx": { + "name": "sessions_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sessions_token_unique": { + "name": "sessions_token_unique", + "nullsNotDistinct": false, + "columns": ["token"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.showcase_votes": { + "name": "showcase_votes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "showcase_id": { + "name": "showcase_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "showcase_votes_showcase_id_idx": { + "name": "showcase_votes_showcase_id_idx", + "columns": [ + { + "expression": "showcase_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "showcase_votes_user_id_idx": { + "name": "showcase_votes_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "showcase_votes_showcase_id_showcases_id_fk": { + "name": "showcase_votes_showcase_id_showcases_id_fk", + "tableFrom": "showcase_votes", + "tableTo": "showcases", + "columnsFrom": ["showcase_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "showcase_votes_user_id_users_id_fk": { + "name": "showcase_votes_user_id_users_id_fk", + "tableFrom": "showcase_votes", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "showcase_votes_showcase_id_user_id_unique": { + "name": "showcase_votes_showcase_id_user_id_unique", + "nullsNotDistinct": false, + "columns": ["showcase_id", "user_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.showcases": { + "name": "showcases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "tagline": { + "name": "tagline", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "logo_url": { + "name": "logo_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "screenshot_url": { + "name": "screenshot_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_url": { + "name": "source_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "libraries": { + "name": "libraries", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "use_cases": { + "name": "use_cases", + "type": "showcase_use_case[]", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "is_featured": { + "name": "is_featured", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "status": { + "name": "status", + "type": "showcase_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "placement": { + "name": "placement", + "type": "showcase_placement", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'private'" + }, + "review_reason": { + "name": "review_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "moderated_by": { + "name": "moderated_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "moderated_at": { + "name": "moderated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "moderation_note": { + "name": "moderation_note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tranco_rank": { + "name": "tranco_rank", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "tranco_rank_updated_at": { + "name": "tranco_rank_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "vote_score": { + "name": "vote_score", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "showcases_user_id_idx": { + "name": "showcases_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "showcases_status_idx": { + "name": "showcases_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "showcases_status_placement_idx": { + "name": "showcases_status_placement_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "placement", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "showcases_is_featured_idx": { + "name": "showcases_is_featured_idx", + "columns": [ + { + "expression": "is_featured", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "showcases_created_at_idx": { + "name": "showcases_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "showcases_moderated_by_idx": { + "name": "showcases_moderated_by_idx", + "columns": [ + { + "expression": "moderated_by", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "showcases_tranco_rank_idx": { + "name": "showcases_tranco_rank_idx", + "columns": [ + { + "expression": "tranco_rank", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "showcases_vote_score_idx": { + "name": "showcases_vote_score_idx", + "columns": [ + { + "expression": "vote_score", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "showcases_user_id_users_id_fk": { + "name": "showcases_user_id_users_id_fk", + "tableFrom": "showcases", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "showcases_moderated_by_users_id_fk": { + "name": "showcases_moderated_by_users_id_fk", + "tableFrom": "showcases", + "tableTo": "users", + "columnsFrom": ["moderated_by"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_activity": { + "name": "user_activity", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "date": { + "name": "date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_activity_user_date_unique": { + "name": "user_activity_user_date_unique", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "date", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_activity_user_id_idx": { + "name": "user_activity_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_activity_date_idx": { + "name": "user_activity_date_idx", + "columns": [ + { + "expression": "date", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_activity_user_id_users_id_fk": { + "name": "user_activity_user_id_users_id_fk", + "tableFrom": "user_activity", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "oauth_image": { + "name": "oauth_image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "capabilities": { + "name": "capabilities", + "type": "capability[]", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "ads_disabled": { + "name": "ads_disabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "interested_in_hiding_ads": { + "name": "interested_in_hiding_ads", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "last_used_framework": { + "name": "last_used_framework", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "signup_sources": { + "name": "signup_sources", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "session_version": { + "name": "session_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_idx": { + "name": "users_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_created_at_idx": { + "name": "users_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": ["email"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.audit_action": { + "name": "audit_action", + "schema": "public", + "values": [ + "user.capabilities.update", + "user.adsDisabled.update", + "user.sessions.revoke", + "role.create", + "role.update", + "role.delete", + "role.assignment.create", + "role.assignment.delete", + "feedback.moderate", + "showcase.create", + "showcase.update", + "showcase.delete", + "showcase.moderate" + ] + }, + "public.builder_message_role": { + "name": "builder_message_role", + "schema": "public", + "values": ["user", "assistant"] + }, + "public.builder_project_event_type": { + "name": "builder_project_event_type", + "schema": "public", + "values": [ + "project.created", + "project.updated", + "project.deleted", + "thread.created", + "thread.updated", + "thread.archived", + "revision.created", + "message.created", + "message.updated", + "message.deleted", + "run.created", + "run.started", + "run.activity", + "run.interrupted", + "run.completed", + "run.failed", + "run.cancelled" + ] + }, + "public.builder_run_status": { + "name": "builder_run_status", + "schema": "public", + "values": [ + "pending", + "running", + "interrupted", + "completed", + "failed", + "cancelled" + ] + }, + "public.capability": { + "name": "capability", + "schema": "public", + "values": [ + "admin", + "api-keys", + "disableAds", + "builder", + "mcp", + "moderate-feedback", + "moderate-showcases" + ] + }, + "public.doc_feedback_status": { + "name": "doc_feedback_status", + "schema": "public", + "values": ["pending", "approved", "denied"] + }, + "public.doc_feedback_type": { + "name": "doc_feedback_type", + "schema": "public", + "values": ["note", "improvement"] + }, + "public.oauth_provider": { + "name": "oauth_provider", + "schema": "public", + "values": ["github", "google"] + }, + "public.showcase_placement": { + "name": "showcase_placement", + "schema": "public", + "values": ["showcase", "community", "private"] + }, + "public.showcase_status": { + "name": "showcase_status", + "schema": "public", + "values": ["pending", "approved", "denied"] + }, + "public.showcase_use_case": { + "name": "showcase_use_case", + "schema": "public", + "values": [ + "blog", + "e-commerce", + "saas", + "dashboard", + "documentation", + "portfolio", + "social", + "developer-tool", + "marketing", + "media", + "open-source" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/drizzle/migrations/meta/_journal.json b/drizzle/migrations/meta/_journal.json index cf6b8d599..16d84a419 100644 --- a/drizzle/migrations/meta/_journal.json +++ b/drizzle/migrations/meta/_journal.json @@ -8,6 +8,13 @@ "when": 1787266378167, "tag": "0000_builder_durability", "breakpoints": true + }, + { + "idx": 1, + "version": "7", + "when": 1789144581608, + "tag": "0001_showcase_placements", + "breakpoints": true } ] } diff --git a/scripts/apply-showcase-review.ts b/scripts/apply-showcase-review.ts new file mode 100644 index 000000000..cc24965a2 --- /dev/null +++ b/scripts/apply-showcase-review.ts @@ -0,0 +1,167 @@ +import { readFile } from 'node:fs/promises' +import { parseArgs } from 'node:util' +import postgres from 'postgres' +import * as v from 'valibot' + +const { values } = parseArgs({ + options: { + plan: { + type: 'string', + default: 'docs/showcase-review/placement-plan.json', + }, + apply: { type: 'boolean', default: false }, + 'actor-id': { type: 'string' }, + }, +}) +const decisionSchema = v.object({ + id: v.pipe(v.string(), v.uuid()), + name: v.string(), + url: v.string(), + previousStatus: v.picklist(['pending', 'approved', 'denied']), + placement: v.picklist(['showcase', 'community', 'private']), + reviewedAt: v.pipe( + v.string(), + v.check( + (value) => Number.isFinite(Date.parse(value)), + 'Invalid review date', + ), + ), + reason: v.pipe(v.string(), v.trim(), v.minLength(1)), + notes: v.string(), + holdReason: v.nullable(v.string()), +}) +const plan = v.parse( + v.array(decisionSchema), + JSON.parse(await readFile(values.plan, 'utf8')), +) +if (new Set(plan.map((item) => item.id)).size !== plan.length) + throw new Error('Duplicate submission IDs in plan') +if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is required') +const actorId = values.apply + ? v.parse(v.pipe(v.string(), v.uuid()), values['actor-id']) + : null +const sql = postgres(process.env.DATABASE_URL, { max: 1 }) +try { + await sql.begin(async (tx) => { + if (actorId) { + const [rawActor] = await tx.unsafe( + `SELECT EXISTS ( + SELECT 1 FROM users WHERE id = $1 AND ( + capabilities && ARRAY['admin', 'moderate-showcases']::capability[] OR + EXISTS (SELECT 1 FROM role_assignments a JOIN roles r ON r.id = a.role_id + WHERE a.user_id = users.id AND r.capabilities && ARRAY['admin', 'moderate-showcases']::capability[]) + )) AS allowed`, + [actorId], + ) + const actor = v.parse(v.object({ allowed: v.boolean() }), rawActor) + if (!actor.allowed) + throw new Error('The actor must have showcase moderation permission') + } + let ready = 0 + let unchanged = 0 + const blocked: { id: string; name: string; reason: string }[] = [] + for (const item of plan) { + if (item.holdReason) { + blocked.push({ id: item.id, name: item.name, reason: item.holdReason }) + continue + } + const [raw] = await tx.unsafe( + 'SELECT * FROM showcases WHERE id = $1 FOR UPDATE', + [item.id], + ) + if (!raw) { + blocked.push({ + id: item.id, + name: item.name, + reason: 'Submission is missing', + }) + continue + } + const row = v.parse( + v.object({ + name: v.string(), + url: v.string(), + status: v.string(), + placement: v.string(), + review_reason: v.nullable(v.string()), + updated_at: v.date(), + }), + raw, + ) + const status = + item.placement === 'private' + ? item.previousStatus === 'approved' + ? 'approved' + : 'denied' + : 'approved' + if ( + row.placement === item.placement && + row.status === status && + row.review_reason === item.reason + ) { + unchanged++ + continue + } + if ( + row.name !== item.name || + new URL(row.url).href !== new URL(item.url).href || + row.status !== item.previousStatus || + row.updated_at > new Date(item.reviewedAt) + ) { + blocked.push({ + id: item.id, + name: item.name, + reason: + 'Submission changed since review, review the current version first', + }) + continue + } + ready++ + if (actorId) { + const [after] = await tx.unsafe( + `UPDATE showcases SET + status = $1, placement = $2::showcase_placement, review_reason = $3, + moderation_note = $4, moderated_at = $5, moderated_by = $6, + is_featured = CASE WHEN $2::showcase_placement = 'showcase' THEN is_featured ELSE false END, + updated_at = now() WHERE id = $7 RETURNING *`, + [ + status, + item.placement, + item.reason, + item.notes, + item.reviewedAt, + actorId, + item.id, + ], + ) + await tx.unsafe( + `INSERT INTO audit_logs (actor_id, action, target_type, target_id, details) + VALUES ($1, 'showcase.moderate', 'showcase', $2, $3::jsonb)`, + [ + actorId, + item.id, + JSON.stringify({ + source: 'showcase-review-migration', + before: raw, + after, + }), + ], + ) + } + } + console.log( + JSON.stringify( + { mode: values.apply ? 'apply' : 'preview', ready, unchanged, blocked }, + null, + 2, + ), + ) + // Any stale record aborts the entire apply, so a partial batch cannot go unnoticed. + if (values.apply && blocked.length) + throw new Error( + 'Nothing applied. Resolve held or changed entries, or supply an explicitly narrowed plan.', + ) + }) +} finally { + await sql.end() +} diff --git a/src/components/ClientAuth.tsx b/src/components/ClientAuth.tsx index 27cf15d50..ecb8a5930 100644 --- a/src/components/ClientAuth.tsx +++ b/src/components/ClientAuth.tsx @@ -3,7 +3,7 @@ import React from 'react' import { Spinner } from '~/components/Spinner' import { SignInForm } from '~/routes/login' import { useCurrentUserQuery } from '~/hooks/useCurrentUser' -import { hasCapability } from '~/db/types' +import { hasCapability, ADMIN_ACCESS_CAPABILITIES } from '~/db/types' const baseClasses = 'p-4 flex flex-col items-center justify-center gap-4' @@ -64,7 +64,9 @@ export function ClientAdminAuth({ children }: { children: React.ReactNode }) { } const capabilities = userQuery.data?.capabilities || [] - const canAdmin = hasCapability(capabilities, 'admin') + const canAdmin = ADMIN_ACCESS_CAPABILITIES.some((capability) => + hasCapability(capabilities, capability), + ) if (!canAdmin) { return ( diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index bf6840859..f50aca7d9 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -44,6 +44,7 @@ const FOOTER_COLUMNS: Array = [ { label: 'GitHub', to: 'https://github.com/TanStack' }, { label: 'Maintainers', to: '/maintainers' }, { label: 'Showcase', to: '/showcase' }, + { label: 'Community projects', to: '/community-projects' }, ], }, { diff --git a/src/components/ImageUpload.tsx b/src/components/ImageUpload.tsx index c570960e8..cee6d9435 100644 --- a/src/components/ImageUpload.tsx +++ b/src/components/ImageUpload.tsx @@ -1,11 +1,14 @@ import * as React from 'react' +import { createClientOnlyFn } from '@tanstack/react-start' import { ClientOnly } from '@tanstack/react-router' import type { ImageUploadProps } from './ImageUpload.client' -const LazyImageUploadClient = React.lazy(() => - import('./ImageUpload.client').then((m) => ({ - default: m.ImageUploadClient, - })), +const LazyImageUploadClient = React.lazy( + createClientOnlyFn(() => + import('./ImageUpload.client').then((m) => ({ + default: m.ImageUploadClient, + })), + ), ) export type { ImageUploadProps } diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 4931d7a7d..daefde3d4 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -215,9 +215,14 @@ const NAV_GROUPS = [ { label: 'Showcase', to: '/showcase', - description: 'Teams building with TanStack.', + description: 'Projects selected by the TanStack team.', icon: SparkleIcon, }, + { + label: 'Community projects', + to: '/community-projects', + icon: CodeIcon, + }, ], }, ], diff --git a/src/components/ShowcaseCard.tsx b/src/components/ShowcaseCard.tsx index 371329320..a1c62cd36 100644 --- a/src/components/ShowcaseCard.tsx +++ b/src/components/ShowcaseCard.tsx @@ -1,3 +1,4 @@ +import { showcaseLinkRel } from '~/utils/showcase.shared' import { Link } from '@tanstack/react-router' import { twMerge } from 'tailwind-merge' import { @@ -7,10 +8,10 @@ import { CodeIcon, } from '@phosphor-icons/react' import { libraries, type LibraryId } from '~/libraries' -import type { Showcase } from '~/db/types' +import type { PublicShowcase } from '~/db/types' interface ShowcaseCardProps { - showcase: Showcase + showcase: PublicShowcase user?: { id: string name: string | null @@ -87,7 +88,7 @@ export function ShowcaseCard({ e.stopPropagation()} className="p-2 rounded-full bg-white/90 dark:bg-gray-800/90 shadow-sm hover:bg-white dark:hover:bg-gray-700 transition-colors" title="View source code" @@ -98,7 +99,7 @@ export function ShowcaseCard({ e.stopPropagation()} className="p-2 rounded-full bg-white/90 dark:bg-gray-800/90 shadow-sm hover:bg-white dark:hover:bg-gray-700 transition-colors" title="Visit site" diff --git a/src/components/ShowcaseDetail.tsx b/src/components/ShowcaseDetail.tsx index ecce3f4cb..a369d4d14 100644 --- a/src/components/ShowcaseDetail.tsx +++ b/src/components/ShowcaseDetail.tsx @@ -1,3 +1,4 @@ +import { showcaseLinkRel, isPublicShowcase } from '~/utils/showcase.shared' import * as React from 'react' import { Link } from '@tanstack/react-router' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' @@ -224,11 +225,17 @@ export function ShowcaseDetail({ showcaseId }: ShowcaseDetailProps) {
{/* Back link */} - Back to Showcase Gallery + {showcase.placement === 'community' + ? 'Back to Community projects' + : 'Back to Showcase'} {/* Hero Screenshot */} @@ -265,7 +272,7 @@ export function ShowcaseDetail({ showcaseId }: ShowcaseDetailProps) { as="a" href={showcase.sourceUrl} target="_blank" - rel="noopener noreferrer" + rel={showcaseLinkRel(showcase)} className="px-4 py-2 text-sm" > View Source @@ -276,7 +283,7 @@ export function ShowcaseDetail({ showcaseId }: ShowcaseDetailProps) { as="a" href={showcase.url} target="_blank" - rel="noopener noreferrer" + rel={showcaseLinkRel(showcase)} className="px-4 py-2 text-sm bg-gray-900 dark:bg-white text-white dark:text-gray-900 border-gray-900 dark:border-white hover:bg-gray-700 dark:hover:bg-gray-200" > Visit Site @@ -336,61 +343,63 @@ export function ShowcaseDetail({ showcaseId }: ShowcaseDetailProps) { )} {/* Voting */} -
- - Rate this project - -
- - - 0 - ? 'text-emerald-600 dark:text-emerald-400' - : 'text-gray-500 dark:text-gray-400', - )} - > - {displayScore} + {isPublicShowcase(showcase) && ( +
+ + Rate this project +
+ - + 0 + ? 'text-emerald-600 dark:text-emerald-400' + : 'text-gray-500 dark:text-gray-400', + )} + > + {displayScore} + + + +
-
+ )} {/* Related Projects */} {relatedData?.showcases && relatedData.showcases.length > 0 && ( diff --git a/src/components/ShowcaseGallery.tsx b/src/components/ShowcaseGallery.tsx index 269129a77..bec8f058c 100644 --- a/src/components/ShowcaseGallery.tsx +++ b/src/components/ShowcaseGallery.tsx @@ -18,9 +18,15 @@ import { useLoginModal } from '~/contexts/LoginModalContext' import type { LibraryId } from '~/libraries' import { PAGE_SIZE_OPTIONS } from '~/routes/showcase' -export function ShowcaseGallery() { - const navigate = useNavigate({ from: '/showcase/' }) - const search = useSearch({ from: '/showcase/' }) +export function ShowcaseGallery({ + community = false, +}: { + community?: boolean +}) { + const from = community ? '/community-projects' : '/showcase/' + const placement = community ? 'community' : 'showcase' + const navigate = useNavigate({ from }) + const search = useSearch({ from }) const queryClient = useQueryClient() const currentUser = useCurrentUser() const { openLoginModal } = useLoginModal() @@ -34,8 +40,9 @@ export function ShowcaseGallery() { pageSize, }, filters: { + placement, libraryIds: search.libraryIds, - useCases: search.useCases as ShowcaseUseCase[], + useCases: search.useCases, hasSourceCode: search.hasSourceCode, q: search.q, }, @@ -74,8 +81,10 @@ export function ShowcaseGallery() { getApprovedShowcasesQueryOptions({ pagination: { page: search.page, pageSize }, filters: { + placement, libraryIds: search.libraryIds, - useCases: search.useCases as ShowcaseUseCase[], + useCases: search.useCases, + hasSourceCode: search.hasSourceCode, q: search.q, }, }).queryKey, @@ -118,8 +127,10 @@ export function ShowcaseGallery() { getApprovedShowcasesQueryOptions({ pagination: { page: search.page, pageSize }, filters: { + placement, libraryIds: search.libraryIds, - useCases: search.useCases as ShowcaseUseCase[], + useCases: search.useCases, + hasSourceCode: search.hasSourceCode, q: search.q, }, }).queryKey, @@ -159,8 +170,10 @@ export function ShowcaseGallery() { getApprovedShowcasesQueryOptions({ pagination: { page: search.page, pageSize }, filters: { + placement, libraryIds: search.libraryIds, - useCases: search.useCases as ShowcaseUseCase[], + useCases: search.useCases, + hasSourceCode: search.hasSourceCode, q: search.q, }, }).queryKey, @@ -300,20 +313,31 @@ export function ShowcaseGallery() {

- Showcase + {community ? 'Community projects' : 'Showcase'}

-

- Discover projects built with TanStack libraries -

+ {!community && ( +

+ Selected by the TanStack team for their adoption, craft, and + technical depth. +

+ )} +
+
+ + {community ? 'Showcase' : 'Community projects'} + +
-
@@ -324,7 +348,7 @@ export function ShowcaseGallery() { void onPageSizeChange: (pageSize: number) => void - onModerate: ( - showcaseId: string, - action: 'approve' | 'deny', - note?: string, - ) => void onToggleFeatured: (showcaseId: string, isFeatured: boolean) => void onDelete: (showcaseId: string) => void onVote: (showcaseId: string, value: 1 | -1) => void @@ -73,17 +66,12 @@ export function ShowcaseModerationList({ pageSize, onPageChange, onPageSizeChange, - onModerate, onToggleFeatured, onDelete, onVote, isModeratingId, }: ShowcaseModerationListProps) { const [expandedIds, setExpandedIds] = useState>(new Set()) - const [moderationNotes, setModerationNotes] = useState< - Record - >({}) - const toggleExpanded = (id: string) => { setExpandedIds((prev) => { const next = new Set(prev) @@ -96,30 +84,12 @@ export function ShowcaseModerationList({ }) } - const handleModerationNoteChange = (showcaseId: string, note: string) => { - setModerationNotes((prev) => ({ ...prev, [showcaseId]: note })) - } - - const handleModerate = (showcaseId: string, action: 'approve' | 'deny') => { - const note = moderationNotes[showcaseId] - onModerate(showcaseId, action, note) - setModerationNotes((prev) => { - const next = { ...prev } - delete next[showcaseId] - return next - }) - } - - if (error) { + if (error) return ( -
-

- Failed to load showcases: {error.message} -

-
+

+ Failed to load projects: {error.message} +

) - } - const showcaseList = data?.showcases || [] const pagination = data?.pagination || { page: 1, @@ -128,39 +98,6 @@ export function ShowcaseModerationList({ totalPages: 0, } - // Compute display rank for approved showcases based on actual display order: - // 1. Featured first, 2. Vote score desc, 3. Tranco rank asc (nulls last), 4. Created date desc - const approvedShowcases = showcaseList - .filter((e) => e.showcase.status === 'approved') - .sort((a, b) => { - // Featured first - if (a.showcase.isFeatured !== b.showcase.isFeatured) { - return a.showcase.isFeatured ? -1 : 1 - } - // Vote score desc - if (a.showcase.voteScore !== b.showcase.voteScore) { - return b.showcase.voteScore - a.showcase.voteScore - } - // Tranco rank asc (nulls last) - const aRank = a.showcase.trancoRank - const bRank = b.showcase.trancoRank - if (aRank !== bRank) { - if (aRank === null) return 1 - if (bRank === null) return -1 - return aRank - bRank - } - // Created date desc - return ( - new Date(b.showcase.createdAt).getTime() - - new Date(a.showcase.createdAt).getTime() - ) - }) - - const displayRankMap = new Map() - approvedShowcases.forEach((entry, index) => { - displayRankMap.set(entry.showcase.id, index + 1) - }) - if (isLoading) { return (
@@ -194,7 +131,6 @@ export function ShowcaseModerationList({ Libraries Featured Votes - Display Tranco Date Actions @@ -206,11 +142,6 @@ export function ShowcaseModerationList({ const isExpanded = expandedIds.has(showcase.id) const isPending = showcase.status === 'pending' const isModeratingThis = isModeratingId === showcase.id - const moderationNoteId = getRowFieldId( - 'showcase-moderation', - showcase.id, - 'note', - ) return ( @@ -257,6 +188,9 @@ export function ShowcaseModerationList({ > {showcase.status.charAt(0).toUpperCase() + showcase.status.slice(1)} + + {PLACEMENT_LABELS[showcase.placement]} + @@ -344,15 +278,6 @@ export function ShowcaseModerationList({
- - {showcase.status === 'approved' ? ( - - #{displayRankMap.get(showcase.id)} - - ) : ( - - - )} - {showcase.trancoRank ? `#${showcase.trancoRank.toLocaleString()}` @@ -366,30 +291,13 @@ export function ShowcaseModerationList({
Processing...
) : (
- {showcase.status !== 'approved' && ( - - )} - {showcase.status !== 'denied' && ( - - )} + + Review +