feat: add auth and database foundation

This commit is contained in:
2026-06-05 23:25:23 +01:00
parent 6c3cef4da2
commit 7bb19e1be3
35 changed files with 7497 additions and 0 deletions
+188
View File
@@ -0,0 +1,188 @@
CREATE TABLE `task` (
`id` text PRIMARY KEY NOT NULL,
`title` text NOT NULL,
`priority` integer DEFAULT 1 NOT NULL
);
--> statement-breakpoint
CREATE TABLE `clients` (
`id` text PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`type` text DEFAULT 'business' NOT NULL,
`status` text DEFAULT 'active' NOT NULL,
`email` text,
`phone` text,
`website` text,
`notes` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer
);
--> statement-breakpoint
CREATE TABLE `addresses` (
`id` text PRIMARY KEY NOT NULL,
`client_id` text NOT NULL,
`label` text NOT NULL,
`line_1` text NOT NULL,
`line_2` text,
`city` text NOT NULL,
`region` text,
`postcode` text NOT NULL,
`country` text DEFAULT 'United Kingdom' NOT NULL,
`is_primary` integer DEFAULT false NOT NULL,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer,
FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON UPDATE no action ON DELETE restrict
);
--> statement-breakpoint
CREATE INDEX `addresses_client_id_idx` ON `addresses` (`client_id`);--> statement-breakpoint
CREATE TABLE `contacts` (
`id` text PRIMARY KEY NOT NULL,
`client_id` text NOT NULL,
`name` text NOT NULL,
`role` text,
`email` text,
`phone` text,
`is_primary` integer DEFAULT false NOT NULL,
`notes` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer,
FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON UPDATE no action ON DELETE restrict
);
--> statement-breakpoint
CREATE INDEX `contacts_client_id_idx` ON `contacts` (`client_id`);--> statement-breakpoint
CREATE TABLE `rooms` (
`id` text PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`type` text DEFAULT 'room' NOT NULL,
`capacity` integer DEFAULT 1 NOT NULL,
`location` text,
`status` text DEFAULT 'available' NOT NULL,
`hourly_rate_cents` integer DEFAULT 0 NOT NULL,
`notes` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer
);
--> statement-breakpoint
CREATE TABLE `services` (
`id` text PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`category` text,
`unit` text DEFAULT 'each' NOT NULL,
`price_cents` integer DEFAULT 0 NOT NULL,
`description` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer
);
--> statement-breakpoint
CREATE TABLE `bookings` (
`id` text PRIMARY KEY NOT NULL,
`client_id` text NOT NULL,
`room_id` text NOT NULL,
`service_id` text,
`starts_at` text NOT NULL,
`ends_at` text NOT NULL,
`status` text DEFAULT 'booked' NOT NULL,
`notes` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer,
FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON UPDATE no action ON DELETE restrict,
FOREIGN KEY (`room_id`) REFERENCES `rooms`(`id`) ON UPDATE no action ON DELETE restrict,
FOREIGN KEY (`service_id`) REFERENCES `services`(`id`) ON UPDATE no action ON DELETE set null
);
--> statement-breakpoint
CREATE INDEX `bookings_client_id_idx` ON `bookings` (`client_id`);--> statement-breakpoint
CREATE INDEX `bookings_room_id_idx` ON `bookings` (`room_id`);--> statement-breakpoint
CREATE INDEX `bookings_service_id_idx` ON `bookings` (`service_id`);--> statement-breakpoint
CREATE TABLE `invoices` (
`id` text PRIMARY KEY NOT NULL,
`client_id` text NOT NULL,
`invoice_number` text NOT NULL,
`issue_date` text NOT NULL,
`due_date` text NOT NULL,
`status` text DEFAULT 'draft' NOT NULL,
`subtotal_cents` integer DEFAULT 0 NOT NULL,
`tax_cents` integer DEFAULT 0 NOT NULL,
`total_cents` integer DEFAULT 0 NOT NULL,
`notes` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer,
FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON UPDATE no action ON DELETE restrict
);
--> statement-breakpoint
CREATE UNIQUE INDEX `invoices_invoice_number_unique` ON `invoices` (`invoice_number`);--> statement-breakpoint
CREATE INDEX `invoices_client_id_idx` ON `invoices` (`client_id`);--> statement-breakpoint
CREATE TABLE `contracts` (
`id` text PRIMARY KEY NOT NULL,
`client_id` text NOT NULL,
`title` text NOT NULL,
`start_date` text NOT NULL,
`end_date` text,
`status` text DEFAULT 'draft' NOT NULL,
`value_cents` integer DEFAULT 0 NOT NULL,
`notes` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer,
FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON UPDATE no action ON DELETE restrict
);
--> statement-breakpoint
CREATE INDEX `contracts_client_id_idx` ON `contracts` (`client_id`);--> statement-breakpoint
CREATE TABLE `account` (
`id` text PRIMARY KEY NOT NULL,
`account_id` text NOT NULL,
`provider_id` text NOT NULL,
`user_id` text NOT NULL,
`access_token` text,
`refresh_token` text,
`id_token` text,
`access_token_expires_at` integer,
`refresh_token_expires_at` integer,
`scope` text,
`password` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer NOT NULL,
FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
);
--> statement-breakpoint
CREATE INDEX `account_userId_idx` ON `account` (`user_id`);--> statement-breakpoint
CREATE TABLE `session` (
`id` text PRIMARY KEY NOT NULL,
`expires_at` integer NOT NULL,
`token` text NOT NULL,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer NOT NULL,
`ip_address` text,
`user_agent` text,
`user_id` text NOT NULL,
FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
);
--> statement-breakpoint
CREATE UNIQUE INDEX `session_token_unique` ON `session` (`token`);--> statement-breakpoint
CREATE INDEX `session_userId_idx` ON `session` (`user_id`);--> statement-breakpoint
CREATE TABLE `user` (
`id` text PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`email` text NOT NULL,
`email_verified` integer DEFAULT false NOT NULL,
`image` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL
);
--> statement-breakpoint
CREATE UNIQUE INDEX `user_email_unique` ON `user` (`email`);--> statement-breakpoint
CREATE TABLE `verification` (
`id` text PRIMARY KEY NOT NULL,
`identifier` text NOT NULL,
`value` text NOT NULL,
`expires_at` integer NOT NULL,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL
);
--> statement-breakpoint
CREATE INDEX `verification_identifier_idx` ON `verification` (`identifier`);
+2
View File
@@ -0,0 +1,2 @@
ALTER TABLE `clients` DROP COLUMN `email`;--> statement-breakpoint
ALTER TABLE `clients` DROP COLUMN `phone`;
+24
View File
@@ -0,0 +1,24 @@
PRAGMA foreign_keys=OFF;--> statement-breakpoint
CREATE TABLE `__new_rooms` (
`id` text PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`type` text DEFAULT 'meeting_room' NOT NULL,
`sq_ft` integer,
`internal_price_per_hour_cents` integer,
`external_price_per_hour_cents` integer,
`internal_price_per_day_cents` integer,
`external_price_per_day_cents` integer,
`internal_price_per_half_day_cents` integer,
`external_price_per_half_day_cents` integer,
`max_attendees` integer,
`workstations` integer,
`price_per_month_cents` integer,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer
);
--> statement-breakpoint
INSERT INTO `__new_rooms`("id", "name", "type", "sq_ft", "internal_price_per_hour_cents", "external_price_per_hour_cents", "internal_price_per_day_cents", "external_price_per_day_cents", "internal_price_per_half_day_cents", "external_price_per_half_day_cents", "max_attendees", "workstations", "price_per_month_cents", "created_at", "updated_at", "archived_at") SELECT "id", "name", CASE WHEN "type" = 'office' THEN 'private_office' ELSE 'meeting_room' END, NULL, "hourly_rate_cents", "hourly_rate_cents", NULL, NULL, NULL, NULL, "capacity", NULL, NULL, "created_at", "updated_at", "archived_at" FROM `rooms`;--> statement-breakpoint
DROP TABLE `rooms`;--> statement-breakpoint
ALTER TABLE `__new_rooms` RENAME TO `rooms`;--> statement-breakpoint
PRAGMA foreign_keys=ON;
+80
View File
@@ -0,0 +1,80 @@
PRAGMA foreign_keys=OFF;--> statement-breakpoint
CREATE TABLE `__new_rooms` (
`id` text PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`type` text DEFAULT 'meeting_room' NOT NULL,
`sq_ft` integer,
`internal_price_per_hour_gbp` real,
`external_price_per_hour_gbp` real,
`internal_price_per_day_gbp` real,
`external_price_per_day_gbp` real,
`internal_price_per_half_day_gbp` real,
`external_price_per_half_day_gbp` real,
`max_attendees` integer,
`workstations` integer,
`price_per_month_gbp` real,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer
);
--> statement-breakpoint
INSERT INTO `__new_rooms`("id", "name", "type", "sq_ft", "internal_price_per_hour_gbp", "external_price_per_hour_gbp", "internal_price_per_day_gbp", "external_price_per_day_gbp", "internal_price_per_half_day_gbp", "external_price_per_half_day_gbp", "max_attendees", "workstations", "price_per_month_gbp", "created_at", "updated_at", "archived_at") SELECT "id", "name", "type", "sq_ft", "internal_price_per_hour_cents" / 100.0, "external_price_per_hour_cents" / 100.0, "internal_price_per_day_cents" / 100.0, "external_price_per_day_cents" / 100.0, "internal_price_per_half_day_cents" / 100.0, "external_price_per_half_day_cents" / 100.0, "max_attendees", "workstations", "price_per_month_cents" / 100.0, "created_at", "updated_at", "archived_at" FROM `rooms`;--> statement-breakpoint
DROP TABLE `rooms`;--> statement-breakpoint
ALTER TABLE `__new_rooms` RENAME TO `rooms`;--> statement-breakpoint
PRAGMA foreign_keys=ON;--> statement-breakpoint
CREATE TABLE `__new_services` (
`id` text PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`category` text,
`unit` text DEFAULT 'each' NOT NULL,
`price_gbp` real DEFAULT 0 NOT NULL,
`description` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer
);
--> statement-breakpoint
INSERT INTO `__new_services`("id", "name", "category", "unit", "price_gbp", "description", "created_at", "updated_at", "archived_at") SELECT "id", "name", "category", "unit", "price_cents" / 100.0, "description", "created_at", "updated_at", "archived_at" FROM `services`;--> statement-breakpoint
DROP TABLE `services`;--> statement-breakpoint
ALTER TABLE `__new_services` RENAME TO `services`;--> statement-breakpoint
CREATE TABLE `__new_invoices` (
`id` text PRIMARY KEY NOT NULL,
`client_id` text NOT NULL,
`invoice_number` text NOT NULL,
`issue_date` text NOT NULL,
`due_date` text NOT NULL,
`status` text DEFAULT 'draft' NOT NULL,
`subtotal_gbp` real DEFAULT 0 NOT NULL,
`tax_gbp` real DEFAULT 0 NOT NULL,
`total_gbp` real DEFAULT 0 NOT NULL,
`notes` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer,
FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON UPDATE no action ON DELETE restrict
);
--> statement-breakpoint
INSERT INTO `__new_invoices`("id", "client_id", "invoice_number", "issue_date", "due_date", "status", "subtotal_gbp", "tax_gbp", "total_gbp", "notes", "created_at", "updated_at", "archived_at") SELECT "id", "client_id", "invoice_number", "issue_date", "due_date", "status", "subtotal_cents" / 100.0, "tax_cents" / 100.0, "total_cents" / 100.0, "notes", "created_at", "updated_at", "archived_at" FROM `invoices`;--> statement-breakpoint
DROP TABLE `invoices`;--> statement-breakpoint
ALTER TABLE `__new_invoices` RENAME TO `invoices`;--> statement-breakpoint
CREATE UNIQUE INDEX `invoices_invoice_number_unique` ON `invoices` (`invoice_number`);--> statement-breakpoint
CREATE INDEX `invoices_client_id_idx` ON `invoices` (`client_id`);--> statement-breakpoint
CREATE TABLE `__new_contracts` (
`id` text PRIMARY KEY NOT NULL,
`client_id` text NOT NULL,
`title` text NOT NULL,
`start_date` text NOT NULL,
`end_date` text,
`status` text DEFAULT 'draft' NOT NULL,
`value_gbp` real DEFAULT 0 NOT NULL,
`notes` text,
`created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL,
`archived_at` integer,
FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON UPDATE no action ON DELETE restrict
);
--> statement-breakpoint
INSERT INTO `__new_contracts`("id", "client_id", "title", "start_date", "end_date", "status", "value_gbp", "notes", "created_at", "updated_at", "archived_at") SELECT "id", "client_id", "title", "start_date", "end_date", "status", "value_cents" / 100.0, "notes", "created_at", "updated_at", "archived_at" FROM `contracts`;--> statement-breakpoint
DROP TABLE `contracts`;--> statement-breakpoint
ALTER TABLE `__new_contracts` RENAME TO `contracts`;--> statement-breakpoint
CREATE INDEX `contracts_client_id_idx` ON `contracts` (`client_id`);
+2
View File
@@ -0,0 +1,2 @@
ALTER TABLE `rooms` DROP COLUMN `internal_price_per_half_day_gbp`;--> statement-breakpoint
ALTER TABLE `rooms` DROP COLUMN `external_price_per_half_day_gbp`;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+41
View File
@@ -0,0 +1,41 @@
{
"version": "7",
"dialect": "sqlite",
"entries": [
{
"idx": 0,
"version": "6",
"when": 1779571091471,
"tag": "0000_wild_guardian",
"breakpoints": true
},
{
"idx": 1,
"version": "6",
"when": 1780516359556,
"tag": "0001_amusing_maximus",
"breakpoints": true
},
{
"idx": 2,
"version": "6",
"when": 1780608782775,
"tag": "0002_volatile_gressill",
"breakpoints": true
},
{
"idx": 3,
"version": "6",
"when": 1780609384877,
"tag": "0003_tan_george_stacy",
"breakpoints": true
},
{
"idx": 4,
"version": "6",
"when": 1780609661307,
"tag": "0004_orange_ultimatum",
"breakpoints": true
}
]
}