mirror of
https://github.com/hex248/sprint.git
synced 2026-02-07 18:23:03 +00:00
status colours
This commit is contained in:
3
bun.lock
3
bun.lock
@@ -44,6 +44,7 @@
|
|||||||
"@radix-ui/react-label": "^2.1.8",
|
"@radix-ui/react-label": "^2.1.8",
|
||||||
"@radix-ui/react-select": "^2.2.6",
|
"@radix-ui/react-select": "^2.2.6",
|
||||||
"@radix-ui/react-slot": "^1.2.4",
|
"@radix-ui/react-slot": "^1.2.4",
|
||||||
|
"@radix-ui/react-tabs": "^1.1.13",
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"@tauri-apps/api": "^2",
|
"@tauri-apps/api": "^2",
|
||||||
"@tauri-apps/plugin-opener": "^2",
|
"@tauri-apps/plugin-opener": "^2",
|
||||||
@@ -302,6 +303,8 @@
|
|||||||
|
|
||||||
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "optionalDependencies": { "@types/react": "19.2.7" }, "peerDependencies": { "react": "19.2.3" } }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="],
|
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "optionalDependencies": { "@types/react": "19.2.7" }, "peerDependencies": { "react": "19.2.3" } }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="],
|
||||||
|
|
||||||
|
"@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="],
|
||||||
|
|
||||||
"@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
|
"@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
|
||||||
|
|
||||||
"@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="],
|
"@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="],
|
||||||
|
|||||||
1
packages/backend/drizzle/0013_overrated_chamber.sql
Normal file
1
packages/backend/drizzle/0013_overrated_chamber.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "Organisation" RENAME COLUMN "statuses" TO "statusColours";
|
||||||
1
packages/backend/drizzle/0014_lucky_mother_askani.sql
Normal file
1
packages/backend/drizzle/0014_lucky_mother_askani.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "Organisation" RENAME COLUMN "statusColours" TO "statuses";
|
||||||
1
packages/backend/drizzle/0015_brainy_xavin.sql
Normal file
1
packages/backend/drizzle/0015_brainy_xavin.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "Organisation" ALTER COLUMN "statuses" SET DEFAULT '{"TO DO":"#fafafa","IN PROGRESS":"#f97316","REVIEW":"#8952bc","DONE":"#22c55e","REJECTED":"#ef4444","ARCHIVED":"#a1a1a1","MERGED":"#a1a1a1"}'::json;
|
||||||
627
packages/backend/drizzle/meta/0013_snapshot.json
Normal file
627
packages/backend/drizzle/meta/0013_snapshot.json
Normal file
@@ -0,0 +1,627 @@
|
|||||||
|
{
|
||||||
|
"id": "52b84100-1751-43fc-b296-93c8130d3df9",
|
||||||
|
"prevId": "5a513ffa-9a5f-42ef-a2bc-939e12a17824",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {
|
||||||
|
"public.Issue": {
|
||||||
|
"name": "Issue",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Issue_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"name": "projectId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"name": "number",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"name": "title",
|
||||||
|
"type": "varchar(256)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "varchar(2048)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "status",
|
||||||
|
"type": "varchar(24)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'TO DO'"
|
||||||
|
},
|
||||||
|
"creatorId": {
|
||||||
|
"name": "creatorId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"assigneeId": {
|
||||||
|
"name": "assigneeId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"unique_project_issue_number": {
|
||||||
|
"name": "unique_project_issue_number",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"expression": "projectId",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expression": "number",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isUnique": true,
|
||||||
|
"concurrently": false,
|
||||||
|
"method": "btree",
|
||||||
|
"with": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {
|
||||||
|
"Issue_projectId_Project_id_fk": {
|
||||||
|
"name": "Issue_projectId_Project_id_fk",
|
||||||
|
"tableFrom": "Issue",
|
||||||
|
"tableTo": "Project",
|
||||||
|
"columnsFrom": [
|
||||||
|
"projectId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"Issue_creatorId_User_id_fk": {
|
||||||
|
"name": "Issue_creatorId_User_id_fk",
|
||||||
|
"tableFrom": "Issue",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"creatorId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"Issue_assigneeId_User_id_fk": {
|
||||||
|
"name": "Issue_assigneeId_User_id_fk",
|
||||||
|
"tableFrom": "Issue",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"assigneeId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.Organisation": {
|
||||||
|
"name": "Organisation",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Organisation_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(256)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "varchar(1024)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"slug": {
|
||||||
|
"name": "slug",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"statusColours": {
|
||||||
|
"name": "statusColours",
|
||||||
|
"type": "json",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'{\"TO DO\":\"#ffffff\",\"IN PROGRESS\":\"#f97316\",\"REVIEW\":\"#a855f7\",\"DONE\":\"#22c55e\",\"REJECTED\":\"#ef4444\",\"ARCHIVED\":\"oklch(0.708 0 0)\",\"MERGED\":\"oklch(0.708 0 0)\"}'::json"
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"name": "updatedAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"Organisation_slug_unique": {
|
||||||
|
"name": "Organisation_slug_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"slug"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.OrganisationMember": {
|
||||||
|
"name": "OrganisationMember",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "OrganisationMember_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"organisationId": {
|
||||||
|
"name": "organisationId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"name": "role",
|
||||||
|
"type": "varchar(32)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"OrganisationMember_organisationId_Organisation_id_fk": {
|
||||||
|
"name": "OrganisationMember_organisationId_Organisation_id_fk",
|
||||||
|
"tableFrom": "OrganisationMember",
|
||||||
|
"tableTo": "Organisation",
|
||||||
|
"columnsFrom": [
|
||||||
|
"organisationId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"OrganisationMember_userId_User_id_fk": {
|
||||||
|
"name": "OrganisationMember_userId_User_id_fk",
|
||||||
|
"tableFrom": "OrganisationMember",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.Project": {
|
||||||
|
"name": "Project",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Project_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"type": "varchar(4)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(256)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"organisationId": {
|
||||||
|
"name": "organisationId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"creatorId": {
|
||||||
|
"name": "creatorId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"Project_organisationId_Organisation_id_fk": {
|
||||||
|
"name": "Project_organisationId_Organisation_id_fk",
|
||||||
|
"tableFrom": "Project",
|
||||||
|
"tableTo": "Organisation",
|
||||||
|
"columnsFrom": [
|
||||||
|
"organisationId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"Project_creatorId_User_id_fk": {
|
||||||
|
"name": "Project_creatorId_User_id_fk",
|
||||||
|
"tableFrom": "Project",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"creatorId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.Session": {
|
||||||
|
"name": "Session",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Session_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"csrfToken": {
|
||||||
|
"name": "csrfToken",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expiresAt": {
|
||||||
|
"name": "expiresAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"Session_userId_User_id_fk": {
|
||||||
|
"name": "Session_userId_User_id_fk",
|
||||||
|
"tableFrom": "Session",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.TimedSession": {
|
||||||
|
"name": "TimedSession",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "TimedSession_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"issueId": {
|
||||||
|
"name": "issueId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"timestamps": {
|
||||||
|
"name": "timestamps",
|
||||||
|
"type": "timestamp[]",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"endedAt": {
|
||||||
|
"name": "endedAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"TimedSession_userId_User_id_fk": {
|
||||||
|
"name": "TimedSession_userId_User_id_fk",
|
||||||
|
"tableFrom": "TimedSession",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"TimedSession_issueId_Issue_id_fk": {
|
||||||
|
"name": "TimedSession_issueId_Issue_id_fk",
|
||||||
|
"tableFrom": "TimedSession",
|
||||||
|
"tableTo": "Issue",
|
||||||
|
"columnsFrom": [
|
||||||
|
"issueId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.User": {
|
||||||
|
"name": "User",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "User_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"name": "username",
|
||||||
|
"type": "varchar(32)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"passwordHash": {
|
||||||
|
"name": "passwordHash",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"avatarURL": {
|
||||||
|
"name": "avatarURL",
|
||||||
|
"type": "varchar(512)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"name": "updatedAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"User_username_unique": {
|
||||||
|
"name": "User_username_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"username"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"roles": {},
|
||||||
|
"policies": {},
|
||||||
|
"views": {},
|
||||||
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
627
packages/backend/drizzle/meta/0014_snapshot.json
Normal file
627
packages/backend/drizzle/meta/0014_snapshot.json
Normal file
@@ -0,0 +1,627 @@
|
|||||||
|
{
|
||||||
|
"id": "1b7736f7-778a-4edf-b2f1-06d0ba1c605b",
|
||||||
|
"prevId": "52b84100-1751-43fc-b296-93c8130d3df9",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {
|
||||||
|
"public.Issue": {
|
||||||
|
"name": "Issue",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Issue_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"name": "projectId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"name": "number",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"name": "title",
|
||||||
|
"type": "varchar(256)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "varchar(2048)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "status",
|
||||||
|
"type": "varchar(24)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'TO DO'"
|
||||||
|
},
|
||||||
|
"creatorId": {
|
||||||
|
"name": "creatorId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"assigneeId": {
|
||||||
|
"name": "assigneeId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"unique_project_issue_number": {
|
||||||
|
"name": "unique_project_issue_number",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"expression": "projectId",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expression": "number",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isUnique": true,
|
||||||
|
"concurrently": false,
|
||||||
|
"method": "btree",
|
||||||
|
"with": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {
|
||||||
|
"Issue_projectId_Project_id_fk": {
|
||||||
|
"name": "Issue_projectId_Project_id_fk",
|
||||||
|
"tableFrom": "Issue",
|
||||||
|
"tableTo": "Project",
|
||||||
|
"columnsFrom": [
|
||||||
|
"projectId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"Issue_creatorId_User_id_fk": {
|
||||||
|
"name": "Issue_creatorId_User_id_fk",
|
||||||
|
"tableFrom": "Issue",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"creatorId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"Issue_assigneeId_User_id_fk": {
|
||||||
|
"name": "Issue_assigneeId_User_id_fk",
|
||||||
|
"tableFrom": "Issue",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"assigneeId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.Organisation": {
|
||||||
|
"name": "Organisation",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Organisation_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(256)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "varchar(1024)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"slug": {
|
||||||
|
"name": "slug",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"statuses": {
|
||||||
|
"name": "statuses",
|
||||||
|
"type": "json",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'{\"TO DO\":\"#fafafa\",\"IN PROGRESS\":\"#f97316\",\"REVIEW\":\"#8952bc\",\"DONE\":\"#22c55e\",\"REJECTED\":\"#ef4444\",\"ARCHIVED\":\"oklch(0.708 0 0)\",\"MERGED\":\"oklch(0.708 0 0)\"}'::json"
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"name": "updatedAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"Organisation_slug_unique": {
|
||||||
|
"name": "Organisation_slug_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"slug"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.OrganisationMember": {
|
||||||
|
"name": "OrganisationMember",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "OrganisationMember_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"organisationId": {
|
||||||
|
"name": "organisationId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"name": "role",
|
||||||
|
"type": "varchar(32)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"OrganisationMember_organisationId_Organisation_id_fk": {
|
||||||
|
"name": "OrganisationMember_organisationId_Organisation_id_fk",
|
||||||
|
"tableFrom": "OrganisationMember",
|
||||||
|
"tableTo": "Organisation",
|
||||||
|
"columnsFrom": [
|
||||||
|
"organisationId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"OrganisationMember_userId_User_id_fk": {
|
||||||
|
"name": "OrganisationMember_userId_User_id_fk",
|
||||||
|
"tableFrom": "OrganisationMember",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.Project": {
|
||||||
|
"name": "Project",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Project_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"type": "varchar(4)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(256)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"organisationId": {
|
||||||
|
"name": "organisationId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"creatorId": {
|
||||||
|
"name": "creatorId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"Project_organisationId_Organisation_id_fk": {
|
||||||
|
"name": "Project_organisationId_Organisation_id_fk",
|
||||||
|
"tableFrom": "Project",
|
||||||
|
"tableTo": "Organisation",
|
||||||
|
"columnsFrom": [
|
||||||
|
"organisationId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"Project_creatorId_User_id_fk": {
|
||||||
|
"name": "Project_creatorId_User_id_fk",
|
||||||
|
"tableFrom": "Project",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"creatorId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.Session": {
|
||||||
|
"name": "Session",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Session_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"csrfToken": {
|
||||||
|
"name": "csrfToken",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expiresAt": {
|
||||||
|
"name": "expiresAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"Session_userId_User_id_fk": {
|
||||||
|
"name": "Session_userId_User_id_fk",
|
||||||
|
"tableFrom": "Session",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.TimedSession": {
|
||||||
|
"name": "TimedSession",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "TimedSession_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"issueId": {
|
||||||
|
"name": "issueId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"timestamps": {
|
||||||
|
"name": "timestamps",
|
||||||
|
"type": "timestamp[]",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"endedAt": {
|
||||||
|
"name": "endedAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"TimedSession_userId_User_id_fk": {
|
||||||
|
"name": "TimedSession_userId_User_id_fk",
|
||||||
|
"tableFrom": "TimedSession",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"TimedSession_issueId_Issue_id_fk": {
|
||||||
|
"name": "TimedSession_issueId_Issue_id_fk",
|
||||||
|
"tableFrom": "TimedSession",
|
||||||
|
"tableTo": "Issue",
|
||||||
|
"columnsFrom": [
|
||||||
|
"issueId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.User": {
|
||||||
|
"name": "User",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "User_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"name": "username",
|
||||||
|
"type": "varchar(32)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"passwordHash": {
|
||||||
|
"name": "passwordHash",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"avatarURL": {
|
||||||
|
"name": "avatarURL",
|
||||||
|
"type": "varchar(512)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"name": "updatedAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"User_username_unique": {
|
||||||
|
"name": "User_username_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"username"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"roles": {},
|
||||||
|
"policies": {},
|
||||||
|
"views": {},
|
||||||
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
627
packages/backend/drizzle/meta/0015_snapshot.json
Normal file
627
packages/backend/drizzle/meta/0015_snapshot.json
Normal file
@@ -0,0 +1,627 @@
|
|||||||
|
{
|
||||||
|
"id": "2fc85f22-9bff-42da-9898-4f284b091724",
|
||||||
|
"prevId": "1b7736f7-778a-4edf-b2f1-06d0ba1c605b",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {
|
||||||
|
"public.Issue": {
|
||||||
|
"name": "Issue",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Issue_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"name": "projectId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"name": "number",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"name": "title",
|
||||||
|
"type": "varchar(256)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "varchar(2048)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "status",
|
||||||
|
"type": "varchar(24)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'TO DO'"
|
||||||
|
},
|
||||||
|
"creatorId": {
|
||||||
|
"name": "creatorId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"assigneeId": {
|
||||||
|
"name": "assigneeId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"unique_project_issue_number": {
|
||||||
|
"name": "unique_project_issue_number",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"expression": "projectId",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expression": "number",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isUnique": true,
|
||||||
|
"concurrently": false,
|
||||||
|
"method": "btree",
|
||||||
|
"with": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {
|
||||||
|
"Issue_projectId_Project_id_fk": {
|
||||||
|
"name": "Issue_projectId_Project_id_fk",
|
||||||
|
"tableFrom": "Issue",
|
||||||
|
"tableTo": "Project",
|
||||||
|
"columnsFrom": [
|
||||||
|
"projectId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"Issue_creatorId_User_id_fk": {
|
||||||
|
"name": "Issue_creatorId_User_id_fk",
|
||||||
|
"tableFrom": "Issue",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"creatorId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"Issue_assigneeId_User_id_fk": {
|
||||||
|
"name": "Issue_assigneeId_User_id_fk",
|
||||||
|
"tableFrom": "Issue",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"assigneeId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.Organisation": {
|
||||||
|
"name": "Organisation",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Organisation_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(256)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "varchar(1024)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"slug": {
|
||||||
|
"name": "slug",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"statuses": {
|
||||||
|
"name": "statuses",
|
||||||
|
"type": "json",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'{\"TO DO\":\"#fafafa\",\"IN PROGRESS\":\"#f97316\",\"REVIEW\":\"#8952bc\",\"DONE\":\"#22c55e\",\"REJECTED\":\"#ef4444\",\"ARCHIVED\":\"#a1a1a1\",\"MERGED\":\"#a1a1a1\"}'::json"
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"name": "updatedAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"Organisation_slug_unique": {
|
||||||
|
"name": "Organisation_slug_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"slug"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.OrganisationMember": {
|
||||||
|
"name": "OrganisationMember",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "OrganisationMember_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"organisationId": {
|
||||||
|
"name": "organisationId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"name": "role",
|
||||||
|
"type": "varchar(32)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"OrganisationMember_organisationId_Organisation_id_fk": {
|
||||||
|
"name": "OrganisationMember_organisationId_Organisation_id_fk",
|
||||||
|
"tableFrom": "OrganisationMember",
|
||||||
|
"tableTo": "Organisation",
|
||||||
|
"columnsFrom": [
|
||||||
|
"organisationId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"OrganisationMember_userId_User_id_fk": {
|
||||||
|
"name": "OrganisationMember_userId_User_id_fk",
|
||||||
|
"tableFrom": "OrganisationMember",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.Project": {
|
||||||
|
"name": "Project",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Project_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"type": "varchar(4)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(256)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"organisationId": {
|
||||||
|
"name": "organisationId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"creatorId": {
|
||||||
|
"name": "creatorId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"Project_organisationId_Organisation_id_fk": {
|
||||||
|
"name": "Project_organisationId_Organisation_id_fk",
|
||||||
|
"tableFrom": "Project",
|
||||||
|
"tableTo": "Organisation",
|
||||||
|
"columnsFrom": [
|
||||||
|
"organisationId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"Project_creatorId_User_id_fk": {
|
||||||
|
"name": "Project_creatorId_User_id_fk",
|
||||||
|
"tableFrom": "Project",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"creatorId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.Session": {
|
||||||
|
"name": "Session",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "Session_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"csrfToken": {
|
||||||
|
"name": "csrfToken",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expiresAt": {
|
||||||
|
"name": "expiresAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"Session_userId_User_id_fk": {
|
||||||
|
"name": "Session_userId_User_id_fk",
|
||||||
|
"tableFrom": "Session",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.TimedSession": {
|
||||||
|
"name": "TimedSession",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "TimedSession_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"issueId": {
|
||||||
|
"name": "issueId",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"timestamps": {
|
||||||
|
"name": "timestamps",
|
||||||
|
"type": "timestamp[]",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"endedAt": {
|
||||||
|
"name": "endedAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"TimedSession_userId_User_id_fk": {
|
||||||
|
"name": "TimedSession_userId_User_id_fk",
|
||||||
|
"tableFrom": "TimedSession",
|
||||||
|
"tableTo": "User",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"TimedSession_issueId_Issue_id_fk": {
|
||||||
|
"name": "TimedSession_issueId_Issue_id_fk",
|
||||||
|
"tableFrom": "TimedSession",
|
||||||
|
"tableTo": "Issue",
|
||||||
|
"columnsFrom": [
|
||||||
|
"issueId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.User": {
|
||||||
|
"name": "User",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"identity": {
|
||||||
|
"type": "always",
|
||||||
|
"name": "User_id_seq",
|
||||||
|
"schema": "public",
|
||||||
|
"increment": "1",
|
||||||
|
"startWith": "1",
|
||||||
|
"minValue": "1",
|
||||||
|
"maxValue": "2147483647",
|
||||||
|
"cache": "1",
|
||||||
|
"cycle": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"name": "username",
|
||||||
|
"type": "varchar(32)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"passwordHash": {
|
||||||
|
"name": "passwordHash",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"avatarURL": {
|
||||||
|
"name": "avatarURL",
|
||||||
|
"type": "varchar(512)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"name": "updatedAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"User_username_unique": {
|
||||||
|
"name": "User_username_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"username"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policies": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"roles": {},
|
||||||
|
"policies": {},
|
||||||
|
"views": {},
|
||||||
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -92,6 +92,27 @@
|
|||||||
"when": 1768072909149,
|
"when": 1768072909149,
|
||||||
"tag": "0012_yielding_inertia",
|
"tag": "0012_yielding_inertia",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 13,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1768078024355,
|
||||||
|
"tag": "0013_overrated_chamber",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 14,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1768080336334,
|
||||||
|
"tag": "0014_lucky_mother_askani",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 15,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1768081741089,
|
||||||
|
"tag": "0015_brainy_xavin",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,12 @@ export async function getOrganisationsByUserId(userId: number) {
|
|||||||
|
|
||||||
export async function updateOrganisation(
|
export async function updateOrganisation(
|
||||||
organisationId: number,
|
organisationId: number,
|
||||||
updates: { name?: string; description?: string; slug?: string; statuses?: string[] },
|
updates: {
|
||||||
|
name?: string;
|
||||||
|
description?: string;
|
||||||
|
slug?: string;
|
||||||
|
statuses?: Record<string, string>;
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
const [organisation] = await db
|
const [organisation] = await db
|
||||||
.update(Organisation)
|
.update(Organisation)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { ISSUE_STATUS_MAX_LENGTH } from "@issue/shared";
|
|||||||
import type { BunRequest } from "bun";
|
import type { BunRequest } from "bun";
|
||||||
import { getOrganisationById, updateOrganisation } from "../../db/queries";
|
import { getOrganisationById, updateOrganisation } from "../../db/queries";
|
||||||
|
|
||||||
// /organisation/update?id=1&name=New%20Name&description=New%20Description&slug=new-slug&statuses=["TO DO","IN PROGRESS"]
|
// /organisation/update?id=1&name=New%20Name&description=New%20Description&slug=new-slug
|
||||||
export default async function organisationUpdate(req: BunRequest) {
|
export default async function organisationUpdate(req: BunRequest) {
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const id = url.searchParams.get("id");
|
const id = url.searchParams.get("id");
|
||||||
@@ -11,24 +11,28 @@ export default async function organisationUpdate(req: BunRequest) {
|
|||||||
const slug = url.searchParams.get("slug") || undefined;
|
const slug = url.searchParams.get("slug") || undefined;
|
||||||
const statusesParam = url.searchParams.get("statuses");
|
const statusesParam = url.searchParams.get("statuses");
|
||||||
|
|
||||||
let statuses: string[] | undefined;
|
let statuses: Record<string, string> | undefined;
|
||||||
if (statusesParam) {
|
if (statusesParam) {
|
||||||
try {
|
try {
|
||||||
statuses = JSON.parse(statusesParam);
|
const parsed = JSON.parse(statusesParam);
|
||||||
if (!Array.isArray(statuses) || !statuses.every((s) => typeof s === "string")) {
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
||||||
return new Response("statuses must be an array of strings", { status: 400 });
|
return new Response("statuses must be an object", { status: 400 });
|
||||||
}
|
}
|
||||||
if (statuses.length === 0) {
|
const entries = Object.entries(parsed);
|
||||||
|
if (entries.length === 0) {
|
||||||
return new Response("statuses must have at least one status", { status: 400 });
|
return new Response("statuses must have at least one status", { status: 400 });
|
||||||
}
|
}
|
||||||
|
if (!entries.every(([key, value]) => typeof key === "string" && typeof value === "string")) {
|
||||||
if (statuses.some((s) => s.length > ISSUE_STATUS_MAX_LENGTH)) {
|
return new Response("statuses values must be strings", { status: 400 });
|
||||||
|
}
|
||||||
|
if (entries.some(([key]) => key.length > ISSUE_STATUS_MAX_LENGTH)) {
|
||||||
return new Response(`status must be <= ${ISSUE_STATUS_MAX_LENGTH} characters`, {
|
return new Response(`status must be <= ${ISSUE_STATUS_MAX_LENGTH} characters`, {
|
||||||
status: 400,
|
status: 400,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
statuses = parsed;
|
||||||
} catch {
|
} catch {
|
||||||
return new Response("invalid statuses format (must be JSON array)", { status: 400 });
|
return new Response("invalid statuses format (must be JSON object)", { status: 400 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export function CreateIssue({
|
|||||||
}: {
|
}: {
|
||||||
projectId?: number;
|
projectId?: number;
|
||||||
members?: UserRecord[];
|
members?: UserRecord[];
|
||||||
statuses?: string[];
|
statuses: Record<string, string>;
|
||||||
trigger?: React.ReactNode;
|
trigger?: React.ReactNode;
|
||||||
completeAction?: (issueId: number) => void | Promise<void>;
|
completeAction?: (issueId: number) => void | Promise<void>;
|
||||||
}) {
|
}) {
|
||||||
@@ -38,7 +38,7 @@ export function CreateIssue({
|
|||||||
const [title, setTitle] = useState("");
|
const [title, setTitle] = useState("");
|
||||||
const [description, setDescription] = useState("");
|
const [description, setDescription] = useState("");
|
||||||
const [assigneeId, setAssigneeId] = useState<string>("unassigned");
|
const [assigneeId, setAssigneeId] = useState<string>("unassigned");
|
||||||
const [status, setStatus] = useState<string>(statuses?.[0] ?? "");
|
const [status, setStatus] = useState<string>(Object.keys(statuses)[0] ?? "");
|
||||||
const [submitAttempted, setSubmitAttempted] = useState(false);
|
const [submitAttempted, setSubmitAttempted] = useState(false);
|
||||||
const [submitting, setSubmitting] = useState(false);
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
@@ -130,7 +130,7 @@ export function CreateIssue({
|
|||||||
|
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div className="grid">
|
<div className="grid">
|
||||||
{statuses && statuses.length > 0 && (
|
{statuses && Object.keys(statuses).length > 0 && (
|
||||||
<div className="flex flex-col gap-2 mb-4">
|
<div className="flex flex-col gap-2 mb-4">
|
||||||
<Label>Status</Label>
|
<Label>Status</Label>
|
||||||
<StatusSelect
|
<StatusSelect
|
||||||
@@ -150,7 +150,8 @@ export function CreateIssue({
|
|||||||
>
|
>
|
||||||
<StatusTag
|
<StatusTag
|
||||||
status={value}
|
status={value}
|
||||||
className="group-hover:bg-foreground/75"
|
colour={statuses[value]}
|
||||||
|
className="hover:opacity-85"
|
||||||
/>
|
/>
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export function IssueDetailPane({
|
|||||||
project: ProjectResponse;
|
project: ProjectResponse;
|
||||||
issueData: IssueResponse;
|
issueData: IssueResponse;
|
||||||
members: UserRecord[];
|
members: UserRecord[];
|
||||||
statuses: string[];
|
statuses: Record<string, string>;
|
||||||
close: () => void;
|
close: () => void;
|
||||||
onIssueUpdate?: () => void;
|
onIssueUpdate?: () => void;
|
||||||
}) {
|
}) {
|
||||||
@@ -98,7 +98,11 @@ export function IssueDetailPane({
|
|||||||
chevronClassName="hidden"
|
chevronClassName="hidden"
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
>
|
>
|
||||||
<StatusTag status={value} className="group-hover:bg-foreground/75" />
|
<StatusTag
|
||||||
|
status={value}
|
||||||
|
colour={statuses[value]}
|
||||||
|
className="hover:opacity-85"
|
||||||
|
/>
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ export function IssuesTable({
|
|||||||
issuesData,
|
issuesData,
|
||||||
columns = {},
|
columns = {},
|
||||||
issueSelectAction,
|
issueSelectAction,
|
||||||
|
statuses,
|
||||||
className,
|
className,
|
||||||
}: {
|
}: {
|
||||||
issuesData: IssueResponse[];
|
issuesData: IssueResponse[];
|
||||||
columns?: { id?: boolean; title?: boolean; description?: boolean; status?: boolean; assignee?: boolean };
|
columns?: { id?: boolean; title?: boolean; description?: boolean; status?: boolean; assignee?: boolean };
|
||||||
issueSelectAction?: (issue: IssueResponse) => void;
|
issueSelectAction?: (issue: IssueResponse) => void;
|
||||||
|
statuses: Record<string, string>;
|
||||||
className: string;
|
className: string;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
@@ -48,7 +50,10 @@ export function IssuesTable({
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
<span className="flex items-center gap-2 max-w-full truncate">
|
<span className="flex items-center gap-2 max-w-full truncate">
|
||||||
{(columns.status == null || columns.status === true) && (
|
{(columns.status == null || columns.status === true) && (
|
||||||
<StatusTag status={issueData.Issue.status} />
|
<StatusTag
|
||||||
|
status={issueData.Issue.status}
|
||||||
|
colour={statuses[issueData.Issue.status]}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{issueData.Issue.title}
|
{issueData.Issue.title}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
DEFAULT_STATUS_COLOUR,
|
||||||
ISSUE_STATUS_MAX_LENGTH,
|
ISSUE_STATUS_MAX_LENGTH,
|
||||||
type OrganisationMemberResponse,
|
type OrganisationMemberResponse,
|
||||||
type OrganisationResponse,
|
type OrganisationResponse,
|
||||||
@@ -38,7 +39,7 @@ function OrganisationsDialog({
|
|||||||
const [activeTab, setActiveTab] = useState("info");
|
const [activeTab, setActiveTab] = useState("info");
|
||||||
const [members, setMembers] = useState<OrganisationMemberResponse[]>([]);
|
const [members, setMembers] = useState<OrganisationMemberResponse[]>([]);
|
||||||
|
|
||||||
const [statuses, setStatuses] = useState<string[]>([]);
|
const [statuses, setStatuses] = useState<Record<string, string>>({});
|
||||||
const [isCreatingStatus, setIsCreatingStatus] = useState(false);
|
const [isCreatingStatus, setIsCreatingStatus] = useState(false);
|
||||||
const [newStatusName, setNewStatusName] = useState("");
|
const [newStatusName, setNewStatusName] = useState("");
|
||||||
const [statusError, setStatusError] = useState<string | null>(null);
|
const [statusError, setStatusError] = useState<string | null>(null);
|
||||||
@@ -161,16 +162,13 @@ function OrganisationsDialog({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedOrganisation) {
|
if (selectedOrganisation) {
|
||||||
const orgStatuses = (selectedOrganisation.Organisation as unknown as { statuses: string[] })
|
setStatuses(selectedOrganisation.Organisation.statuses);
|
||||||
.statuses;
|
|
||||||
setStatuses(
|
|
||||||
Array.isArray(orgStatuses) ? orgStatuses : ["TO DO", "IN PROGRESS", "REVIEW", "DONE"],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}, [selectedOrganisation]);
|
}, [selectedOrganisation]);
|
||||||
|
|
||||||
const updateStatuses = async (newStatuses: string[]) => {
|
const updateStatuses = async (newStatuses: Record<string, string>) => {
|
||||||
if (!selectedOrganisation) return;
|
if (!selectedOrganisation) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await organisation.update({
|
await organisation.update({
|
||||||
organisationId: selectedOrganisation.Organisation.id,
|
organisationId: selectedOrganisation.Organisation.id,
|
||||||
@@ -197,14 +195,14 @@ function OrganisationsDialog({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statuses.includes(trimmed)) {
|
if (Object.keys(statuses).includes(trimmed)) {
|
||||||
setNewStatusName("");
|
setNewStatusName("");
|
||||||
setIsCreatingStatus(false);
|
setIsCreatingStatus(false);
|
||||||
setStatusError(null);
|
setStatusError(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const newStatuses = { ...statuses };
|
||||||
const newStatuses = [...statuses, trimmed];
|
newStatuses[trimmed] = DEFAULT_STATUS_COLOUR;
|
||||||
await updateStatuses(newStatuses);
|
await updateStatuses(newStatuses);
|
||||||
setNewStatusName("");
|
setNewStatusName("");
|
||||||
setIsCreatingStatus(false);
|
setIsCreatingStatus(false);
|
||||||
@@ -212,26 +210,25 @@ function OrganisationsDialog({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoveStatusClick = (status: string) => {
|
const handleRemoveStatusClick = (status: string) => {
|
||||||
if (statuses.length <= 1) return;
|
if (Object.keys(statuses).length <= 1) return;
|
||||||
setStatusToRemove(status);
|
setStatusToRemove(status);
|
||||||
const remaining = statuses.filter((s) => s !== status);
|
const remaining = Object.keys(statuses).filter((s) => s !== status);
|
||||||
setReassignToStatus(remaining[0] || "");
|
setReassignToStatus(remaining[0] || "");
|
||||||
};
|
};
|
||||||
|
|
||||||
const moveStatus = async (status: string, direction: "up" | "down") => {
|
const moveStatus = async (status: string, direction: "up" | "down") => {
|
||||||
const currentIndex = statuses.indexOf(status);
|
const currentIndex = Object.keys(statuses).indexOf(status);
|
||||||
if (currentIndex === -1) return;
|
if (currentIndex === -1) return;
|
||||||
|
|
||||||
const nextIndex = direction === "up" ? currentIndex - 1 : currentIndex + 1;
|
const nextIndex = direction === "up" ? currentIndex - 1 : currentIndex + 1;
|
||||||
if (nextIndex < 0 || nextIndex >= statuses.length) return;
|
if (nextIndex < 0 || nextIndex >= Object.keys(statuses).length) return;
|
||||||
|
const nextStatuses = [...Object.keys(statuses)];
|
||||||
const nextStatuses = [...statuses];
|
|
||||||
[nextStatuses[currentIndex], nextStatuses[nextIndex]] = [
|
[nextStatuses[currentIndex], nextStatuses[nextIndex]] = [
|
||||||
nextStatuses[nextIndex],
|
nextStatuses[nextIndex],
|
||||||
nextStatuses[currentIndex],
|
nextStatuses[currentIndex],
|
||||||
];
|
];
|
||||||
|
|
||||||
await updateStatuses(nextStatuses);
|
await updateStatuses(Object.fromEntries(nextStatuses.map((status) => [status, statuses[status]])));
|
||||||
};
|
};
|
||||||
|
|
||||||
const confirmRemoveStatus = async () => {
|
const confirmRemoveStatus = async () => {
|
||||||
@@ -242,8 +239,10 @@ function OrganisationsDialog({
|
|||||||
oldStatus: statusToRemove,
|
oldStatus: statusToRemove,
|
||||||
newStatus: reassignToStatus,
|
newStatus: reassignToStatus,
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
const newStatuses = statuses.filter((s) => s !== statusToRemove);
|
const newStatuses = Object.keys(statuses).filter((s) => s !== statusToRemove);
|
||||||
await updateStatuses(newStatuses);
|
await updateStatuses(
|
||||||
|
Object.fromEntries(newStatuses.map((status) => [status, statuses[status]])),
|
||||||
|
);
|
||||||
setStatusToRemove(null);
|
setStatusToRemove(null);
|
||||||
setReassignToStatus("");
|
setReassignToStatus("");
|
||||||
},
|
},
|
||||||
@@ -406,13 +405,19 @@ function OrganisationsDialog({
|
|||||||
<div className="border p-2 min-w-0 overflow-hidden">
|
<div className="border p-2 min-w-0 overflow-hidden">
|
||||||
<h2 className="text-xl font-600 mb-2">Issue Statuses</h2>
|
<h2 className="text-xl font-600 mb-2">Issue Statuses</h2>
|
||||||
<div className="flex flex-col gap-2 w-full">
|
<div className="flex flex-col gap-2 w-full">
|
||||||
<div className="flex flex-col gap-2 max-h-56 overflow-y-scroll">
|
<div className="flex flex-col gap-2 max-h-86 overflow-y-scroll grid grid-cols-2">
|
||||||
{statuses.map((status, index) => (
|
{Object.keys(statuses).map((status, index) => (
|
||||||
<div
|
<div
|
||||||
key={status}
|
key={status}
|
||||||
className="flex items-center justify-between p-2 border"
|
className="flex items-center justify-between p-2 border"
|
||||||
>
|
>
|
||||||
<StatusTag status={status} />
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-sm">{index + 1}</span>
|
||||||
|
<StatusTag
|
||||||
|
status={status}
|
||||||
|
colour={statuses[status]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button
|
<Button
|
||||||
@@ -427,7 +432,9 @@ function OrganisationsDialog({
|
|||||||
<Button
|
<Button
|
||||||
variant="dummy"
|
variant="dummy"
|
||||||
size="none"
|
size="none"
|
||||||
disabled={index === statuses.length - 1}
|
disabled={
|
||||||
|
index === Object.keys(statuses).length - 1
|
||||||
|
}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
void moveStatus(status, "down")
|
void moveStatus(status, "down")
|
||||||
}
|
}
|
||||||
@@ -435,7 +442,7 @@ function OrganisationsDialog({
|
|||||||
>
|
>
|
||||||
<ChevronDown className="size-5 text-muted-foreground" />
|
<ChevronDown className="size-5 text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
{statuses.length > 1 && (
|
{Object.keys(statuses).length > 1 && (
|
||||||
<Button
|
<Button
|
||||||
variant="dummy"
|
variant="dummy"
|
||||||
size="none"
|
size="none"
|
||||||
@@ -563,11 +570,11 @@ function OrganisationsDialog({
|
|||||||
<SelectValue placeholder="Select status" />
|
<SelectValue placeholder="Select status" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{statuses
|
{Object.keys(statuses)
|
||||||
.filter((s) => s !== statusToRemove)
|
.filter((s) => s !== statusToRemove)
|
||||||
.map((status) => (
|
.map((status) => (
|
||||||
<SelectItem key={status} value={status}>
|
<SelectItem key={status} value={status}>
|
||||||
{status}
|
<StatusTag status={status} colour={statuses[status]} />
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export function StatusSelect({
|
|||||||
placeholder = "Select status",
|
placeholder = "Select status",
|
||||||
trigger,
|
trigger,
|
||||||
}: {
|
}: {
|
||||||
statuses: string[];
|
statuses: Record<string, string>;
|
||||||
value: string;
|
value: string;
|
||||||
onChange: (value: string) => void;
|
onChange: (value: string) => void;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@@ -33,9 +33,9 @@ export function StatusSelect({
|
|||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
)}
|
)}
|
||||||
<SelectContent side="bottom" position="popper" align="start">
|
<SelectContent side="bottom" position="popper" align="start">
|
||||||
{statuses.map((status) => (
|
{Object.entries(statuses).map(([status, colour]) => (
|
||||||
<SelectItem key={status} value={status} textClassName="text-xs">
|
<SelectItem key={status} value={status} textClassName="text-xs">
|
||||||
<StatusTag status={status} className="" />
|
<StatusTag status={status} colour={colour} />
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|||||||
@@ -1,12 +1,35 @@
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export default function StatusTag({ status, className }: { status: string; className?: string }) {
|
const DARK_TEXT_COLOUR = "#0a0a0a";
|
||||||
|
const THRESHOLD = 0.6;
|
||||||
|
|
||||||
|
const isLight = (hex: string): boolean => {
|
||||||
|
const num = Number.parseInt(hex.replace("#", ""), 16);
|
||||||
|
const r = (num >> 16) & 255;
|
||||||
|
const g = (num >> 8) & 255;
|
||||||
|
const b = num & 255;
|
||||||
|
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
||||||
|
return luminance > THRESHOLD;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function StatusTag({
|
||||||
|
status,
|
||||||
|
colour,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
status: string;
|
||||||
|
colour: string;
|
||||||
|
className?: string;
|
||||||
|
}) {
|
||||||
|
const textColour = isLight(colour) ? DARK_TEXT_COLOUR : "var(--foreground)";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"text-xs px-1 bg-foreground/85 rounded text-background inline-flex whitespace-nowrap",
|
"text-xs px-1 rounded inline-flex whitespace-nowrap border border-foreground/10",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
style={{ backgroundColor: colour, color: textColour }}
|
||||||
>
|
>
|
||||||
{status}
|
{status}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,14 +14,16 @@ export async function update({
|
|||||||
name?: string;
|
name?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
slug?: string;
|
slug?: string;
|
||||||
statuses?: string[];
|
statuses?: Record<string, string>;
|
||||||
} & ServerQueryInput) {
|
} & ServerQueryInput) {
|
||||||
const url = new URL(`${getServerURL()}/organisation/update`);
|
const url = new URL(`${getServerURL()}/organisation/update`);
|
||||||
url.searchParams.set("id", `${organisationId}`);
|
url.searchParams.set("id", `${organisationId}`);
|
||||||
if (name !== undefined) url.searchParams.set("name", name);
|
if (name !== undefined) url.searchParams.set("name", name);
|
||||||
if (description !== undefined) url.searchParams.set("description", description);
|
if (description !== undefined) url.searchParams.set("description", description);
|
||||||
if (slug !== undefined) url.searchParams.set("slug", slug);
|
if (slug !== undefined) url.searchParams.set("slug", slug);
|
||||||
if (statuses !== undefined) url.searchParams.set("statuses", JSON.stringify(statuses));
|
if (statuses !== undefined) {
|
||||||
|
url.searchParams.set("statuses", JSON.stringify(statuses));
|
||||||
|
}
|
||||||
|
|
||||||
const csrfToken = getCsrfToken();
|
const csrfToken = getCsrfToken();
|
||||||
const headers: HeadersInit = {};
|
const headers: HeadersInit = {};
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/** biome-ignore-all lint/correctness/useExhaustiveDependencies: <> */
|
/** biome-ignore-all lint/correctness/useExhaustiveDependencies: <> */
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
IssueResponse,
|
IssueResponse,
|
||||||
OrganisationMemberResponse,
|
OrganisationMemberResponse,
|
||||||
@@ -240,7 +241,7 @@ export default function App() {
|
|||||||
<CreateIssue
|
<CreateIssue
|
||||||
projectId={selectedProject?.Project.id}
|
projectId={selectedProject?.Project.id}
|
||||||
members={members}
|
members={members}
|
||||||
statuses={selectedOrganisation.Organisation.statuses as unknown as string[]}
|
statuses={selectedOrganisation.Organisation.statuses}
|
||||||
completeAction={async () => {
|
completeAction={async () => {
|
||||||
if (!selectedProject) return;
|
if (!selectedProject) return;
|
||||||
await refetchIssues();
|
await refetchIssues();
|
||||||
@@ -288,13 +289,14 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* main body */}
|
{/* main body */}
|
||||||
{selectedProject && issues.length > 0 && (
|
{selectedOrganisation && selectedProject && issues.length > 0 && (
|
||||||
<ResizablePanelGroup className={`flex-1`}>
|
<ResizablePanelGroup className={`flex-1`}>
|
||||||
<ResizablePanel id={"left"} minSize={400}>
|
<ResizablePanel id={"left"} minSize={400}>
|
||||||
{/* issues list (table) */}
|
{/* issues list (table) */}
|
||||||
<IssuesTable
|
<IssuesTable
|
||||||
issuesData={issues}
|
issuesData={issues}
|
||||||
columns={{ description: false }}
|
columns={{ description: false }}
|
||||||
|
statuses={selectedOrganisation.Organisation.statuses}
|
||||||
issueSelectAction={(issue) => {
|
issueSelectAction={(issue) => {
|
||||||
if (issue.Issue.id === selectedIssue?.Issue.id) setSelectedIssue(null);
|
if (issue.Issue.id === selectedIssue?.Issue.id) setSelectedIssue(null);
|
||||||
else setSelectedIssue(issue);
|
else setSelectedIssue(issue);
|
||||||
@@ -313,9 +315,7 @@ export default function App() {
|
|||||||
project={selectedProject}
|
project={selectedProject}
|
||||||
issueData={selectedIssue}
|
issueData={selectedIssue}
|
||||||
members={members}
|
members={members}
|
||||||
statuses={
|
statuses={selectedOrganisation.Organisation.statuses}
|
||||||
selectedOrganisation.Organisation.statuses as unknown as string[]
|
|
||||||
}
|
|
||||||
close={() => setSelectedIssue(null)}
|
close={() => setSelectedIssue(null)}
|
||||||
onIssueUpdate={refetchIssues}
|
onIssueUpdate={refetchIssues}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ export {
|
|||||||
USER_NAME_MAX_LENGTH,
|
USER_NAME_MAX_LENGTH,
|
||||||
USER_USERNAME_MAX_LENGTH,
|
USER_USERNAME_MAX_LENGTH,
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
IssueInsert,
|
IssueInsert,
|
||||||
IssueRecord,
|
IssueRecord,
|
||||||
@@ -33,6 +32,8 @@ export type {
|
|||||||
UserRecord,
|
UserRecord,
|
||||||
} from "./schema";
|
} from "./schema";
|
||||||
export {
|
export {
|
||||||
|
DEFAULT_STATUS_COLOUR,
|
||||||
|
DEFAULT_STATUS_COLOURS,
|
||||||
Issue,
|
Issue,
|
||||||
IssueInsertSchema,
|
IssueInsertSchema,
|
||||||
IssueSelectSchema,
|
IssueSelectSchema,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { integer, pgTable, timestamp, uniqueIndex, varchar } from "drizzle-orm/pg-core";
|
import { integer, json, pgTable, timestamp, uniqueIndex, varchar } from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||||
import type { z } from "zod";
|
import type { z } from "zod";
|
||||||
import {
|
import {
|
||||||
@@ -13,6 +13,18 @@ import {
|
|||||||
USER_USERNAME_MAX_LENGTH,
|
USER_USERNAME_MAX_LENGTH,
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
|
|
||||||
|
export const DEFAULT_STATUS_COLOUR = "#a1a1a1";
|
||||||
|
|
||||||
|
export const DEFAULT_STATUS_COLOURS: Record<string, string> = {
|
||||||
|
"TO DO": "#fafafa",
|
||||||
|
"IN PROGRESS": "#f97316",
|
||||||
|
REVIEW: "#8952bc",
|
||||||
|
DONE: "#22c55e",
|
||||||
|
REJECTED: "#ef4444",
|
||||||
|
ARCHIVED: DEFAULT_STATUS_COLOUR,
|
||||||
|
MERGED: DEFAULT_STATUS_COLOUR,
|
||||||
|
};
|
||||||
|
|
||||||
export const User = pgTable("User", {
|
export const User = pgTable("User", {
|
||||||
id: integer().primaryKey().generatedAlwaysAsIdentity(),
|
id: integer().primaryKey().generatedAlwaysAsIdentity(),
|
||||||
name: varchar({ length: USER_NAME_MAX_LENGTH }).notNull(),
|
name: varchar({ length: USER_NAME_MAX_LENGTH }).notNull(),
|
||||||
@@ -28,10 +40,7 @@ export const Organisation = pgTable("Organisation", {
|
|||||||
name: varchar({ length: ORG_NAME_MAX_LENGTH }).notNull(),
|
name: varchar({ length: ORG_NAME_MAX_LENGTH }).notNull(),
|
||||||
description: varchar({ length: ORG_DESCRIPTION_MAX_LENGTH }),
|
description: varchar({ length: ORG_DESCRIPTION_MAX_LENGTH }),
|
||||||
slug: varchar({ length: ORG_SLUG_MAX_LENGTH }).notNull().unique(),
|
slug: varchar({ length: ORG_SLUG_MAX_LENGTH }).notNull().unique(),
|
||||||
statuses: varchar({ length: ISSUE_STATUS_MAX_LENGTH })
|
statuses: json("statuses").$type<Record<string, string>>().notNull().default(DEFAULT_STATUS_COLOURS),
|
||||||
.array()
|
|
||||||
.notNull()
|
|
||||||
.default(["TO DO", "IN PROGRESS", "REVIEW", "DONE", "ARCHIVED", "MERGED"]),
|
|
||||||
createdAt: timestamp({ withTimezone: false }).defaultNow(),
|
createdAt: timestamp({ withTimezone: false }).defaultNow(),
|
||||||
updatedAt: timestamp({ withTimezone: false }).defaultNow(),
|
updatedAt: timestamp({ withTimezone: false }).defaultNow(),
|
||||||
});
|
});
|
||||||
@@ -135,7 +144,9 @@ export const TimedSessionInsertSchema = createInsertSchema(TimedSession);
|
|||||||
export type UserRecord = z.infer<typeof UserSelectSchema>;
|
export type UserRecord = z.infer<typeof UserSelectSchema>;
|
||||||
export type UserInsert = z.infer<typeof UserInsertSchema>;
|
export type UserInsert = z.infer<typeof UserInsertSchema>;
|
||||||
|
|
||||||
export type OrganisationRecord = z.infer<typeof OrganisationSelectSchema>;
|
export type OrganisationRecord = z.infer<typeof OrganisationSelectSchema> & {
|
||||||
|
statuses: Record<string, string>;
|
||||||
|
};
|
||||||
export type OrganisationInsert = z.infer<typeof OrganisationInsertSchema>;
|
export type OrganisationInsert = z.infer<typeof OrganisationInsertSchema>;
|
||||||
|
|
||||||
export type OrganisationMemberRecord = z.infer<typeof OrganisationMemberSelectSchema>;
|
export type OrganisationMemberRecord = z.infer<typeof OrganisationMemberSelectSchema>;
|
||||||
|
|||||||
Reference in New Issue
Block a user