Skip to content

Commit 16ad838

Browse files
committed
Add database, auth, and org infrastructure for the website worker
## db/ package (new workspace package) Drizzle ORM schema with D1 SQLite targeting Cloudflare Workers: - **BetterAuth core tables**: user, session, account, verification - **Org hierarchy**: org, orgMember (many-to-many user<>org with role enum) - **Device flow**: deviceCode table for CLI/agent login (RFC 8628) - All timestamps use epochMs custom type for D1 Date compat - All IDs are ULIDs, all FKs have cascade delete + indexes - Relations wired with defineRelations v2 (including many-to-many through) - Dual entrypoints: workerd.ts (drizzle-orm/d1) and node.ts (D1 HTTP API) - flatten-migrations.ts script for wrangler D1 compatibility - First migration generated and flattened ## website/ auth + UI - **src/db.ts**: getDb(), getAuth() with Google social + device flow + bearer plugins, cookie caching, getSession(), requireSession(), requireOrgMember() - **server.tsx**: BetterAuth middleware on /api/auth/*, login page (/login), Google OAuth redirect (/login/google), device flow page (/device) with approve/deny server actions - **Tailwind v4 + shadcn tokens**: globals.css with light/dark mode via @variant dark, cn() utility, Button component with form pending states, DeviceActionButtons client component - **wrangler.jsonc**: D1 bindings (holocron-db + holocron-preview-db), BETTER_AUTH_SECRET/GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET secrets, BETTER_AUTH_URL vars per environment - **package.json**: Added better-auth, drizzle-orm@beta, tailwindcss, shadcn deps. Migration scripts for local/preview/prod D1. - **vite.config.ts**: Added react + tailwind plugins - **tsconfig.json**: Added JSX, DOM lib, worker-configuration.d.ts ## Root - tsconfig.base.json: shared strict ESNext config for all packages - .gitignore: added .dev.vars, .env.*, worker-configuration.d.ts ## Sigillo Created holocron org + website project with dev/preview/prod environments. Placeholder secrets added: BETTER_AUTH_SECRET, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, CF_API_TOKEN, AIG_GATEWAY_TOKEN. ## D1 databases created - holocron-db (prod): 1b6a43e2-2e03-408c-9199-291faa305fa4 - holocron-preview-db (preview): 8c7b5000-0d42-4c55-9a0a-ecad450f1e3d Session: ses_243dcc460ffeCk1FXcCKm4HFhj
1 parent 156da43 commit 16ad838

25 files changed

Lines changed: 5350 additions & 182 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ tmp
1212
.tmp-*
1313
play
1414
.wrangler
15+
.dev.vars
16+
.env.preview
17+
.env.prod
18+
worker-configuration.d.ts

db/drizzle.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineConfig } from 'drizzle-kit'
2+
3+
export default defineConfig({
4+
out: './drizzle',
5+
schema: './src/schema.ts',
6+
dialect: 'sqlite',
7+
})

