Compare commits
10 Commits
60f87472a1
...
136b58c44f
| Author | SHA1 | Date | |
|---|---|---|---|
| 136b58c44f | |||
| 5fddf2f394 | |||
| b6c6f74576 | |||
| b68935a11e | |||
| 0331042b8b | |||
| 8fe8ba68f8 | |||
| a0d12d4661 | |||
| 2c9b855d2a | |||
| 22c782c3ec | |||
| 450bcf173f |
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,6 +12,7 @@ node_modules
|
|||||||
*.log
|
*.log
|
||||||
|
|
||||||
# Databases
|
# Databases
|
||||||
|
/drizzle
|
||||||
*.db
|
*.db
|
||||||
|
|
||||||
# OS
|
# OS
|
||||||
|
|||||||
8
bun.lock
8
bun.lock
@ -6,11 +6,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"better-sqlite3": "^12.4.1",
|
"better-sqlite3": "^12.4.1",
|
||||||
"drizzle-orm": "^0.44.5",
|
"drizzle-orm": "^0.44.5",
|
||||||
|
"drizzle-seed": "^0.3.1",
|
||||||
"pino": "^9.11.0",
|
"pino": "^9.11.0",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/compat": "^1.2.5",
|
"@eslint/compat": "^1.2.5",
|
||||||
"@eslint/js": "^9.22.0",
|
"@eslint/js": "^9.22.0",
|
||||||
|
"@faker-js/faker": "^10.0.0",
|
||||||
"@sveltejs/adapter-auto": "^6.0.0",
|
"@sveltejs/adapter-auto": "^6.0.0",
|
||||||
"@sveltejs/kit": "^2.22.0",
|
"@sveltejs/kit": "^2.22.0",
|
||||||
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
||||||
@ -109,6 +111,8 @@
|
|||||||
|
|
||||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="],
|
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="],
|
||||||
|
|
||||||
|
"@faker-js/faker": ["@faker-js/faker@10.0.0", "", {}, "sha512-UollFEUkVXutsaP+Vndjxar40Gs5JL2HeLcl8xO1QAjJgOdhc3OmBFWyEylS+RddWaaBiAzH+5/17PLQJwDiLw=="],
|
||||||
|
|
||||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||||
|
|
||||||
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
||||||
@ -303,6 +307,8 @@
|
|||||||
|
|
||||||
"drizzle-orm": ["drizzle-orm@0.44.5", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-jBe37K7d8ZSKptdKfakQFdeljtu3P2Cbo7tJoJSVZADzIKOBo9IAJPOmMsH2bZl90bZgh8FQlD8BjxXA/zuBkQ=="],
|
"drizzle-orm": ["drizzle-orm@0.44.5", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-jBe37K7d8ZSKptdKfakQFdeljtu3P2Cbo7tJoJSVZADzIKOBo9IAJPOmMsH2bZl90bZgh8FQlD8BjxXA/zuBkQ=="],
|
||||||
|
|
||||||
|
"drizzle-seed": ["drizzle-seed@0.3.1", "", { "dependencies": { "pure-rand": "^6.1.0" }, "peerDependencies": { "drizzle-orm": ">=0.36.4" }, "optionalPeers": ["drizzle-orm"] }, "sha512-F/0lgvfOAsqlYoHM/QAGut4xXIOXoE5VoAdv2FIl7DpGYVXlAzKuJO+IphkKUFK3Dz+rFlOsQLnMNrvoQ0cx7g=="],
|
||||||
|
|
||||||
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
||||||
|
|
||||||
"esbuild": ["esbuild@0.25.10", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.10", "@esbuild/android-arm": "0.25.10", "@esbuild/android-arm64": "0.25.10", "@esbuild/android-x64": "0.25.10", "@esbuild/darwin-arm64": "0.25.10", "@esbuild/darwin-x64": "0.25.10", "@esbuild/freebsd-arm64": "0.25.10", "@esbuild/freebsd-x64": "0.25.10", "@esbuild/linux-arm": "0.25.10", "@esbuild/linux-arm64": "0.25.10", "@esbuild/linux-ia32": "0.25.10", "@esbuild/linux-loong64": "0.25.10", "@esbuild/linux-mips64el": "0.25.10", "@esbuild/linux-ppc64": "0.25.10", "@esbuild/linux-riscv64": "0.25.10", "@esbuild/linux-s390x": "0.25.10", "@esbuild/linux-x64": "0.25.10", "@esbuild/netbsd-arm64": "0.25.10", "@esbuild/netbsd-x64": "0.25.10", "@esbuild/openbsd-arm64": "0.25.10", "@esbuild/openbsd-x64": "0.25.10", "@esbuild/openharmony-arm64": "0.25.10", "@esbuild/sunos-x64": "0.25.10", "@esbuild/win32-arm64": "0.25.10", "@esbuild/win32-ia32": "0.25.10", "@esbuild/win32-x64": "0.25.10" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ=="],
|
"esbuild": ["esbuild@0.25.10", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.10", "@esbuild/android-arm": "0.25.10", "@esbuild/android-arm64": "0.25.10", "@esbuild/android-x64": "0.25.10", "@esbuild/darwin-arm64": "0.25.10", "@esbuild/darwin-x64": "0.25.10", "@esbuild/freebsd-arm64": "0.25.10", "@esbuild/freebsd-x64": "0.25.10", "@esbuild/linux-arm": "0.25.10", "@esbuild/linux-arm64": "0.25.10", "@esbuild/linux-ia32": "0.25.10", "@esbuild/linux-loong64": "0.25.10", "@esbuild/linux-mips64el": "0.25.10", "@esbuild/linux-ppc64": "0.25.10", "@esbuild/linux-riscv64": "0.25.10", "@esbuild/linux-s390x": "0.25.10", "@esbuild/linux-x64": "0.25.10", "@esbuild/netbsd-arm64": "0.25.10", "@esbuild/netbsd-x64": "0.25.10", "@esbuild/openbsd-arm64": "0.25.10", "@esbuild/openbsd-x64": "0.25.10", "@esbuild/openharmony-arm64": "0.25.10", "@esbuild/sunos-x64": "0.25.10", "@esbuild/win32-arm64": "0.25.10", "@esbuild/win32-ia32": "0.25.10", "@esbuild/win32-x64": "0.25.10" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ=="],
|
||||||
@ -507,6 +513,8 @@
|
|||||||
|
|
||||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||||
|
|
||||||
|
"pure-rand": ["pure-rand@6.1.0", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="],
|
||||||
|
|
||||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||||
|
|
||||||
"quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="],
|
"quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="],
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
CREATE TABLE `records` (
|
|
||||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
||||||
`record_id` text NOT NULL,
|
|
||||||
`type_id` integer NOT NULL,
|
|
||||||
FOREIGN KEY (`type_id`) REFERENCES `record_types`(`id`) ON UPDATE no action ON DELETE no action
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `records_record_id_unique` ON `records` (`record_id`);--> statement-breakpoint
|
|
||||||
CREATE INDEX `chores_index` ON `records` (`record_id`) WHERE type_id = 1;--> statement-breakpoint
|
|
||||||
CREATE INDEX `project_index` ON `records` (`record_id`) WHERE type_id = 2;--> statement-breakpoint
|
|
||||||
CREATE INDEX `ticket_index` ON `records` (`record_id`) WHERE type_id = 3;--> statement-breakpoint
|
|
||||||
CREATE TABLE `record_types` (
|
|
||||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
||||||
`type` text
|
|
||||||
);
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "6",
|
|
||||||
"dialect": "sqlite",
|
|
||||||
"id": "feb276b9-6e2b-4204-885b-167701a4a707",
|
|
||||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
|
||||||
"tables": {
|
|
||||||
"records": {
|
|
||||||
"name": "records",
|
|
||||||
"columns": {
|
|
||||||
"id": {
|
|
||||||
"name": "id",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": true,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": true
|
|
||||||
},
|
|
||||||
"record_id": {
|
|
||||||
"name": "record_id",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"type_id": {
|
|
||||||
"name": "type_id",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"records_record_id_unique": {
|
|
||||||
"name": "records_record_id_unique",
|
|
||||||
"columns": [
|
|
||||||
"record_id"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
},
|
|
||||||
"chores_index": {
|
|
||||||
"name": "chores_index",
|
|
||||||
"columns": [
|
|
||||||
"record_id"
|
|
||||||
],
|
|
||||||
"isUnique": false,
|
|
||||||
"where": "type_id = 1"
|
|
||||||
},
|
|
||||||
"project_index": {
|
|
||||||
"name": "project_index",
|
|
||||||
"columns": [
|
|
||||||
"record_id"
|
|
||||||
],
|
|
||||||
"isUnique": false,
|
|
||||||
"where": "type_id = 2"
|
|
||||||
},
|
|
||||||
"ticket_index": {
|
|
||||||
"name": "ticket_index",
|
|
||||||
"columns": [
|
|
||||||
"record_id"
|
|
||||||
],
|
|
||||||
"isUnique": false,
|
|
||||||
"where": "type_id = 3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"foreignKeys": {
|
|
||||||
"records_type_id_record_types_id_fk": {
|
|
||||||
"name": "records_type_id_record_types_id_fk",
|
|
||||||
"tableFrom": "records",
|
|
||||||
"tableTo": "record_types",
|
|
||||||
"columnsFrom": [
|
|
||||||
"type_id"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {},
|
|
||||||
"checkConstraints": {}
|
|
||||||
},
|
|
||||||
"record_types": {
|
|
||||||
"name": "record_types",
|
|
||||||
"columns": {
|
|
||||||
"id": {
|
|
||||||
"name": "id",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": true,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": true
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"name": "type",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {},
|
|
||||||
"checkConstraints": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"views": {},
|
|
||||||
"enums": {},
|
|
||||||
"_meta": {
|
|
||||||
"schemas": {},
|
|
||||||
"tables": {},
|
|
||||||
"columns": {}
|
|
||||||
},
|
|
||||||
"internal": {
|
|
||||||
"indexes": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "7",
|
|
||||||
"dialect": "sqlite",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"idx": 0,
|
|
||||||
"version": "6",
|
|
||||||
"when": 1758833816361,
|
|
||||||
"tag": "0000_wandering_riptide",
|
|
||||||
"breakpoints": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -15,6 +15,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/compat": "^1.2.5",
|
"@eslint/compat": "^1.2.5",
|
||||||
"@eslint/js": "^9.22.0",
|
"@eslint/js": "^9.22.0",
|
||||||
|
"@faker-js/faker": "^10.0.0",
|
||||||
"@sveltejs/adapter-auto": "^6.0.0",
|
"@sveltejs/adapter-auto": "^6.0.0",
|
||||||
"@sveltejs/kit": "^2.22.0",
|
"@sveltejs/kit": "^2.22.0",
|
||||||
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
||||||
@ -35,6 +36,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"better-sqlite3": "^12.4.1",
|
"better-sqlite3": "^12.4.1",
|
||||||
"drizzle-orm": "^0.44.5",
|
"drizzle-orm": "^0.44.5",
|
||||||
|
"drizzle-seed": "^0.3.1",
|
||||||
"pino": "^9.11.0"
|
"pino": "^9.11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import * as schema2 from "$lib/server/db/schema/records";
|
import * as schema2 from "$lib/server/db/schema/records";
|
||||||
import * as schema1 from "$lib/server/db/schema/recordTypes";
|
import * as schema1 from "$lib/server/db/schema/recordTypes";
|
||||||
|
import * as schema3 from "$lib/server/db/schema/tasks";
|
||||||
import { Database } from "bun:sqlite";
|
import { Database } from "bun:sqlite";
|
||||||
import { drizzle } from "drizzle-orm/bun-sqlite";
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
||||||
|
|
||||||
const sqlite = new Database("sqlite.db");
|
const sqlite = new Database("sqlite.db");
|
||||||
export const db = drizzle({ client: sqlite, schema: { ...schema1, ...schema2 } });
|
export const db = drizzle({ client: sqlite, schema: { ...schema1, ...schema2, ...schema3 } });
|
||||||
|
export type DB = typeof db;
|
||||||
|
|||||||
71
src/lib/server/db/schema/tasks.ts
Normal file
71
src/lib/server/db/schema/tasks.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { relations, sql } from "drizzle-orm";
|
||||||
|
import { type AnySQLiteColumn, check, int, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
||||||
|
|
||||||
|
export type TaskIntegrationConfigs = {
|
||||||
|
source_control: Array<{
|
||||||
|
repo_id: string;
|
||||||
|
commits: Array<{
|
||||||
|
hash: string;
|
||||||
|
message: string;
|
||||||
|
description?: string;
|
||||||
|
}>;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const taskTypes = sqliteTable("task_types", {
|
||||||
|
id: int("id").primaryKey({ autoIncrement: true }),
|
||||||
|
name: text("name").unique(),
|
||||||
|
prefix: text("prefix").unique(),
|
||||||
|
}, (table) => [
|
||||||
|
check("prefix_limit", sql`LENGTH(${table.prefix}) <=2`),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const taskTypesRelations = relations(taskTypes, ({ many }) => ({
|
||||||
|
tasks: many(tasks),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const tasks = sqliteTable("tasks", {
|
||||||
|
id: int("id").primaryKey({ autoIncrement: true }),
|
||||||
|
taskId: text("task_id").unique(),
|
||||||
|
description: text("description"),
|
||||||
|
type: int("type").references(() => taskTypes.id),
|
||||||
|
subtype: text("subtype"),
|
||||||
|
openDate: text("open_date").$type<Date["toISOString"]>(),
|
||||||
|
closeDate: text("close_date").$type<Date["toISOString"]>(),
|
||||||
|
status: text("status"),
|
||||||
|
priority: text("priority"),
|
||||||
|
parent: int("parent").references((): AnySQLiteColumn => tasks.id),
|
||||||
|
body: text("body"),
|
||||||
|
bodyHistory: text("body_history"),
|
||||||
|
checklist: text("checklist", { mode: "json" }).$type<
|
||||||
|
{
|
||||||
|
enabled: boolean;
|
||||||
|
entries: Array<{
|
||||||
|
group?: string;
|
||||||
|
sort_order: number;
|
||||||
|
checked: boolean;
|
||||||
|
text: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
>(),
|
||||||
|
updateChain: text("udpate_chain", { mode: "json" }).$type<
|
||||||
|
{
|
||||||
|
enabled: boolean;
|
||||||
|
entries: Array<{
|
||||||
|
updated_on: Date["toISOString"];
|
||||||
|
updated_by: string;
|
||||||
|
body: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
>(),
|
||||||
|
integrations: text("integrations", { mode: "json" }).$type<
|
||||||
|
{ type: keyof TaskIntegrationConfigs; config: TaskIntegrationConfigs["source_control"] }
|
||||||
|
>(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const tasksRelations = relations(tasks, ({ one }) => ({
|
||||||
|
type: one(taskTypes, {
|
||||||
|
fields: [tasks.type],
|
||||||
|
references: [taskTypes.id],
|
||||||
|
}),
|
||||||
|
}));
|
||||||
@ -11,12 +11,14 @@ const loggerConfig: Record<string, pino.LoggerOptions> = {
|
|||||||
transport: {
|
transport: {
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
|
level: "debug",
|
||||||
target: "pino-pretty",
|
target: "pino-pretty",
|
||||||
options: {
|
options: {
|
||||||
colorize: true,
|
colorize: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
level: "debug",
|
||||||
target: "pino/file",
|
target: "pino/file",
|
||||||
options: {
|
options: {
|
||||||
destination: "./logs/dev.log",
|
destination: "./logs/dev.log",
|
||||||
|
|||||||
29
src/lib/server/services/tasks.ts
Normal file
29
src/lib/server/services/tasks.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { type DB, db } from "$lib/server/db/db";
|
||||||
|
import logger from "../logger";
|
||||||
|
class TasksService {
|
||||||
|
private db: DB;
|
||||||
|
private caller: "internal" | "api";
|
||||||
|
|
||||||
|
constructor(caller: "internal" | "api", dbClient: DB = db) {
|
||||||
|
this.db = dbClient;
|
||||||
|
this.caller = caller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getAll() {
|
||||||
|
logger.info("Fetching all task records...");
|
||||||
|
try {
|
||||||
|
const result = await this.db.query.tasks.findMany({
|
||||||
|
with: {
|
||||||
|
type: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
logger.debug(`Found ${result.length} records.`);
|
||||||
|
return result;
|
||||||
|
} catch (e) {
|
||||||
|
logger.error({ msg: "Error querying the database.", error: e });
|
||||||
|
return false as const;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TasksService;
|
||||||
10
src/routes/tasks/+page.server.ts
Normal file
10
src/routes/tasks/+page.server.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import TasksService from "$lib/server/services/tasks";
|
||||||
|
import type { PageServerLoad } from "./$types";
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async () => {
|
||||||
|
const tasks = new TasksService("internal");
|
||||||
|
return {
|
||||||
|
tasks: await tasks.getAll(),
|
||||||
|
test: "string",
|
||||||
|
};
|
||||||
|
};
|
||||||
32
src/routes/tasks/+page.svelte
Normal file
32
src/routes/tasks/+page.svelte
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { PageProps } from "./$types";
|
||||||
|
|
||||||
|
let { data }: PageProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if data.tasks}
|
||||||
|
<p>{data.tasks.length} total records.</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Id</strong></td>
|
||||||
|
<td><strong>Description</strong></td>
|
||||||
|
<td><strong>Status</strong></td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each data.tasks as task (task.id)}
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
>{task.type?.prefix +
|
||||||
|
task.taskId}</td
|
||||||
|
>
|
||||||
|
<td>{task.description}</td>
|
||||||
|
<td>{task.status}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{:else}
|
||||||
|
<p>There was an error accessing the database.</p>
|
||||||
|
{/if}
|
||||||
99
utils/seed.ts
Normal file
99
utils/seed.ts
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import { db } from "../src/lib/server/db/db";
|
||||||
|
import { tasks, taskTypes } from "../src/lib/server/db/schema/tasks";
|
||||||
|
import { faker } from "@faker-js/faker";
|
||||||
|
import logger from "../src/lib/server/logger";
|
||||||
|
|
||||||
|
async function resetDatabase() {
|
||||||
|
logger.info("Resetting database...");
|
||||||
|
// Delete in reverse order of creation to respect foreign key constraints
|
||||||
|
await db.delete(tasks);
|
||||||
|
await db.delete(taskTypes);
|
||||||
|
logger.info("Database reset complete.");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function seedDatabase(count: number) {
|
||||||
|
logger.info(`Seeding database with ${count} tasks...`);
|
||||||
|
|
||||||
|
// 1. Seed Task Types
|
||||||
|
const insertedTaskTypes = await db.insert(taskTypes).values([
|
||||||
|
{ name: "Product Change", prefix: "PC" },
|
||||||
|
{ name: "Task", prefix: "TA" },
|
||||||
|
]).returning();
|
||||||
|
logger.info(`Seeded ${insertedTaskTypes.length} task types.`);
|
||||||
|
|
||||||
|
if (insertedTaskTypes.length === 0) {
|
||||||
|
throw new Error("Task type seeding failed. Cannot seed tasks.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Seed Tasks
|
||||||
|
const newTasks = [];
|
||||||
|
const usedTaskIds = new Set<number>();
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
let randomId: number;
|
||||||
|
do {
|
||||||
|
randomId = Math.floor(100000 + Math.random() * 900000);
|
||||||
|
} while (usedTaskIds.has(randomId));
|
||||||
|
usedTaskIds.add(randomId);
|
||||||
|
|
||||||
|
newTasks.push({
|
||||||
|
// task_id with a guaranteed unique 6 digit number
|
||||||
|
taskId: randomId.toString(),
|
||||||
|
// a random phrase in each description
|
||||||
|
description: faker.lorem.sentence(),
|
||||||
|
// open_date with a valid date
|
||||||
|
openDate: faker.date.recent({ days: 30 }).toISOString(),
|
||||||
|
// a random paragraph in body
|
||||||
|
body: faker.lorem.paragraphs(3),
|
||||||
|
// other fields as needed
|
||||||
|
type: faker.helpers.arrayElement(insertedTaskTypes).id,
|
||||||
|
status: faker.helpers.arrayElement(["Todo", "In Progress", "Done", "Canceled"]),
|
||||||
|
priority: faker.helpers.arrayElement(["Low", "Medium", "High", "Urgent"]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Insert the new tasks in chunks to avoid exceeding driver limits
|
||||||
|
logger.info(`Inserting ${newTasks.length} tasks in chunks...`);
|
||||||
|
const chunkSize = 500;
|
||||||
|
let totalInserted = 0;
|
||||||
|
for (let i = 0; i < newTasks.length; i += chunkSize) {
|
||||||
|
const chunk = newTasks.slice(i, i + chunkSize);
|
||||||
|
const inserted = await db.insert(tasks).values(chunk).returning();
|
||||||
|
totalInserted += inserted.length;
|
||||||
|
logger.info(` ... inserted chunk ${Math.floor(i / chunkSize) + 1}, ${totalInserted}/${newTasks.length} tasks`);
|
||||||
|
}
|
||||||
|
logger.info(`Seeding complete. Total tasks inserted: ${totalInserted}.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const mode = process.argv[2];
|
||||||
|
|
||||||
|
// Default count if no flag is provided
|
||||||
|
let count = 20;
|
||||||
|
|
||||||
|
// Find and parse the --count flag
|
||||||
|
const countArg = process.argv.find((arg) => arg.startsWith("--count="));
|
||||||
|
if (countArg) {
|
||||||
|
const countValue = parseInt(countArg.split("=")[1], 10);
|
||||||
|
if (!isNaN(countValue) && countValue > 0) {
|
||||||
|
count = countValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode === "reset") {
|
||||||
|
await resetDatabase();
|
||||||
|
} else if (mode === "seed") {
|
||||||
|
// Seeding implies a reset first for a clean slate
|
||||||
|
await resetDatabase();
|
||||||
|
await seedDatabase(count);
|
||||||
|
} else {
|
||||||
|
logger.error('Invalid mode. Use "seed" or "reset".');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Script finished.");
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((e) => {
|
||||||
|
logger.error(e, "An error occurred during the script execution.");
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user