feat: add board access settings (#249)
* wip: add board access settings * wip: add user access control * wip: add user access control * feat: add user access control * refactor: move away from mantine-modal-manager * fix: ci issues and failing tests * fix: lint issue * fix: format issue * fix: deepsource issues * chore: address pull request feedback
This commit is contained in:
@@ -14,10 +14,28 @@ CREATE TABLE `account` (
|
||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `app` (
|
||||
`id` text PRIMARY KEY NOT NULL,
|
||||
`name` text NOT NULL,
|
||||
`description` text,
|
||||
`icon_url` text NOT NULL,
|
||||
`href` text
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `boardPermission` (
|
||||
`board_id` text NOT NULL,
|
||||
`user_id` text NOT NULL,
|
||||
`permission` text NOT NULL,
|
||||
PRIMARY KEY(`board_id`, `permission`, `user_id`),
|
||||
FOREIGN KEY (`board_id`) REFERENCES `board`(`id`) ON UPDATE no action ON DELETE cascade,
|
||||
FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `board` (
|
||||
`id` text PRIMARY KEY NOT NULL,
|
||||
`name` text NOT NULL,
|
||||
`is_public` integer DEFAULT false NOT NULL,
|
||||
`creator_id` text,
|
||||
`page_title` text,
|
||||
`meta_title` text,
|
||||
`logo_image_url` text,
|
||||
@@ -30,7 +48,8 @@ CREATE TABLE `board` (
|
||||
`secondary_color` text DEFAULT '#fd7e14' NOT NULL,
|
||||
`opacity` integer DEFAULT 100 NOT NULL,
|
||||
`custom_css` text,
|
||||
`column_count` integer DEFAULT 10 NOT NULL
|
||||
`column_count` integer DEFAULT 10 NOT NULL,
|
||||
FOREIGN KEY (`creator_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE set null
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `integration_item` (
|
||||
@@ -1,7 +0,0 @@
|
||||
CREATE TABLE `app` (
|
||||
`id` text PRIMARY KEY NOT NULL,
|
||||
`name` text NOT NULL,
|
||||
`description` text,
|
||||
`icon_url` text NOT NULL,
|
||||
`href` text
|
||||
);
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "sqlite",
|
||||
"id": "7ba12cbf-d8eb-4469-b7c5-7f31acb7717d",
|
||||
"id": "7c2291ee-febd-4b90-994c-85e6ef27102d",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"tables": {
|
||||
"account": {
|
||||
@@ -111,6 +111,104 @@
|
||||
},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"app": {
|
||||
"name": "app",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"icon_url": {
|
||||
"name": "icon_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"href": {
|
||||
"name": "href",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"boardPermission": {
|
||||
"name": "boardPermission",
|
||||
"columns": {
|
||||
"board_id": {
|
||||
"name": "board_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"permission": {
|
||||
"name": "permission",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"boardPermission_board_id_board_id_fk": {
|
||||
"name": "boardPermission_board_id_board_id_fk",
|
||||
"tableFrom": "boardPermission",
|
||||
"tableTo": "board",
|
||||
"columnsFrom": ["board_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"boardPermission_user_id_user_id_fk": {
|
||||
"name": "boardPermission_user_id_user_id_fk",
|
||||
"tableFrom": "boardPermission",
|
||||
"tableTo": "user",
|
||||
"columnsFrom": ["user_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"boardPermission_board_id_user_id_permission_pk": {
|
||||
"columns": ["board_id", "permission", "user_id"],
|
||||
"name": "boardPermission_board_id_user_id_permission_pk"
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"board": {
|
||||
"name": "board",
|
||||
"columns": {
|
||||
@@ -136,6 +234,13 @@
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"creator_id": {
|
||||
"name": "creator_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"page_title": {
|
||||
"name": "page_title",
|
||||
"type": "text",
|
||||
@@ -242,7 +347,17 @@
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"foreignKeys": {
|
||||
"board_creator_id_user_id_fk": {
|
||||
"name": "board_creator_id_user_id_fk",
|
||||
"tableFrom": "board",
|
||||
"tableTo": "user",
|
||||
"columnsFrom": ["creator_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "set null",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
|
||||
@@ -1,722 +0,0 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "sqlite",
|
||||
"id": "f7263224-116a-42ba-8fb1-4574cb637880",
|
||||
"prevId": "7ba12cbf-d8eb-4469-b7c5-7f31acb7717d",
|
||||
"tables": {
|
||||
"account": {
|
||||
"name": "account",
|
||||
"columns": {
|
||||
"userId": {
|
||||
"name": "userId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"provider": {
|
||||
"name": "provider",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"providerAccountId": {
|
||||
"name": "providerAccountId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"refresh_token": {
|
||||
"name": "refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"access_token": {
|
||||
"name": "access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"token_type": {
|
||||
"name": "token_type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"scope": {
|
||||
"name": "scope",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"id_token": {
|
||||
"name": "id_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"session_state": {
|
||||
"name": "session_state",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"userId_idx": {
|
||||
"name": "userId_idx",
|
||||
"columns": ["userId"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"account_userId_user_id_fk": {
|
||||
"name": "account_userId_user_id_fk",
|
||||
"tableFrom": "account",
|
||||
"tableTo": "user",
|
||||
"columnsFrom": ["userId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"account_provider_providerAccountId_pk": {
|
||||
"columns": ["provider", "providerAccountId"],
|
||||
"name": "account_provider_providerAccountId_pk"
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"app": {
|
||||
"name": "app",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"icon_url": {
|
||||
"name": "icon_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"href": {
|
||||
"name": "href",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"board": {
|
||||
"name": "board",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"page_title": {
|
||||
"name": "page_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"meta_title": {
|
||||
"name": "meta_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"logo_image_url": {
|
||||
"name": "logo_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"favicon_image_url": {
|
||||
"name": "favicon_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"background_image_url": {
|
||||
"name": "background_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"background_image_attachment": {
|
||||
"name": "background_image_attachment",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'fixed'"
|
||||
},
|
||||
"background_image_repeat": {
|
||||
"name": "background_image_repeat",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'no-repeat'"
|
||||
},
|
||||
"background_image_size": {
|
||||
"name": "background_image_size",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'cover'"
|
||||
},
|
||||
"primary_color": {
|
||||
"name": "primary_color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'#fa5252'"
|
||||
},
|
||||
"secondary_color": {
|
||||
"name": "secondary_color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'#fd7e14'"
|
||||
},
|
||||
"opacity": {
|
||||
"name": "opacity",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": 100
|
||||
},
|
||||
"custom_css": {
|
||||
"name": "custom_css",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"column_count": {
|
||||
"name": "column_count",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": 10
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"board_name_unique": {
|
||||
"name": "board_name_unique",
|
||||
"columns": ["name"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"integration_item": {
|
||||
"name": "integration_item",
|
||||
"columns": {
|
||||
"item_id": {
|
||||
"name": "item_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"integration_id": {
|
||||
"name": "integration_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"integration_item_item_id_item_id_fk": {
|
||||
"name": "integration_item_item_id_item_id_fk",
|
||||
"tableFrom": "integration_item",
|
||||
"tableTo": "item",
|
||||
"columnsFrom": ["item_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"integration_item_integration_id_integration_id_fk": {
|
||||
"name": "integration_item_integration_id_integration_id_fk",
|
||||
"tableFrom": "integration_item",
|
||||
"tableTo": "integration",
|
||||
"columnsFrom": ["integration_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"integration_item_item_id_integration_id_pk": {
|
||||
"columns": ["integration_id", "item_id"],
|
||||
"name": "integration_item_item_id_integration_id_pk"
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"integrationSecret": {
|
||||
"name": "integrationSecret",
|
||||
"columns": {
|
||||
"kind": {
|
||||
"name": "kind",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"value": {
|
||||
"name": "value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"integration_id": {
|
||||
"name": "integration_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"integration_secret__kind_idx": {
|
||||
"name": "integration_secret__kind_idx",
|
||||
"columns": ["kind"],
|
||||
"isUnique": false
|
||||
},
|
||||
"integration_secret__updated_at_idx": {
|
||||
"name": "integration_secret__updated_at_idx",
|
||||
"columns": ["updated_at"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"integrationSecret_integration_id_integration_id_fk": {
|
||||
"name": "integrationSecret_integration_id_integration_id_fk",
|
||||
"tableFrom": "integrationSecret",
|
||||
"tableTo": "integration",
|
||||
"columnsFrom": ["integration_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"integrationSecret_integration_id_kind_pk": {
|
||||
"columns": ["integration_id", "kind"],
|
||||
"name": "integrationSecret_integration_id_kind_pk"
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"integration": {
|
||||
"name": "integration",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"kind": {
|
||||
"name": "kind",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"integration__kind_idx": {
|
||||
"name": "integration__kind_idx",
|
||||
"columns": ["kind"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"item": {
|
||||
"name": "item",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"section_id": {
|
||||
"name": "section_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"kind": {
|
||||
"name": "kind",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"x_offset": {
|
||||
"name": "x_offset",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"y_offset": {
|
||||
"name": "y_offset",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"width": {
|
||||
"name": "width",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"height": {
|
||||
"name": "height",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"options": {
|
||||
"name": "options",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'{\"json\": {}}'"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"item_section_id_section_id_fk": {
|
||||
"name": "item_section_id_section_id_fk",
|
||||
"tableFrom": "item",
|
||||
"tableTo": "section",
|
||||
"columnsFrom": ["section_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"section": {
|
||||
"name": "section",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"board_id": {
|
||||
"name": "board_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"kind": {
|
||||
"name": "kind",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"position": {
|
||||
"name": "position",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"section_board_id_board_id_fk": {
|
||||
"name": "section_board_id_board_id_fk",
|
||||
"tableFrom": "section",
|
||||
"tableTo": "board",
|
||||
"columnsFrom": ["board_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"session": {
|
||||
"name": "session",
|
||||
"columns": {
|
||||
"sessionToken": {
|
||||
"name": "sessionToken",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"userId": {
|
||||
"name": "userId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires": {
|
||||
"name": "expires",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"user_id_idx": {
|
||||
"name": "user_id_idx",
|
||||
"columns": ["userId"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"session_userId_user_id_fk": {
|
||||
"name": "session_userId_user_id_fk",
|
||||
"tableFrom": "session",
|
||||
"tableTo": "user",
|
||||
"columnsFrom": ["userId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"user": {
|
||||
"name": "user",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"emailVerified": {
|
||||
"name": "emailVerified",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password": {
|
||||
"name": "password",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"salt": {
|
||||
"name": "salt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"verificationToken": {
|
||||
"name": "verificationToken",
|
||||
"columns": {
|
||||
"identifier": {
|
||||
"name": "identifier",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"token": {
|
||||
"name": "token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires": {
|
||||
"name": "expires",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"verificationToken_identifier_token_pk": {
|
||||
"columns": ["identifier", "token"],
|
||||
"name": "verificationToken_identifier_token_pk"
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,8 @@
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "5",
|
||||
"when": 1709409142712,
|
||||
"tag": "0000_sloppy_bloodstorm",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "5",
|
||||
"when": 1709585624230,
|
||||
"tag": "0001_slim_swarm",
|
||||
"when": 1710878250235,
|
||||
"tag": "0000_productive_changeling",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -15,6 +15,7 @@ import type {
|
||||
BackgroundImageAttachment,
|
||||
BackgroundImageRepeat,
|
||||
BackgroundImageSize,
|
||||
BoardPermission,
|
||||
IntegrationKind,
|
||||
IntegrationSecretKind,
|
||||
SectionKind,
|
||||
@@ -97,8 +98,8 @@ export const integrations = mysqlTable(
|
||||
url: text("url").notNull(),
|
||||
kind: varchar("kind", { length: 128 }).$type<IntegrationKind>().notNull(),
|
||||
},
|
||||
(i) => ({
|
||||
kindIdx: index("integration__kind_idx").on(i.kind),
|
||||
(integrations) => ({
|
||||
kindIdx: index("integration__kind_idx").on(integrations.kind),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -127,6 +128,9 @@ export const boards = mysqlTable("board", {
|
||||
id: varchar("id", { length: 256 }).notNull().primaryKey(),
|
||||
name: varchar("name", { length: 256 }).unique().notNull(),
|
||||
isPublic: boolean("is_public").default(false).notNull(),
|
||||
creatorId: text("creator_id").references(() => users.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
pageTitle: text("page_title"),
|
||||
metaTitle: text("meta_title"),
|
||||
logoImageUrl: text("logo_image_url"),
|
||||
@@ -151,6 +155,24 @@ export const boards = mysqlTable("board", {
|
||||
columnCount: int("column_count").default(10).notNull(),
|
||||
});
|
||||
|
||||
export const boardPermissions = mysqlTable(
|
||||
"boardPermission",
|
||||
{
|
||||
boardId: text("board_id")
|
||||
.notNull()
|
||||
.references(() => boards.id, { onDelete: "cascade" }),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
permission: text("permission").$type<BoardPermission>().notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
compoundKey: primaryKey({
|
||||
columns: [table.boardId, table.userId, table.permission],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
export const sections = mysqlTable("section", {
|
||||
id: varchar("id", { length: 256 }).notNull().primaryKey(),
|
||||
boardId: varchar("board_id", { length: 256 })
|
||||
@@ -208,8 +230,25 @@ export const accountRelations = relations(accounts, ({ one }) => ({
|
||||
|
||||
export const userRelations = relations(users, ({ many }) => ({
|
||||
accounts: many(accounts),
|
||||
|
||||
boards: many(boards),
|
||||
boardPermissions: many(boardPermissions),
|
||||
}));
|
||||
|
||||
export const boardPermissionRelations = relations(
|
||||
boardPermissions,
|
||||
({ one }) => ({
|
||||
user: one(users, {
|
||||
fields: [boardPermissions.userId],
|
||||
references: [users.id],
|
||||
}),
|
||||
board: one(boards, {
|
||||
fields: [boardPermissions.boardId],
|
||||
references: [boards.id],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
export const integrationRelations = relations(integrations, ({ many }) => ({
|
||||
secrets: many(integrationSecrets),
|
||||
items: many(integrationItems),
|
||||
@@ -225,8 +264,13 @@ export const integrationSecretRelations = relations(
|
||||
}),
|
||||
);
|
||||
|
||||
export const boardRelations = relations(boards, ({ many }) => ({
|
||||
export const boardRelations = relations(boards, ({ many, one }) => ({
|
||||
sections: many(sections),
|
||||
creator: one(users, {
|
||||
fields: [boards.creatorId],
|
||||
references: [users.id],
|
||||
}),
|
||||
permissions: many(boardPermissions),
|
||||
}));
|
||||
|
||||
export const sectionRelations = relations(sections, ({ many, one }) => ({
|
||||
|
||||
@@ -19,6 +19,7 @@ import type {
|
||||
BackgroundImageAttachment,
|
||||
BackgroundImageRepeat,
|
||||
BackgroundImageSize,
|
||||
BoardPermission,
|
||||
IntegrationKind,
|
||||
IntegrationSecretKind,
|
||||
SectionKind,
|
||||
@@ -94,8 +95,8 @@ export const integrations = sqliteTable(
|
||||
url: text("url").notNull(),
|
||||
kind: text("kind").$type<IntegrationKind>().notNull(),
|
||||
},
|
||||
(i) => ({
|
||||
kindIdx: index("integration__kind_idx").on(i.kind),
|
||||
(integrations) => ({
|
||||
kindIdx: index("integration__kind_idx").on(integrations.kind),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -122,6 +123,9 @@ export const boards = sqliteTable("board", {
|
||||
id: text("id").notNull().primaryKey(),
|
||||
name: text("name").unique().notNull(),
|
||||
isPublic: int("is_public", { mode: "boolean" }).default(false).notNull(),
|
||||
creatorId: text("creator_id").references(() => users.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
pageTitle: text("page_title"),
|
||||
metaTitle: text("meta_title"),
|
||||
logoImageUrl: text("logo_image_url"),
|
||||
@@ -146,6 +150,24 @@ export const boards = sqliteTable("board", {
|
||||
columnCount: int("column_count").default(10).notNull(),
|
||||
});
|
||||
|
||||
export const boardPermissions = sqliteTable(
|
||||
"boardPermission",
|
||||
{
|
||||
boardId: text("board_id")
|
||||
.notNull()
|
||||
.references(() => boards.id, { onDelete: "cascade" }),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
permission: text("permission").$type<BoardPermission>().notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
compoundKey: primaryKey({
|
||||
columns: [table.boardId, table.userId, table.permission],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
export const sections = sqliteTable("section", {
|
||||
id: text("id").notNull().primaryKey(),
|
||||
boardId: text("board_id")
|
||||
@@ -203,8 +225,24 @@ export const accountRelations = relations(accounts, ({ one }) => ({
|
||||
|
||||
export const userRelations = relations(users, ({ many }) => ({
|
||||
accounts: many(accounts),
|
||||
boards: many(boards),
|
||||
boardPermissions: many(boardPermissions),
|
||||
}));
|
||||
|
||||
export const boardPermissionRelations = relations(
|
||||
boardPermissions,
|
||||
({ one }) => ({
|
||||
user: one(users, {
|
||||
fields: [boardPermissions.userId],
|
||||
references: [users.id],
|
||||
}),
|
||||
board: one(boards, {
|
||||
fields: [boardPermissions.boardId],
|
||||
references: [boards.id],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
export const integrationRelations = relations(integrations, ({ many }) => ({
|
||||
secrets: many(integrationSecrets),
|
||||
items: many(integrationItems),
|
||||
@@ -220,8 +258,13 @@ export const integrationSecretRelations = relations(
|
||||
}),
|
||||
);
|
||||
|
||||
export const boardRelations = relations(boards, ({ many }) => ({
|
||||
export const boardRelations = relations(boards, ({ many, one }) => ({
|
||||
sections: many(sections),
|
||||
creator: one(users, {
|
||||
fields: [boards.creatorId],
|
||||
references: [users.id],
|
||||
}),
|
||||
permissions: many(boardPermissions),
|
||||
}));
|
||||
|
||||
export const sectionRelations = relations(sections, ({ many, one }) => ({
|
||||
|
||||
@@ -51,7 +51,7 @@ test("schemas should match", () => {
|
||||
},
|
||||
);
|
||||
|
||||
const mysqlTable = mysqlSchema[tableName as keyof typeof mysqlSchema];
|
||||
const mysqlTable = mysqlSchema[tableName];
|
||||
const sqliteForeignKeys = sqliteTable[
|
||||
Symbol.for("drizzle:SQLiteInlineForeignKeys") as keyof typeof sqliteTable
|
||||
] as SqliteForeignKey[] | undefined;
|
||||
@@ -97,7 +97,9 @@ test("schemas should match", () => {
|
||||
|
||||
sqliteForeignKey.reference().foreignColumns.forEach((column) => {
|
||||
expect(
|
||||
mysqlForeignKey!.reference().foreignColumns.map((x) => x.name),
|
||||
mysqlForeignKey!
|
||||
.reference()
|
||||
.foreignColumns.map((column) => column.name),
|
||||
`expect foreign key (${sqliteForeignKey.getName()}) columns to be the same for both schemas`,
|
||||
).toContainEqual(column.name);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user