db/drizzle/0001_clumsy_electro.sql

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
CREATE TABLE `account` (
2+
`id` text PRIMARY KEY,
3+
`user_id` text NOT NULL,
4+
`account_id` text NOT NULL,
5+
`provider_id` text NOT NULL,
6+
`access_token` text,
7+
`refresh_token` text,
8+
`access_token_expires_at` integer,
9+
`refresh_token_expires_at` integer,
10+
`scope` text,
11+
`id_token` text,
12+
`password` text,
13+
`created_at` integer NOT NULL,
14+
`updated_at` integer NOT NULL,
15+
CONSTRAINT `fk_account_user_id_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE
16+
);
17+
--> statement-breakpoint
18+
CREATE TABLE `device_code` (
19+
`id` text PRIMARY KEY,
20+
`device_code` text NOT NULL UNIQUE,
21+
`user_code` text NOT NULL UNIQUE,
22+
`user_id` text,
23+
`expires_at` integer NOT NULL,
24+
`status` text DEFAULT 'pending' NOT NULL,
25+
`last_polled_at` integer,
26+
`polling_interval` integer,
27+
`client_id` text,
28+
`scope` text,
29+
CONSTRAINT `fk_device_code_user_id_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE
30+
);
31+
--> statement-breakpoint
32+
CREATE TABLE `org` (
33+
`id` text PRIMARY KEY,
34+
`name` text NOT NULL,
35+
`created_at` integer NOT NULL,
36+
`updated_at` integer NOT NULL
37+
);
38+
--> statement-breakpoint
39+
CREATE TABLE `org_member` (
40+
`id` text PRIMARY KEY,
41+
`org_id` text NOT NULL,
42+
`user_id` text NOT NULL,
43+
`role` text DEFAULT 'member' NOT NULL,
44+
`created_at` integer NOT NULL,
45+
CONSTRAINT `fk_org_member_org_id_org_id_fk` FOREIGN KEY (`org_id`) REFERENCES `org`(`id`) ON DELETE CASCADE,
46+
CONSTRAINT `fk_org_member_user_id_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE
47+
);
48+
--> statement-breakpoint
49+
CREATE TABLE `session` (
50+
`id` text PRIMARY KEY,
51+
`user_id` text NOT NULL,
52+
`token` text NOT NULL UNIQUE,
53+
`expires_at` integer NOT NULL,
54+
`ip_address` text,
55+
`user_agent` text,
56+
`created_at` integer NOT NULL,
57+
`updated_at` integer NOT NULL,
58+
CONSTRAINT `fk_session_user_id_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE
59+
);
60+
--> statement-breakpoint
61+
CREATE TABLE `user` (
62+
`id` text PRIMARY KEY,
63+
`name` text NOT NULL,
64+
`email` text NOT NULL UNIQUE,
65+
`email_verified` integer DEFAULT false NOT NULL,
66+
`image` text,
67+
`created_at` integer NOT NULL,
68+
`updated_at` integer NOT NULL
69+
);
70+
--> statement-breakpoint
71+
CREATE TABLE `verification` (
72+
`id` text PRIMARY KEY,
73+
`identifier` text NOT NULL,
74+
`value` text NOT NULL,
75+
`expires_at` integer NOT NULL,
76+
`created_at` integer NOT NULL,
77+
`updated_at` integer NOT NULL
78+
);
79+
--> statement-breakpoint
80+
CREATE INDEX `account_user_id_idx` ON `account` (`user_id`);--> statement-breakpoint
81+
CREATE INDEX `device_code_user_id_idx` ON `device_code` (`user_id`);--> statement-breakpoint
82+
CREATE INDEX `org_member_org_id_idx` ON `org_member` (`org_id`);--> statement-breakpoint
83+
CREATE INDEX `org_member_user_id_idx` ON `org_member` (`user_id`);--> statement-breakpoint
84+
CREATE UNIQUE INDEX `org_member_org_id_user_id_unique` ON `org_member` (`org_id`,`user_id`);--> statement-breakpoint
85+
CREATE INDEX `session_user_id_idx` ON `session` (`user_id`);
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
CREATE TABLE `account` (
2+
`id` text PRIMARY KEY,
3+
`user_id` text NOT NULL,
4+
`account_id` text NOT NULL,
5+
`provider_id` text NOT NULL,
6+
`access_token` text,
7+
`refresh_token` text,
8+
`access_token_expires_at` integer,
9+
`refresh_token_expires_at` integer,
10+
`scope` text,
11+
`id_token` text,
12+
`password` text,
13+
`created_at` integer NOT NULL,
14+
`updated_at` integer NOT NULL,
15+
CONSTRAINT `fk_account_user_id_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE
16+
);
17+
--> statement-breakpoint
18+
CREATE TABLE `device_code` (
19+
`id` text PRIMARY KEY,
20+
`device_code` text NOT NULL UNIQUE,
21+
`user_code` text NOT NULL UNIQUE,
22+
`user_id` text,
23+
`expires_at` integer NOT NULL,
24+
`status` text DEFAULT 'pending' NOT NULL,
25+
`last_polled_at` integer,
26+
`polling_interval` integer,
27+
`client_id` text,
28+
`scope` text,
29+
CONSTRAINT `fk_device_code_user_id_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE
30+
);
31+
--> statement-breakpoint
32+
CREATE TABLE `org` (
33+
`id` text PRIMARY KEY,
34+
`name` text NOT NULL,
35+
`created_at` integer NOT NULL,
36+
`updated_at` integer NOT NULL
37+
);
38+
--> statement-breakpoint
39+
CREATE TABLE `org_member` (
40+
`id` text PRIMARY KEY,
41+
`org_id` text NOT NULL,
42+
`user_id` text NOT NULL,
43+
`role` text DEFAULT 'member' NOT NULL,
44+
`created_at` integer NOT NULL,
45+
CONSTRAINT `fk_org_member_org_id_org_id_fk` FOREIGN KEY (`org_id`) REFERENCES `org`(`id`) ON DELETE CASCADE,
46+
CONSTRAINT `fk_org_member_user_id_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE
47+
);
48+
--> statement-breakpoint
49+
CREATE TABLE `session` (
50+
`id` text PRIMARY KEY,
51+
`user_id` text NOT NULL,
52+
`token` text NOT NULL UNIQUE,
53+
`expires_at` integer NOT NULL,
54+
`ip_address` text,
55+
`user_agent` text,
56+
`created_at` integer NOT NULL,
57+
`updated_at` integer NOT NULL,
58+
CONSTRAINT `fk_session_user_id_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE
59+
);
60+
--> statement-breakpoint
61+
CREATE TABLE `user` (
62+
`id` text PRIMARY KEY,
63+
`name` text NOT NULL,
64+
`email` text NOT NULL UNIQUE,
65+
`email_verified` integer DEFAULT false NOT NULL,
66+
`image` text,
67+
`created_at` integer NOT NULL,
68+
`updated_at` integer NOT NULL
69+
);
70+
--> statement-breakpoint
71+
CREATE TABLE `verification` (
72+
`id` text PRIMARY KEY,
73+
`identifier` text NOT NULL,
74+
`value` text NOT NULL,
75+
`expires_at` integer NOT NULL,
76+
`created_at` integer NOT NULL,
77+
`updated_at` integer NOT NULL
78+
);
79+
--> statement-breakpoint
80+
CREATE INDEX `account_user_id_idx` ON `account` (`user_id`);--> statement-breakpoint
81+
CREATE INDEX `device_code_user_id_idx` ON `device_code` (`user_id`);--> statement-breakpoint
82+
CREATE INDEX `org_member_org_id_idx` ON `org_member` (`org_id`);--> statement-breakpoint
83+
CREATE INDEX `org_member_user_id_idx` ON `org_member` (`user_id`);--> statement-breakpoint
84+
CREATE UNIQUE INDEX `org_member_org_id_user_id_unique` ON `org_member` (`org_id`,`user_id`);--> statement-breakpoint
85+
CREATE INDEX `session_user_id_idx` ON `session` (`user_id`);

0 commit comments

Comments
 (0)