@freema/drobek-modules 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +53 -0
- package/dist/chunk-WHKPW5MP.js +6611 -0
- package/dist/index.d.ts +1604 -0
- package/dist/index.js +373 -0
- package/dist/mail-guard.d-BKJhsVA2.d.ts +2097 -0
- package/dist/migrations/core/0000_dusty_scarecrow.sql +84 -0
- package/dist/migrations/core/0001_busy_orphan.sql +69 -0
- package/dist/migrations/core/0002_odd_alex_power.sql +17 -0
- package/dist/migrations/core/0003_nosy_shatterstar.sql +26 -0
- package/dist/migrations/core/0004_nice_ben_parker.sql +27 -0
- package/dist/migrations/core/0005_panoramic_bill_hollister.sql +4 -0
- package/dist/migrations/core/0006_outgoing_ricochet.sql +29 -0
- package/dist/migrations/core/0007_app_versions.sql +95 -0
- package/dist/migrations/core/0008_user_bound_tokens.sql +42 -0
- package/dist/migrations/core/0009_app_name.sql +1 -0
- package/dist/migrations/core/0010_apps_origin.sql +12 -0
- package/dist/migrations/core/0011_modules.sql +32 -0
- package/dist/migrations/core/0012_data_module_tables.sql +9 -0
- package/dist/migrations/core/0014_get_logs.sql +26 -0
- package/dist/migrations/core/0016_apps_slug_release.sql +8 -0
- package/dist/migrations/core/0018_custom_domains.sql +22 -0
- package/dist/migrations/core/0021_abuse_reports.sql +23 -0
- package/dist/migrations/core/0022_gallery.sql +20 -0
- package/dist/migrations/core/0023_workspace_modules.sql +13 -0
- package/dist/migrations/core/0024_app_assets.sql +18 -0
- package/dist/migrations/core/0025_app_asset_snapshots.sql +28 -0
- package/dist/migrations/core/0026_publish_approval.sql +13 -0
- package/dist/migrations/core/0027_publish_block.sql +6 -0
- package/dist/migrations/core/meta/_journal.json +167 -0
- package/dist/testing.d.ts +269 -0
- package/dist/testing.js +1569 -0
- package/package.json +63 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
CREATE TYPE "public"."app_status" AS ENUM('live', 'hibernated');--> statement-breakpoint
|
|
2
|
+
CREATE TYPE "public"."app_visibility" AS ENUM('public', 'team', 'password');--> statement-breakpoint
|
|
3
|
+
CREATE TYPE "public"."membership_role" AS ENUM('workspace-admin', 'editor', 'viewer');--> statement-breakpoint
|
|
4
|
+
CREATE TYPE "public"."routing_mode" AS ENUM('spa', 'exact');--> statement-breakpoint
|
|
5
|
+
CREATE TYPE "public"."workspace_kind" AS ENUM('personal', 'team');--> statement-breakpoint
|
|
6
|
+
CREATE TABLE "apps" (
|
|
7
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
8
|
+
"workspace_id" text NOT NULL,
|
|
9
|
+
"slug" text NOT NULL,
|
|
10
|
+
"active_deploy_id" text,
|
|
11
|
+
"routing_mode" "routing_mode" DEFAULT 'spa' NOT NULL,
|
|
12
|
+
"visibility" "app_visibility" DEFAULT 'public' NOT NULL,
|
|
13
|
+
"password_hash" text,
|
|
14
|
+
"status" "app_status" DEFAULT 'live' NOT NULL,
|
|
15
|
+
"uses_end_user_auth" boolean DEFAULT false NOT NULL,
|
|
16
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
17
|
+
"deleted_at" timestamp
|
|
18
|
+
);
|
|
19
|
+
--> statement-breakpoint
|
|
20
|
+
CREATE TABLE "blob_refs" (
|
|
21
|
+
"sha256" text NOT NULL,
|
|
22
|
+
"deploy_id" text NOT NULL,
|
|
23
|
+
CONSTRAINT "blob_refs_sha256_deploy_id_pk" PRIMARY KEY("sha256","deploy_id")
|
|
24
|
+
);
|
|
25
|
+
--> statement-breakpoint
|
|
26
|
+
CREATE TABLE "blobs" (
|
|
27
|
+
"sha256" text PRIMARY KEY NOT NULL,
|
|
28
|
+
"content_type" text NOT NULL,
|
|
29
|
+
"size" bigint NOT NULL,
|
|
30
|
+
"path" text NOT NULL
|
|
31
|
+
);
|
|
32
|
+
--> statement-breakpoint
|
|
33
|
+
CREATE TABLE "deploy_files" (
|
|
34
|
+
"deploy_id" text NOT NULL,
|
|
35
|
+
"path" text NOT NULL,
|
|
36
|
+
"sha256" text NOT NULL,
|
|
37
|
+
CONSTRAINT "deploy_files_deploy_id_path_pk" PRIMARY KEY("deploy_id","path")
|
|
38
|
+
);
|
|
39
|
+
--> statement-breakpoint
|
|
40
|
+
CREATE TABLE "deploys" (
|
|
41
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
42
|
+
"app_id" text NOT NULL,
|
|
43
|
+
"manifest" jsonb NOT NULL,
|
|
44
|
+
"lint_report" jsonb,
|
|
45
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
46
|
+
"deleted_at" timestamp
|
|
47
|
+
);
|
|
48
|
+
--> statement-breakpoint
|
|
49
|
+
CREATE TABLE "memberships" (
|
|
50
|
+
"user_id" text NOT NULL,
|
|
51
|
+
"workspace_id" text NOT NULL,
|
|
52
|
+
"role" "membership_role" NOT NULL,
|
|
53
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
54
|
+
CONSTRAINT "memberships_user_id_workspace_id_pk" PRIMARY KEY("user_id","workspace_id")
|
|
55
|
+
);
|
|
56
|
+
--> statement-breakpoint
|
|
57
|
+
CREATE TABLE "users" (
|
|
58
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
59
|
+
"email" text NOT NULL,
|
|
60
|
+
"google_sub" text,
|
|
61
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
62
|
+
CONSTRAINT "users_email_unique" UNIQUE("email"),
|
|
63
|
+
CONSTRAINT "users_google_sub_unique" UNIQUE("google_sub")
|
|
64
|
+
);
|
|
65
|
+
--> statement-breakpoint
|
|
66
|
+
CREATE TABLE "workspaces" (
|
|
67
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
68
|
+
"kind" "workspace_kind" NOT NULL,
|
|
69
|
+
"slug" text NOT NULL,
|
|
70
|
+
"name" text NOT NULL,
|
|
71
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
72
|
+
CONSTRAINT "workspaces_slug_unique" UNIQUE("slug")
|
|
73
|
+
);
|
|
74
|
+
--> statement-breakpoint
|
|
75
|
+
ALTER TABLE "apps" ADD CONSTRAINT "apps_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
76
|
+
ALTER TABLE "apps" ADD CONSTRAINT "apps_active_deploy_id_deploys_id_fk" FOREIGN KEY ("active_deploy_id") REFERENCES "public"."deploys"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
77
|
+
ALTER TABLE "blob_refs" ADD CONSTRAINT "blob_refs_sha256_blobs_sha256_fk" FOREIGN KEY ("sha256") REFERENCES "public"."blobs"("sha256") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
78
|
+
ALTER TABLE "blob_refs" ADD CONSTRAINT "blob_refs_deploy_id_deploys_id_fk" FOREIGN KEY ("deploy_id") REFERENCES "public"."deploys"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
79
|
+
ALTER TABLE "deploy_files" ADD CONSTRAINT "deploy_files_deploy_id_deploys_id_fk" FOREIGN KEY ("deploy_id") REFERENCES "public"."deploys"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
80
|
+
ALTER TABLE "deploy_files" ADD CONSTRAINT "deploy_files_sha256_blobs_sha256_fk" FOREIGN KEY ("sha256") REFERENCES "public"."blobs"("sha256") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
81
|
+
ALTER TABLE "deploys" ADD CONSTRAINT "deploys_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
82
|
+
ALTER TABLE "memberships" ADD CONSTRAINT "memberships_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
83
|
+
ALTER TABLE "memberships" ADD CONSTRAINT "memberships_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
84
|
+
CREATE UNIQUE INDEX "apps_workspace_slug_uq" ON "apps" USING btree ("workspace_id","slug");
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
CREATE TABLE "oauth_access_tokens" (
|
|
2
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
3
|
+
"token_hash" text NOT NULL,
|
|
4
|
+
"user_id" text NOT NULL,
|
|
5
|
+
"workspace_id" text NOT NULL,
|
|
6
|
+
"role" "membership_role" NOT NULL,
|
|
7
|
+
"oauth_client_id" text,
|
|
8
|
+
"scope" text NOT NULL,
|
|
9
|
+
"audience" text NOT NULL,
|
|
10
|
+
"expires_at" timestamp NOT NULL,
|
|
11
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
12
|
+
"revoked_at" timestamp,
|
|
13
|
+
CONSTRAINT "oauth_access_tokens_token_hash_unique" UNIQUE("token_hash")
|
|
14
|
+
);
|
|
15
|
+
--> statement-breakpoint
|
|
16
|
+
CREATE TABLE "oauth_authorization_codes" (
|
|
17
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
18
|
+
"code_hash" text NOT NULL,
|
|
19
|
+
"client_id" text NOT NULL,
|
|
20
|
+
"user_id" text NOT NULL,
|
|
21
|
+
"workspace_id" text NOT NULL,
|
|
22
|
+
"role" "membership_role" NOT NULL,
|
|
23
|
+
"redirect_uri" text NOT NULL,
|
|
24
|
+
"code_challenge" text NOT NULL,
|
|
25
|
+
"code_challenge_method" text NOT NULL,
|
|
26
|
+
"scope" text NOT NULL,
|
|
27
|
+
"resource" text NOT NULL,
|
|
28
|
+
"used" boolean DEFAULT false NOT NULL,
|
|
29
|
+
"expires_at" timestamp NOT NULL,
|
|
30
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
31
|
+
CONSTRAINT "oauth_authorization_codes_code_hash_unique" UNIQUE("code_hash")
|
|
32
|
+
);
|
|
33
|
+
--> statement-breakpoint
|
|
34
|
+
CREATE TABLE "oauth_clients" (
|
|
35
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
36
|
+
"client_id" text NOT NULL,
|
|
37
|
+
"client_name" text NOT NULL,
|
|
38
|
+
"redirect_uris" text[] NOT NULL,
|
|
39
|
+
"token_endpoint_auth_method" text DEFAULT 'none' NOT NULL,
|
|
40
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
41
|
+
CONSTRAINT "oauth_clients_client_id_unique" UNIQUE("client_id")
|
|
42
|
+
);
|
|
43
|
+
--> statement-breakpoint
|
|
44
|
+
CREATE TABLE "oauth_refresh_tokens" (
|
|
45
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
46
|
+
"token_hash" text NOT NULL,
|
|
47
|
+
"user_id" text NOT NULL,
|
|
48
|
+
"workspace_id" text NOT NULL,
|
|
49
|
+
"role" "membership_role" NOT NULL,
|
|
50
|
+
"oauth_client_id" text,
|
|
51
|
+
"scope" text NOT NULL,
|
|
52
|
+
"audience" text NOT NULL,
|
|
53
|
+
"rotated_to" text,
|
|
54
|
+
"used_at" timestamp,
|
|
55
|
+
"expires_at" timestamp NOT NULL,
|
|
56
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
57
|
+
CONSTRAINT "oauth_refresh_tokens_token_hash_unique" UNIQUE("token_hash")
|
|
58
|
+
);
|
|
59
|
+
--> statement-breakpoint
|
|
60
|
+
ALTER TABLE "oauth_access_tokens" ADD CONSTRAINT "oauth_access_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
61
|
+
ALTER TABLE "oauth_access_tokens" ADD CONSTRAINT "oauth_access_tokens_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
62
|
+
ALTER TABLE "oauth_access_tokens" ADD CONSTRAINT "oauth_access_tokens_oauth_client_id_oauth_clients_id_fk" FOREIGN KEY ("oauth_client_id") REFERENCES "public"."oauth_clients"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
|
63
|
+
ALTER TABLE "oauth_authorization_codes" ADD CONSTRAINT "oauth_authorization_codes_client_id_oauth_clients_client_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."oauth_clients"("client_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
64
|
+
ALTER TABLE "oauth_authorization_codes" ADD CONSTRAINT "oauth_authorization_codes_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
65
|
+
ALTER TABLE "oauth_authorization_codes" ADD CONSTRAINT "oauth_authorization_codes_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
66
|
+
ALTER TABLE "oauth_refresh_tokens" ADD CONSTRAINT "oauth_refresh_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
67
|
+
ALTER TABLE "oauth_refresh_tokens" ADD CONSTRAINT "oauth_refresh_tokens_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
68
|
+
ALTER TABLE "oauth_refresh_tokens" ADD CONSTRAINT "oauth_refresh_tokens_oauth_client_id_oauth_clients_id_fk" FOREIGN KEY ("oauth_client_id") REFERENCES "public"."oauth_clients"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
|
69
|
+
ALTER TABLE "oauth_refresh_tokens" ADD CONSTRAINT "oauth_refresh_tokens_rotated_to_oauth_refresh_tokens_id_fk" FOREIGN KEY ("rotated_to") REFERENCES "public"."oauth_refresh_tokens"("id") ON DELETE no action ON UPDATE no action;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
CREATE TYPE "public"."deploy_state" AS ENUM('awaiting_upload', 'queued', 'linting', 'storing', 'activating', 'ready', 'failed');--> statement-breakpoint
|
|
2
|
+
CREATE TABLE "audit_log" (
|
|
3
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
4
|
+
"workspace_id" text NOT NULL,
|
|
5
|
+
"actor_user_id" text,
|
|
6
|
+
"action" text NOT NULL,
|
|
7
|
+
"target" text,
|
|
8
|
+
"meta" jsonb,
|
|
9
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
10
|
+
);
|
|
11
|
+
--> statement-breakpoint
|
|
12
|
+
ALTER TABLE "deploys" ADD COLUMN "state" "deploy_state" DEFAULT 'awaiting_upload' NOT NULL;--> statement-breakpoint
|
|
13
|
+
ALTER TABLE "deploys" ADD COLUMN "error" text;--> statement-breakpoint
|
|
14
|
+
ALTER TABLE "deploys" ADD COLUMN "total_bytes" bigint;--> statement-breakpoint
|
|
15
|
+
ALTER TABLE "deploys" ADD COLUMN "activated_at" timestamp;--> statement-breakpoint
|
|
16
|
+
ALTER TABLE "audit_log" ADD CONSTRAINT "audit_log_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
17
|
+
ALTER TABLE "audit_log" ADD CONSTRAINT "audit_log_actor_user_id_users_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
CREATE TYPE "public"."collection_access_mode" AS ENUM('public-read', 'public-write', 'locked', 'owner-only');--> statement-breakpoint
|
|
2
|
+
CREATE TABLE "app_documents" (
|
|
3
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
4
|
+
"app_id" text NOT NULL,
|
|
5
|
+
"collection" text NOT NULL,
|
|
6
|
+
"owner_end_user_id" text,
|
|
7
|
+
"doc" jsonb NOT NULL,
|
|
8
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
9
|
+
"updated_at" timestamp DEFAULT now() NOT NULL,
|
|
10
|
+
"deleted_at" timestamp
|
|
11
|
+
);
|
|
12
|
+
--> statement-breakpoint
|
|
13
|
+
CREATE TABLE "collections" (
|
|
14
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
15
|
+
"app_id" text NOT NULL,
|
|
16
|
+
"name" text NOT NULL,
|
|
17
|
+
"json_schema" jsonb NOT NULL,
|
|
18
|
+
"access_mode" "collection_access_mode" DEFAULT 'locked' NOT NULL,
|
|
19
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
20
|
+
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
21
|
+
);
|
|
22
|
+
--> statement-breakpoint
|
|
23
|
+
ALTER TABLE "app_documents" ADD CONSTRAINT "app_documents_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
24
|
+
ALTER TABLE "collections" ADD CONSTRAINT "collections_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
25
|
+
CREATE INDEX "app_documents_app_collection_idx" ON "app_documents" USING btree ("app_id","collection");--> statement-breakpoint
|
|
26
|
+
CREATE UNIQUE INDEX "collections_app_name_uq" ON "collections" USING btree ("app_id","name");
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
CREATE TYPE "public"."app_error_type" AS ENUM('error', 'unhandledrejection');--> statement-breakpoint
|
|
2
|
+
CREATE TABLE "app_daily_stats" (
|
|
3
|
+
"app_id" text NOT NULL,
|
|
4
|
+
"day" text NOT NULL,
|
|
5
|
+
"path_404_counts" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
|
6
|
+
"count_5xx" integer DEFAULT 0 NOT NULL,
|
|
7
|
+
"request_count" integer DEFAULT 0 NOT NULL,
|
|
8
|
+
"updated_at" timestamp DEFAULT now() NOT NULL,
|
|
9
|
+
CONSTRAINT "app_daily_stats_app_id_day_pk" PRIMARY KEY("app_id","day")
|
|
10
|
+
);
|
|
11
|
+
--> statement-breakpoint
|
|
12
|
+
CREATE TABLE "app_errors" (
|
|
13
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
14
|
+
"app_id" text NOT NULL,
|
|
15
|
+
"type" "app_error_type" NOT NULL,
|
|
16
|
+
"message" text NOT NULL,
|
|
17
|
+
"stack" text,
|
|
18
|
+
"url" text NOT NULL,
|
|
19
|
+
"ua" text,
|
|
20
|
+
"ts" timestamp,
|
|
21
|
+
"dedup_key" text NOT NULL,
|
|
22
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
23
|
+
);
|
|
24
|
+
--> statement-breakpoint
|
|
25
|
+
ALTER TABLE "app_daily_stats" ADD CONSTRAINT "app_daily_stats_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
26
|
+
ALTER TABLE "app_errors" ADD CONSTRAINT "app_errors_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
27
|
+
CREATE INDEX "app_errors_app_created_idx" ON "app_errors" USING btree ("app_id","created_at");
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
CREATE TYPE "public"."audit_actor_kind" AS ENUM('user', 'agent');--> statement-breakpoint
|
|
2
|
+
ALTER TABLE "audit_log" ADD COLUMN "actor_kind" "audit_actor_kind" DEFAULT 'user' NOT NULL;--> statement-breakpoint
|
|
3
|
+
ALTER TABLE "audit_log" ADD COLUMN "subject_type" text;--> statement-breakpoint
|
|
4
|
+
CREATE INDEX "audit_log_workspace_created_idx" ON "audit_log" USING btree ("workspace_id","created_at");
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
CREATE TYPE "public"."upstream_auth_type" AS ENUM('none', 'bearer', 'header');--> statement-breakpoint
|
|
2
|
+
CREATE TABLE "upstream_secrets" (
|
|
3
|
+
"upstream_id" text PRIMARY KEY NOT NULL,
|
|
4
|
+
"ciphertext" text NOT NULL,
|
|
5
|
+
"iv" text NOT NULL,
|
|
6
|
+
"auth_tag" text NOT NULL,
|
|
7
|
+
"wrapped_dek" text NOT NULL,
|
|
8
|
+
"kek_id" text NOT NULL,
|
|
9
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
10
|
+
);
|
|
11
|
+
--> statement-breakpoint
|
|
12
|
+
CREATE TABLE "upstreams" (
|
|
13
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
14
|
+
"workspace_id" text NOT NULL,
|
|
15
|
+
"name" text NOT NULL,
|
|
16
|
+
"base_url" text NOT NULL,
|
|
17
|
+
"allowed_methods" text[] NOT NULL,
|
|
18
|
+
"allowed_path_prefixes" text[] NOT NULL,
|
|
19
|
+
"auth_type" "upstream_auth_type" DEFAULT 'none' NOT NULL,
|
|
20
|
+
"auth_header_name" text,
|
|
21
|
+
"allowed_app_ids" text[] DEFAULT '{}' NOT NULL,
|
|
22
|
+
"created_by" text,
|
|
23
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
24
|
+
);
|
|
25
|
+
--> statement-breakpoint
|
|
26
|
+
ALTER TABLE "upstream_secrets" ADD CONSTRAINT "upstream_secrets_upstream_id_upstreams_id_fk" FOREIGN KEY ("upstream_id") REFERENCES "public"."upstreams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
27
|
+
ALTER TABLE "upstreams" ADD CONSTRAINT "upstreams_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
28
|
+
ALTER TABLE "upstreams" ADD CONSTRAINT "upstreams_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
29
|
+
CREATE UNIQUE INDEX "upstreams_workspace_name_uq" ON "upstreams" USING btree ("workspace_id","name");
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
-- M0-02 (NSO-281): immutable app versions replace the upload/deploy pipeline.
|
|
2
|
+
--
|
|
3
|
+
-- EXPLICIT, DESTRUCTIVE: the deploy pipeline tables are dropped and their
|
|
4
|
+
-- history is NOT migrated (decided in the M0 plan). Apps, collections,
|
|
5
|
+
-- documents, errors, stats, upstreams and the audit log are kept. Blob bytes
|
|
6
|
+
-- move from the disk volume into Postgres (`blobs.bytes`); the old on-disk
|
|
7
|
+
-- BLOB_DIR contents are no longer read by anything. See CHANGELOG.md.
|
|
8
|
+
ALTER TABLE "apps" DROP CONSTRAINT "apps_active_deploy_id_deploys_id_fk";--> statement-breakpoint
|
|
9
|
+
ALTER TABLE "apps" DROP COLUMN "active_deploy_id";--> statement-breakpoint
|
|
10
|
+
ALTER TABLE "apps" DROP COLUMN "routing_mode";--> statement-breakpoint
|
|
11
|
+
ALTER TABLE "apps" DROP COLUMN "uses_end_user_auth";--> statement-breakpoint
|
|
12
|
+
DROP TABLE "blob_refs";--> statement-breakpoint
|
|
13
|
+
DROP TABLE "deploy_files";--> statement-breakpoint
|
|
14
|
+
DROP TABLE "deploys";--> statement-breakpoint
|
|
15
|
+
DROP TABLE "blobs";--> statement-breakpoint
|
|
16
|
+
DROP TYPE "public"."deploy_state";--> statement-breakpoint
|
|
17
|
+
DROP TYPE "public"."routing_mode";--> statement-breakpoint
|
|
18
|
+
DROP INDEX "apps_workspace_slug_uq";--> statement-breakpoint
|
|
19
|
+
-- App slugs become GLOBALLY unique host labels (`<slug>.<APPS_DOMAIN>`):
|
|
20
|
+
-- 3–40 chars of ^[a-z0-9]+(-[a-z0-9]+)*$, no reserved word. Existing slugs
|
|
21
|
+
-- that break the grammar, are reserved, or collide with an OLDER app's slug
|
|
22
|
+
-- in another workspace are renamed to `<base>-<4hex>` (deterministic from the
|
|
23
|
+
-- app id; the oldest app keeps a contested slug).
|
|
24
|
+
DO $$
|
|
25
|
+
DECLARE
|
|
26
|
+
r record;
|
|
27
|
+
base text;
|
|
28
|
+
candidate text;
|
|
29
|
+
attempt int;
|
|
30
|
+
BEGIN
|
|
31
|
+
FOR r IN
|
|
32
|
+
SELECT id, slug FROM (
|
|
33
|
+
SELECT id, slug,
|
|
34
|
+
row_number() OVER (PARTITION BY slug ORDER BY created_at, id) AS rank
|
|
35
|
+
FROM apps
|
|
36
|
+
) ranked
|
|
37
|
+
WHERE rank > 1
|
|
38
|
+
OR slug !~ '^[a-z0-9]+(-[a-z0-9]+)*$'
|
|
39
|
+
OR char_length(slug) NOT BETWEEN 3 AND 40
|
|
40
|
+
OR slug IN ('www', 'api', 'mcp', 'preview', 'admin', 'mail', 'static', 'app', 'auth', 'oauth')
|
|
41
|
+
ORDER BY id
|
|
42
|
+
LOOP
|
|
43
|
+
base := trim(both '-' from regexp_replace(lower(r.slug), '[^a-z0-9]+', '-', 'g'));
|
|
44
|
+
base := trim(trailing '-' from left(base, 35));
|
|
45
|
+
IF base = '' THEN base := 'app'; END IF;
|
|
46
|
+
attempt := 0;
|
|
47
|
+
LOOP
|
|
48
|
+
candidate := base || '-' || substr(md5(r.id || attempt::text), 1, 4);
|
|
49
|
+
EXIT WHEN NOT EXISTS (SELECT 1 FROM apps WHERE slug = candidate);
|
|
50
|
+
attempt := attempt + 1;
|
|
51
|
+
END LOOP;
|
|
52
|
+
UPDATE apps SET slug = candidate WHERE id = r.id;
|
|
53
|
+
END LOOP;
|
|
54
|
+
END $$;--> statement-breakpoint
|
|
55
|
+
CREATE TYPE "public"."compile_status" AS ENUM('pending', 'ok', 'error');--> statement-breakpoint
|
|
56
|
+
CREATE TYPE "public"."version_file_kind" AS ENUM('source', 'built');--> statement-breakpoint
|
|
57
|
+
CREATE TABLE "blobs" (
|
|
58
|
+
"sha256" text PRIMARY KEY NOT NULL,
|
|
59
|
+
"bytes" "bytea" NOT NULL,
|
|
60
|
+
"size" integer NOT NULL,
|
|
61
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
62
|
+
);
|
|
63
|
+
--> statement-breakpoint
|
|
64
|
+
CREATE TABLE "app_versions" (
|
|
65
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
66
|
+
"app_id" text NOT NULL,
|
|
67
|
+
"number" integer NOT NULL,
|
|
68
|
+
"created_by_user_id" text,
|
|
69
|
+
"actor_kind" "audit_actor_kind" NOT NULL,
|
|
70
|
+
"reasoning" text,
|
|
71
|
+
"compile_status" "compile_status" DEFAULT 'pending' NOT NULL,
|
|
72
|
+
"compile_errors" jsonb,
|
|
73
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
74
|
+
);
|
|
75
|
+
--> statement-breakpoint
|
|
76
|
+
CREATE TABLE "version_files" (
|
|
77
|
+
"version_id" text NOT NULL,
|
|
78
|
+
"path" text NOT NULL,
|
|
79
|
+
"sha256" text NOT NULL,
|
|
80
|
+
"size" integer NOT NULL,
|
|
81
|
+
"kind" "version_file_kind" NOT NULL,
|
|
82
|
+
CONSTRAINT "version_files_version_id_kind_path_pk" PRIMARY KEY("version_id","kind","path")
|
|
83
|
+
);
|
|
84
|
+
--> statement-breakpoint
|
|
85
|
+
ALTER TABLE "apps" ADD COLUMN "published_version_id" text;--> statement-breakpoint
|
|
86
|
+
ALTER TABLE "app_versions" ADD CONSTRAINT "app_versions_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
87
|
+
ALTER TABLE "app_versions" ADD CONSTRAINT "app_versions_created_by_user_id_users_id_fk" FOREIGN KEY ("created_by_user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
88
|
+
ALTER TABLE "apps" ADD CONSTRAINT "apps_published_version_id_app_versions_id_fk" FOREIGN KEY ("published_version_id") REFERENCES "public"."app_versions"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
|
89
|
+
ALTER TABLE "version_files" ADD CONSTRAINT "version_files_version_id_app_versions_id_fk" FOREIGN KEY ("version_id") REFERENCES "public"."app_versions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
90
|
+
ALTER TABLE "version_files" ADD CONSTRAINT "version_files_sha256_blobs_sha256_fk" FOREIGN KEY ("sha256") REFERENCES "public"."blobs"("sha256") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
91
|
+
CREATE UNIQUE INDEX "app_versions_app_number_uq" ON "app_versions" USING btree ("app_id","number");--> statement-breakpoint
|
|
92
|
+
CREATE UNIQUE INDEX "apps_slug_uq" ON "apps" USING btree ("slug");--> statement-breakpoint
|
|
93
|
+
CREATE INDEX "apps_workspace_idx" ON "apps" USING btree ("workspace_id");--> statement-breakpoint
|
|
94
|
+
CREATE INDEX "version_files_sha256_idx" ON "version_files" USING btree ("sha256");--> statement-breakpoint
|
|
95
|
+
ALTER TABLE "apps" ADD CONSTRAINT "apps_slug_format" CHECK ("apps"."slug" ~ '^[a-z0-9]+(-[a-z0-9]+)*$' AND char_length("apps"."slug") BETWEEN 3 AND 40);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
-- M0-04 (NSO-282): OAuth tokens become USER-bound; API keys; CIMD/DCR client
|
|
2
|
+
-- bookkeeping.
|
|
3
|
+
--
|
|
4
|
+
-- EXPLICIT, DESTRUCTIVE: every authorization code, access token and refresh
|
|
5
|
+
-- token is deleted — they were bound to one workspace + role and used the old
|
|
6
|
+
-- scope vocabulary (mcp:whoami, apps:read, deploy:write, data:read,
|
|
7
|
+
-- data:write), which nothing accepts any more. Connected agents simply
|
|
8
|
+
-- reconnect (new consent → read / write / publish). Registered clients are
|
|
9
|
+
-- kept; the ones that ever held a grant are stamped as used so they do not
|
|
10
|
+
-- count toward the unused-DCR-client cap. See CHANGELOG.md.
|
|
11
|
+
ALTER TABLE "oauth_clients" ADD COLUMN "source" text DEFAULT 'dcr' NOT NULL;--> statement-breakpoint
|
|
12
|
+
ALTER TABLE "oauth_clients" ADD COLUMN "last_used_at" timestamp;--> statement-breakpoint
|
|
13
|
+
UPDATE "oauth_clients" c SET "last_used_at" = c."created_at"
|
|
14
|
+
WHERE EXISTS (SELECT 1 FROM "oauth_authorization_codes" a WHERE a."client_id" = c."client_id")
|
|
15
|
+
OR EXISTS (SELECT 1 FROM "oauth_access_tokens" t WHERE t."oauth_client_id" = c."id")
|
|
16
|
+
OR EXISTS (SELECT 1 FROM "oauth_refresh_tokens" r WHERE r."oauth_client_id" = c."id");--> statement-breakpoint
|
|
17
|
+
TRUNCATE TABLE "oauth_authorization_codes", "oauth_access_tokens", "oauth_refresh_tokens";--> statement-breakpoint
|
|
18
|
+
CREATE TABLE "api_keys" (
|
|
19
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
20
|
+
"user_id" text NOT NULL,
|
|
21
|
+
"name" text NOT NULL,
|
|
22
|
+
"key_hash" text NOT NULL,
|
|
23
|
+
"scopes" text NOT NULL,
|
|
24
|
+
"last_used_at" timestamp,
|
|
25
|
+
"revoked_at" timestamp,
|
|
26
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
27
|
+
CONSTRAINT "api_keys_key_hash_unique" UNIQUE("key_hash")
|
|
28
|
+
);
|
|
29
|
+
--> statement-breakpoint
|
|
30
|
+
ALTER TABLE "oauth_access_tokens" DROP CONSTRAINT "oauth_access_tokens_workspace_id_workspaces_id_fk";
|
|
31
|
+
--> statement-breakpoint
|
|
32
|
+
ALTER TABLE "oauth_authorization_codes" DROP CONSTRAINT "oauth_authorization_codes_workspace_id_workspaces_id_fk";
|
|
33
|
+
--> statement-breakpoint
|
|
34
|
+
ALTER TABLE "oauth_refresh_tokens" DROP CONSTRAINT "oauth_refresh_tokens_workspace_id_workspaces_id_fk";
|
|
35
|
+
--> statement-breakpoint
|
|
36
|
+
ALTER TABLE "api_keys" ADD CONSTRAINT "api_keys_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
37
|
+
ALTER TABLE "oauth_access_tokens" DROP COLUMN "workspace_id";--> statement-breakpoint
|
|
38
|
+
ALTER TABLE "oauth_access_tokens" DROP COLUMN "role";--> statement-breakpoint
|
|
39
|
+
ALTER TABLE "oauth_authorization_codes" DROP COLUMN "workspace_id";--> statement-breakpoint
|
|
40
|
+
ALTER TABLE "oauth_authorization_codes" DROP COLUMN "role";--> statement-breakpoint
|
|
41
|
+
ALTER TABLE "oauth_refresh_tokens" DROP COLUMN "workspace_id";--> statement-breakpoint
|
|
42
|
+
ALTER TABLE "oauth_refresh_tokens" DROP COLUMN "role";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "apps" ADD COLUMN "name" text;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- M0-06 (NSO-285): apps origin. Generated by drizzle-kit, then hand-edited:
|
|
2
|
+
-- the `team` visibility cannot be enforced on an app host (app hosts never read
|
|
3
|
+
-- the dashboard session), so existing `team` apps become `password` apps —
|
|
4
|
+
-- fail closed: with no password set nobody passes the gate until the owner sets one.
|
|
5
|
+
ALTER TABLE "apps" ALTER COLUMN "visibility" SET DATA TYPE text;--> statement-breakpoint
|
|
6
|
+
UPDATE "apps" SET "visibility" = 'password' WHERE "visibility" = 'team';--> statement-breakpoint
|
|
7
|
+
ALTER TABLE "apps" ALTER COLUMN "visibility" SET DEFAULT 'public'::text;--> statement-breakpoint
|
|
8
|
+
DROP TYPE "public"."app_visibility";--> statement-breakpoint
|
|
9
|
+
CREATE TYPE "public"."app_visibility" AS ENUM('public', 'password');--> statement-breakpoint
|
|
10
|
+
ALTER TABLE "apps" ALTER COLUMN "visibility" SET DEFAULT 'public'::"public"."app_visibility";--> statement-breakpoint
|
|
11
|
+
ALTER TABLE "apps" ALTER COLUMN "visibility" SET DATA TYPE "public"."app_visibility" USING "visibility"::"public"."app_visibility";--> statement-breakpoint
|
|
12
|
+
ALTER TABLE "apps" ADD COLUMN "frame_ancestors" text;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- M1-01 (NSO-287): platform modules. Generated by drizzle-kit. module_configs =
|
|
2
|
+
-- per-app module configuration (+ one pending change awaiting the owner's
|
|
3
|
+
-- confirmation); module_secrets = envelope-encrypted per-app module secrets
|
|
4
|
+
-- (dashboard-only writes, never returned by any API). audit_actor_kind gains
|
|
5
|
+
-- 'end_user' for module actions of an app's signed-in end users (ADD VALUE is
|
|
6
|
+
-- fine inside the migration transaction on PG 12+: nothing uses it in-txn).
|
|
7
|
+
ALTER TYPE "public"."audit_actor_kind" ADD VALUE 'end_user';--> statement-breakpoint
|
|
8
|
+
CREATE TABLE "module_configs" (
|
|
9
|
+
"app_id" text NOT NULL,
|
|
10
|
+
"module" text NOT NULL,
|
|
11
|
+
"config" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
|
12
|
+
"pending" jsonb,
|
|
13
|
+
"updated_at" timestamp DEFAULT now() NOT NULL,
|
|
14
|
+
CONSTRAINT "module_configs_app_id_module_pk" PRIMARY KEY("app_id","module")
|
|
15
|
+
);
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
CREATE TABLE "module_secrets" (
|
|
18
|
+
"app_id" text NOT NULL,
|
|
19
|
+
"module" text NOT NULL,
|
|
20
|
+
"name" text NOT NULL,
|
|
21
|
+
"ciphertext" text NOT NULL,
|
|
22
|
+
"iv" text NOT NULL,
|
|
23
|
+
"auth_tag" text NOT NULL,
|
|
24
|
+
"wrapped_dek" text NOT NULL,
|
|
25
|
+
"kek_id" text NOT NULL,
|
|
26
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
27
|
+
"updated_at" timestamp DEFAULT now() NOT NULL,
|
|
28
|
+
CONSTRAINT "module_secrets_app_id_module_name_pk" PRIMARY KEY("app_id","module","name")
|
|
29
|
+
);
|
|
30
|
+
--> statement-breakpoint
|
|
31
|
+
ALTER TABLE "module_configs" ADD CONSTRAINT "module_configs_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
32
|
+
ALTER TABLE "module_secrets" ADD CONSTRAINT "module_secrets_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE cascade ON UPDATE no action;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- NSO-300 (M1-03): the pre-module Data API tables `collections`,
|
|
2
|
+
-- `app_documents` and the enum `collection_access_mode` now belong to the
|
|
3
|
+
-- platform module `data` (modules/data, drobek-module-data). Its first
|
|
4
|
+
-- migration (journal __drizzle_migrations_mod_data) imports every collection
|
|
5
|
+
-- into the app's `module_configs` row (access_mode → per-operation rules) and
|
|
6
|
+
-- every live document into `mod_data_documents`, then drops the old tables.
|
|
7
|
+
-- Core only forgets them here, so a server without the data module never
|
|
8
|
+
-- loses the stored records.
|
|
9
|
+
SELECT 1;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- NSO-290 (M1-07): get_logs — the compile history (app_compiles) and the
|
|
2
|
+
-- per-module request counters (module_request_stats). Additive only.
|
|
3
|
+
CREATE TABLE "app_compiles" (
|
|
4
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
5
|
+
"app_id" text NOT NULL,
|
|
6
|
+
"version_number" integer,
|
|
7
|
+
"ok" boolean NOT NULL,
|
|
8
|
+
"errors" jsonb DEFAULT '[]'::jsonb NOT NULL,
|
|
9
|
+
"warning_count" integer DEFAULT 0 NOT NULL,
|
|
10
|
+
"duration_ms" integer DEFAULT 0 NOT NULL,
|
|
11
|
+
"trigger" text NOT NULL,
|
|
12
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
13
|
+
);
|
|
14
|
+
--> statement-breakpoint
|
|
15
|
+
CREATE TABLE "module_request_stats" (
|
|
16
|
+
"app_id" text NOT NULL,
|
|
17
|
+
"module" text NOT NULL,
|
|
18
|
+
"status_class" text NOT NULL,
|
|
19
|
+
"day" text NOT NULL,
|
|
20
|
+
"count" integer DEFAULT 0 NOT NULL,
|
|
21
|
+
CONSTRAINT "module_request_stats_app_id_module_status_class_day_pk" PRIMARY KEY("app_id","module","status_class","day")
|
|
22
|
+
);
|
|
23
|
+
--> statement-breakpoint
|
|
24
|
+
ALTER TABLE "app_compiles" ADD CONSTRAINT "app_compiles_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
25
|
+
ALTER TABLE "module_request_stats" ADD CONSTRAINT "module_request_stats_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
26
|
+
CREATE INDEX "app_compiles_app_created_idx" ON "app_compiles" USING btree ("app_id","created_at");
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- NSO-288 (M2-01): dashboard app delete. A soft-deleted app keeps its slug for
|
|
2
|
+
-- 30 days; then @drobek/apps (releaseDeletedAppSlugs) renames it to the
|
|
3
|
+
-- tombstone `<slug>~deleted-<id>` so a new app can take the slug. The slug
|
|
4
|
+
-- CHECK admits that tombstone on deleted rows only; the partial index serves
|
|
5
|
+
-- the release sweep. Additive for live rows (their grammar is unchanged).
|
|
6
|
+
ALTER TABLE "apps" DROP CONSTRAINT "apps_slug_format";--> statement-breakpoint
|
|
7
|
+
CREATE INDEX "apps_deleted_at_idx" ON "apps" USING btree ("deleted_at") WHERE "apps"."deleted_at" IS NOT NULL;--> statement-breakpoint
|
|
8
|
+
ALTER TABLE "apps" ADD CONSTRAINT "apps_slug_format" CHECK (("apps"."slug" ~ '^[a-z0-9]+(-[a-z0-9]+)*$' AND char_length("apps"."slug") BETWEEN 3 AND 40) OR ("apps"."deleted_at" IS NOT NULL AND "apps"."slug" ~ '^[a-z0-9]+(-[a-z0-9]+)*~deleted-[a-z0-9]+$'));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- NSO-292 (M3-01): custom domains. Generated by drizzle-kit. Additive only.
|
|
2
|
+
-- Partial unique indexes: one VERIFIED row per hostname instance-wide (an
|
|
3
|
+
-- unverified claim never blocks the domain's real owner) and at most one
|
|
4
|
+
-- primary (redirect target) domain per app.
|
|
5
|
+
CREATE TABLE "domains" (
|
|
6
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
7
|
+
"app_id" text NOT NULL,
|
|
8
|
+
"hostname" text NOT NULL,
|
|
9
|
+
"verification_token" text NOT NULL,
|
|
10
|
+
"verified_at" timestamp,
|
|
11
|
+
"last_check_at" timestamp,
|
|
12
|
+
"last_error" text,
|
|
13
|
+
"cert_state" text DEFAULT 'none' NOT NULL,
|
|
14
|
+
"is_primary" boolean DEFAULT false NOT NULL,
|
|
15
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
16
|
+
);
|
|
17
|
+
--> statement-breakpoint
|
|
18
|
+
ALTER TABLE "domains" ADD CONSTRAINT "domains_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
19
|
+
CREATE UNIQUE INDEX "domains_app_hostname_uq" ON "domains" USING btree ("app_id","hostname");--> statement-breakpoint
|
|
20
|
+
CREATE UNIQUE INDEX "domains_verified_hostname_uq" ON "domains" USING btree ("hostname") WHERE "domains"."verified_at" IS NOT NULL;--> statement-breakpoint
|
|
21
|
+
CREATE UNIQUE INDEX "domains_primary_uq" ON "domains" USING btree ("app_id") WHERE "domains"."is_primary";--> statement-breakpoint
|
|
22
|
+
CREATE INDEX "domains_hostname_idx" ON "domains" USING btree ("hostname");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- NSO-293 (M4-02): abuse and moderation — the abuse_reports queue (public
|
|
2
|
+
-- report form + publish heuristic flags) and apps.locked_reason (super-admin
|
|
3
|
+
-- takedown). Additive only.
|
|
4
|
+
CREATE TYPE "public"."abuse_report_status" AS ENUM('open', 'resolved');--> statement-breakpoint
|
|
5
|
+
CREATE TABLE "abuse_reports" (
|
|
6
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
7
|
+
"app_id" text,
|
|
8
|
+
"host" text NOT NULL,
|
|
9
|
+
"reason" text NOT NULL,
|
|
10
|
+
"details" text DEFAULT '' NOT NULL,
|
|
11
|
+
"reporter_email" text,
|
|
12
|
+
"ip_hash" text,
|
|
13
|
+
"status" "abuse_report_status" DEFAULT 'open' NOT NULL,
|
|
14
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
15
|
+
"resolved_at" timestamp,
|
|
16
|
+
"resolved_by" text
|
|
17
|
+
);
|
|
18
|
+
--> statement-breakpoint
|
|
19
|
+
ALTER TABLE "apps" ADD COLUMN "locked_reason" text;--> statement-breakpoint
|
|
20
|
+
ALTER TABLE "abuse_reports" ADD CONSTRAINT "abuse_reports_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
|
21
|
+
ALTER TABLE "abuse_reports" ADD CONSTRAINT "abuse_reports_resolved_by_users_id_fk" FOREIGN KEY ("resolved_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
|
22
|
+
CREATE INDEX "abuse_reports_status_created_idx" ON "abuse_reports" USING btree ("status","created_at");--> statement-breakpoint
|
|
23
|
+
CREATE INDEX "abuse_reports_app_idx" ON "abuse_reports" USING btree ("app_id");
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- NSO-340: the public gallery. Generated by drizzle-kit, then the backfill
|
|
2
|
+
-- was added by hand. Additive only.
|
|
3
|
+
-- apps.published_at = when the production host last started serving a
|
|
4
|
+
-- version (publish sets it, unpublish / takedown clear it); backfilled from
|
|
5
|
+
-- the newest `app.publish` audit row, else the published version's creation.
|
|
6
|
+
-- Millisecond precision (the gallery cursor round-trips it through JS Date).
|
|
7
|
+
-- gallery_listed / gallery_description = the owner's opt-in (dashboard);
|
|
8
|
+
-- gallery_hidden_at = a super-admin hid the entry.
|
|
9
|
+
ALTER TABLE "apps" ADD COLUMN "published_at" timestamp;--> statement-breakpoint
|
|
10
|
+
ALTER TABLE "apps" ADD COLUMN "gallery_listed" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
|
11
|
+
ALTER TABLE "apps" ADD COLUMN "gallery_description" text;--> statement-breakpoint
|
|
12
|
+
ALTER TABLE "apps" ADD COLUMN "gallery_hidden_at" timestamp;--> statement-breakpoint
|
|
13
|
+
CREATE INDEX "apps_gallery_idx" ON "apps" USING btree ("published_at" DESC NULLS LAST,"slug" DESC NULLS LAST) WHERE "apps"."gallery_listed";--> statement-breakpoint
|
|
14
|
+
UPDATE "apps" AS a SET "published_at" = date_trunc('milliseconds', COALESCE(
|
|
15
|
+
(SELECT max(l."created_at") FROM "audit_log" l
|
|
16
|
+
WHERE l."workspace_id" = a."workspace_id" AND l."subject_type" = 'app'
|
|
17
|
+
AND l."target" = a."slug" AND l."action" = 'app.publish'),
|
|
18
|
+
(SELECT v."created_at" FROM "app_versions" v WHERE v."id" = a."published_version_id"),
|
|
19
|
+
now()
|
|
20
|
+
)) WHERE a."published_version_id" IS NOT NULL;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- NSO-346: opt-in platform modules a super-admin enabled per workspace
|
|
2
|
+
-- (dashboard). Generated by drizzle-kit. Additive only. A default module never
|
|
3
|
+
-- has a row; the limits provider's MODULE_ENABLED_<NAME> overrides a row.
|
|
4
|
+
CREATE TABLE "workspace_modules" (
|
|
5
|
+
"workspace_id" text NOT NULL,
|
|
6
|
+
"module" text NOT NULL,
|
|
7
|
+
"enabled_by" text,
|
|
8
|
+
"enabled_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
9
|
+
CONSTRAINT "workspace_modules_workspace_id_module_pk" PRIMARY KEY("workspace_id","module")
|
|
10
|
+
);
|
|
11
|
+
--> statement-breakpoint
|
|
12
|
+
ALTER TABLE "workspace_modules" ADD CONSTRAINT "workspace_modules_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
13
|
+
ALTER TABLE "workspace_modules" ADD CONSTRAINT "workspace_modules_enabled_by_users_id_fk" FOREIGN KEY ("enabled_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- NSO-358: app assets — binary files (images, video, audio, fonts) an app
|
|
2
|
+
-- serves at /assets/<name>; the bytes live on disk under ASSETS_DIR, the rows
|
|
3
|
+
-- here. Additive only.
|
|
4
|
+
CREATE TABLE "app_assets" (
|
|
5
|
+
"app_id" text NOT NULL,
|
|
6
|
+
"name" text NOT NULL,
|
|
7
|
+
"content_type" text NOT NULL,
|
|
8
|
+
"size" bigint NOT NULL,
|
|
9
|
+
"sha256" text NOT NULL,
|
|
10
|
+
"storage_key" text NOT NULL,
|
|
11
|
+
"created_by_user_id" text,
|
|
12
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
13
|
+
"updated_at" timestamp DEFAULT now() NOT NULL,
|
|
14
|
+
CONSTRAINT "app_assets_app_id_name_pk" PRIMARY KEY("app_id","name")
|
|
15
|
+
);
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
ALTER TABLE "app_assets" ADD CONSTRAINT "app_assets_app_id_apps_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."apps"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
18
|
+
ALTER TABLE "app_assets" ADD CONSTRAINT "app_assets_created_by_user_id_users_id_fk" FOREIGN KEY ("created_by_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|