create-m5kdev 0.35.0 → 0.37.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/package.json +3 -3
  2. package/templates/minimal-app/.dockerignore.tpl +6 -0
  3. package/templates/minimal-app/apps/e2e/playwright.config.ts.tpl +3 -0
  4. package/templates/minimal-app/apps/e2e/servers.ts.tpl +4 -0
  5. package/templates/minimal-app/apps/e2e/tests/expo-helpers.ts.tpl +2 -34
  6. package/templates/minimal-app/apps/e2e/tests/expo-standard.spec.ts.tpl +225 -5
  7. package/templates/minimal-app/apps/e2e/tests/helpers.ts.tpl +47 -1
  8. package/templates/minimal-app/apps/e2e/tests/mcp-helpers.ts.tpl +406 -0
  9. package/templates/minimal-app/apps/e2e/tests/mcp.spec.ts.tpl +108 -0
  10. package/templates/minimal-app/apps/e2e/tests/standard.spec.ts.tpl +290 -8
  11. package/templates/minimal-app/apps/expo/app.json.tpl +1 -0
  12. package/templates/minimal-app/apps/expo/package.json.tpl +4 -0
  13. package/templates/minimal-app/apps/expo/src/app/_layout.tsx.tpl +4 -1
  14. package/templates/minimal-app/apps/expo/src/app/notifications.tsx.tpl +70 -0
  15. package/templates/minimal-app/apps/expo/src/app/organization/accept-invitation.tsx.tpl +8 -16
  16. package/templates/minimal-app/apps/expo/src/app/posts.tsx.tpl +4 -1
  17. package/templates/minimal-app/apps/expo/src/lib/trpc.ts.tpl +11 -2
  18. package/templates/minimal-app/apps/landing/vite.config.ts.tpl +2 -3
  19. package/templates/minimal-app/apps/server/AGENTS.md.tpl +10 -0
  20. package/templates/minimal-app/apps/server/db.e2e.ts.tpl +6 -40
  21. package/templates/minimal-app/apps/server/db.ts.tpl +6 -42
  22. package/templates/minimal-app/apps/server/drizzle/{0000_wealthy_absorbing_man.sql → 0000_whole_echo.sql} +102 -3
  23. package/templates/minimal-app/apps/server/drizzle/0001_yummy_spectrum.sql +26 -0
  24. package/templates/minimal-app/apps/server/drizzle/0002_crazy_lilith.sql +47 -0
  25. package/templates/minimal-app/apps/server/drizzle/0003_freezing_fantastic_four.sql +4 -0
  26. package/templates/minimal-app/apps/server/drizzle/0004_slow_ezekiel_stane.sql +99 -0
  27. package/templates/minimal-app/apps/server/drizzle/0005_wonderful_the_professor.sql +2 -0
  28. package/templates/minimal-app/apps/server/drizzle/0006_lazy_blue_marvel.sql +159 -0
  29. package/templates/minimal-app/apps/server/drizzle/0007_abnormal_ultimo.sql +2 -0
  30. package/templates/minimal-app/apps/server/drizzle/0008_steady_nekra.sql +87 -0
  31. package/templates/minimal-app/apps/server/drizzle/meta/0000_snapshot.json.tpl +2625 -1780
  32. package/templates/minimal-app/apps/server/drizzle/meta/0001_snapshot.json.tpl +2671 -1796
  33. package/templates/minimal-app/apps/server/drizzle/meta/0002_snapshot.json.tpl +2716 -1818
  34. package/templates/minimal-app/apps/server/drizzle/meta/0003_snapshot.json.tpl +715 -164
  35. package/templates/minimal-app/apps/server/drizzle/meta/0004_snapshot.json.tpl +2498 -0
  36. package/templates/minimal-app/apps/server/drizzle/meta/0005_snapshot.json.tpl +2484 -0
  37. package/templates/minimal-app/apps/server/drizzle/meta/0006_snapshot.json.tpl +3603 -0
  38. package/templates/minimal-app/apps/server/drizzle/meta/0007_snapshot.json.tpl +3620 -0
  39. package/templates/minimal-app/apps/server/drizzle/meta/0008_snapshot.json.tpl +3620 -0
  40. package/templates/minimal-app/apps/server/drizzle/meta/_journal.json.tpl +44 -9
  41. package/templates/minimal-app/apps/server/src/app.ts.tpl +12 -2
  42. package/templates/minimal-app/apps/server/src/modules/posts/posts.db.ts.tpl +2 -2
  43. package/templates/minimal-app/apps/server/src/modules/posts/posts.mcp.ts.tpl +17 -0
  44. package/templates/minimal-app/apps/server/src/modules/posts/posts.module.ts.tpl +11 -0
  45. package/templates/minimal-app/apps/server/src/modules/posts/posts.service.ts.tpl +14 -5
  46. package/templates/minimal-app/apps/server/src/modules/test-harness/test-harness.module.ts.tpl +13 -36
  47. package/templates/minimal-app/apps/server/src/schema.ts.tpl +16 -2
  48. package/templates/minimal-app/apps/shared/package.json.tpl +1 -0
  49. package/templates/minimal-app/apps/shared/src/modules/app/app.constants.ts.tpl +1 -1
  50. package/templates/minimal-app/apps/shared/src/modules/notification/notification.constants.ts.tpl +5 -0
  51. package/templates/minimal-app/apps/shared/src/modules/notification/notification.schema.ts.tpl +1 -1
  52. package/templates/minimal-app/apps/webapp/src/Layout.tsx.tpl +17 -1
  53. package/templates/minimal-app/apps/webapp/src/Router.tsx.tpl +10 -8
  54. package/templates/minimal-app/apps/webapp/src/modules/notification/NotificationPreferencesRoute.tsx.tpl +29 -0
  55. package/templates/minimal-app/apps/webapp/src/modules/notification/StarterWebPush.tsx.tpl +44 -0
  56. package/templates/minimal-app/apps/webapp/translations/en/{{APP_SLUG}}.json.tpl +8 -0
  57. package/templates/minimal-app/pnpm-workspace.yaml.tpl +14 -13
  58. package/templates/minimal-app/template.manifest.json +9 -0
  59. package/templates/minimal-app/apps/server/drizzle/0001_third_ink.sql +0 -1
  60. package/templates/minimal-app/apps/server/drizzle/0002_concerned_proudstar.sql +0 -3
  61. package/templates/minimal-app/apps/server/drizzle/0003_silly_the_liberteens.sql +0 -27
@@ -82,6 +82,7 @@ async function ensureUser(input: {
82
82
  await orm.insert(schema.accounts).values({
83
83
  id: uuidv4(),
84
84
  accountId: user.id,
85
+ issuer: "local:credential",
85
86
  providerId: "credential",
86
87
  userId: user.id,
87
88
  password: await hashPassword(password),
@@ -96,10 +97,9 @@ async function ensureUser(input: {
96
97
  async function ensureOrganization(input: {
97
98
  orm: SeedOrm;
98
99
  userId: string;
99
- }): Promise<{ organizationId: string; teamId: string }> {
100
+ }): Promise<{ organizationId: string }> {
100
101
  const { orm, userId } = input;
101
102
  const organizationId = `auth-e2e-enterprise-${profile}`;
102
- const teamId = `auth-e2e-team-${profile}`;
103
103
 
104
104
  const [existingOrganization] = await orm
105
105
  .select()
@@ -133,39 +133,7 @@ async function ensureOrganization(input: {
133
133
  });
134
134
  }
135
135
 
136
- const [existingTeam] = await orm
137
- .select()
138
- .from(schema.teams)
139
- .where(eq(schema.teams.id, teamId))
140
- .limit(1);
141
-
142
- if (!existingTeam) {
143
- await orm.insert(schema.teams).values({
144
- id: teamId,
145
- name: "Editorial",
146
- organizationId,
147
- createdAt: new Date(),
148
- updatedAt: new Date(),
149
- });
150
- }
151
-
152
- const [existingTeamMember] = await orm
153
- .select()
154
- .from(schema.teamMembers)
155
- .where(eq(schema.teamMembers.userId, userId))
156
- .limit(1);
157
-
158
- if (!existingTeamMember) {
159
- await orm.insert(schema.teamMembers).values({
160
- id: uuidv4(),
161
- teamId,
162
- userId,
163
- role: "owner",
164
- createdAt: new Date(),
165
- });
166
- }
167
-
168
- return { organizationId, teamId };
136
+ return { organizationId };
169
137
  }
170
138
 
171
139
  async function seedPosts(input: {
@@ -220,7 +188,6 @@ async function seedExpiredWaitlistCode(orm: SeedOrm): Promise<void> {
220
188
  id: uuidv4(),
221
189
  email: `expired.${profile}@auth-e2e.local`,
222
190
  name: "Expired Invite",
223
- type: "WAITLIST",
224
191
  status: "INVITED",
225
192
  code: "expired-waitlist-code",
226
193
  expiresAt: new Date(Date.now() - 60_000),
@@ -241,16 +208,15 @@ async function seedProvisionedClaimUser(orm: SeedOrm): Promise<typeof schema.use
241
208
 
242
209
  const [existingClaim] = await orm
243
210
  .select()
244
- .from(schema.waitlist)
245
- .where(eq(schema.waitlist.claimUserId, user.id))
211
+ .from(schema.accountClaims)
212
+ .where(eq(schema.accountClaims.claimUserId, user.id))
246
213
  .limit(1);
247
214
  if (existingClaim) {
248
215
  return user;
249
216
  }
250
217
 
251
- await orm.insert(schema.waitlist).values({
218
+ await orm.insert(schema.accountClaims).values({
252
219
  id: `auth-e2e-claim-${profile}`,
253
- type: "ACCOUNT_CLAIM",
254
220
  status: "INVITED",
255
221
  claimUserId: user.id,
256
222
  code: uuidv4(),
@@ -7,14 +7,13 @@ import * as schema from "./src/schema";
7
7
  const DEMO_EMAIL = "admin{{PACKAGE_SCOPE}}.local";
8
8
  const DEMO_PASSWORD = "password1234";
9
9
  const ORGANIZATION_ID = "{{APP_SLUG}}-org";
10
- const TEAM_ID = "{{APP_SLUG}}-team";
11
10
 
12
11
  void runDb({
13
12
  schema,
14
13
  seed: async ({ orm }) => {
15
14
  const user = await ensureDemoUser(orm);
16
- const { organizationId, teamId } = await ensureOrganization({ orm, userId: user.id });
17
- await seedPosts({ orm, userId: user.id, organizationId, teamId });
15
+ const { organizationId } = await ensureOrganization({ orm, userId: user.id });
16
+ await seedPosts({ orm, userId: user.id, organizationId });
18
17
  console.info(`Seed completed. Demo login: ${DEMO_EMAIL} / ${DEMO_PASSWORD}`);
19
18
  },
20
19
  });
@@ -53,6 +52,7 @@ async function ensureDemoUser(orm: SeedOrm): Promise<typeof schema.users.$inferS
53
52
  await orm.insert(schema.accounts).values({
54
53
  id: uuidv4(),
55
54
  accountId: user.id,
55
+ issuer: "local:credential",
56
56
  providerId: "credential",
57
57
  userId: user.id,
58
58
  password: await hashPassword(DEMO_PASSWORD),
@@ -66,7 +66,7 @@ async function ensureDemoUser(orm: SeedOrm): Promise<typeof schema.users.$inferS
66
66
  async function ensureOrganization(input: {
67
67
  orm: SeedOrm;
68
68
  userId: string;
69
- }): Promise<{ organizationId: string; teamId: string }> {
69
+ }): Promise<{ organizationId: string }> {
70
70
  const { orm, userId } = input;
71
71
  const [existingOrganization] = await orm
72
72
  .select()
@@ -100,48 +100,15 @@ async function ensureOrganization(input: {
100
100
  });
101
101
  }
102
102
 
103
- const [existingTeam] = await orm
104
- .select()
105
- .from(schema.teams)
106
- .where(eq(schema.teams.id, TEAM_ID))
107
- .limit(1);
108
-
109
- if (!existingTeam) {
110
- await orm.insert(schema.teams).values({
111
- id: TEAM_ID,
112
- name: "Editorial",
113
- organizationId: ORGANIZATION_ID,
114
- createdAt: new Date(),
115
- updatedAt: new Date(),
116
- });
117
- }
118
-
119
- const [existingTeamMember] = await orm
120
- .select()
121
- .from(schema.teamMembers)
122
- .where(eq(schema.teamMembers.userId, userId))
123
- .limit(1);
124
-
125
- if (!existingTeamMember) {
126
- await orm.insert(schema.teamMembers).values({
127
- id: uuidv4(),
128
- teamId: TEAM_ID,
129
- userId,
130
- role: "owner",
131
- createdAt: new Date(),
132
- });
133
- }
134
-
135
- return { organizationId: ORGANIZATION_ID, teamId: TEAM_ID };
103
+ return { organizationId: ORGANIZATION_ID };
136
104
  }
137
105
 
138
106
  async function seedPosts(input: {
139
107
  orm: SeedOrm;
140
108
  userId: string;
141
109
  organizationId: string | null;
142
- teamId: string;
143
110
  }): Promise<void> {
144
- const { orm, userId, organizationId, teamId } = input;
111
+ const { orm, userId, organizationId } = input;
145
112
  const existingPosts = await orm.select().from(schema.posts).limit(1);
146
113
  if (existingPosts.length > 0) {
147
114
  return;
@@ -151,7 +118,6 @@ async function seedPosts(input: {
151
118
  {
152
119
  authorUserId: userId,
153
120
  organizationId,
154
- teamId,
155
121
  title: "An editorial workflow you can ship in an afternoon",
156
122
  slug: "editorial-workflow-in-an-afternoon",
157
123
  excerpt: "A first draft on how this minimal starter is wired together.",
@@ -164,7 +130,6 @@ async function seedPosts(input: {
164
130
  {
165
131
  authorUserId: userId,
166
132
  organizationId,
167
- teamId,
168
133
  title: "Three habits that keep CRUD apps from drifting into chaos",
169
134
  slug: "three-habits-that-keep-crud{{PACKAGE_SCOPE}}s-focused",
170
135
  excerpt: "A draft about explicit composition, typed contracts, and URL state.",
@@ -176,7 +141,6 @@ async function seedPosts(input: {
176
141
  {
177
142
  authorUserId: userId,
178
143
  organizationId,
179
- teamId,
180
144
  title: "What a minimal platform starter should still refuse to compromise on",
181
145
  slug: "minimal-platform-starter-non-negotiables",
182
146
  excerpt: "A published note on keeping the foundation opinionated without being heavy.",
@@ -28,6 +28,28 @@ CREATE TABLE `accounts` (
28
28
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
29
29
  );
30
30
  --> statement-breakpoint
31
+ CREATE TABLE `ai_usage` (
32
+ `id` text PRIMARY KEY NOT NULL,
33
+ `user_id` text,
34
+ `member_id` text,
35
+ `team_id` text,
36
+ `organization_id` text,
37
+ `feature` text NOT NULL,
38
+ `provider` text NOT NULL,
39
+ `model` text NOT NULL,
40
+ `input_tokens` integer,
41
+ `output_tokens` integer,
42
+ `total_tokens` integer,
43
+ `cost` real,
44
+ `trace_id` text,
45
+ `created_at` integer NOT NULL,
46
+ `metadata` text,
47
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE set null,
48
+ FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON UPDATE no action ON DELETE set null,
49
+ FOREIGN KEY (`team_id`) REFERENCES `teams`(`id`) ON UPDATE no action ON DELETE set null,
50
+ FOREIGN KEY (`organization_id`) REFERENCES `organizations`(`id`) ON UPDATE no action ON DELETE set null
51
+ );
52
+ --> statement-breakpoint
31
53
  CREATE TABLE `apikeys` (
32
54
  `id` text PRIMARY KEY NOT NULL,
33
55
  `name` text,
@@ -53,6 +75,44 @@ CREATE TABLE `apikeys` (
53
75
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
54
76
  );
55
77
  --> statement-breakpoint
78
+ CREATE TABLE `chats` (
79
+ `id` text PRIMARY KEY NOT NULL,
80
+ `user_id` text NOT NULL,
81
+ `title` text,
82
+ `type` text,
83
+ `conversation` text,
84
+ `created_at` integer,
85
+ `updated_at` integer NOT NULL,
86
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
87
+ );
88
+ --> statement-breakpoint
89
+ CREATE TABLE `files` (
90
+ `id` text PRIMARY KEY NOT NULL,
91
+ `created_at` integer NOT NULL,
92
+ `updated_at` integer,
93
+ `deleted_at` integer,
94
+ `user_id` text,
95
+ `member_id` text,
96
+ `organization_id` text,
97
+ `team_id` text,
98
+ `bucket` text NOT NULL,
99
+ `key` text NOT NULL,
100
+ `original_name` text NOT NULL,
101
+ `original_extension` text,
102
+ `content_type` text NOT NULL,
103
+ `size_bytes` integer,
104
+ `etag` text,
105
+ `checksum_sha256` text,
106
+ `metadata` text,
107
+ `status` text NOT NULL,
108
+ `uploaded_at` integer,
109
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE set null,
110
+ FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON UPDATE no action ON DELETE set null,
111
+ FOREIGN KEY (`organization_id`) REFERENCES `organizations`(`id`) ON UPDATE no action ON DELETE set null,
112
+ FOREIGN KEY (`team_id`) REFERENCES `teams`(`id`) ON UPDATE no action ON DELETE set null
113
+ );
114
+ --> statement-breakpoint
115
+ CREATE UNIQUE INDEX `files_bucket_key_unique` ON `files` (`bucket`,`key`);--> statement-breakpoint
56
116
  CREATE TABLE `invitations` (
57
117
  `id` text PRIMARY KEY NOT NULL,
58
118
  `organization_id` text NOT NULL,
@@ -72,8 +132,11 @@ CREATE TABLE `members` (
72
132
  `id` text PRIMARY KEY NOT NULL,
73
133
  `organization_id` text NOT NULL,
74
134
  `user_id` text NOT NULL,
135
+ `name` text DEFAULT '' NOT NULL,
136
+ `image` text,
75
137
  `role` text NOT NULL,
76
138
  `created_at` integer NOT NULL,
139
+ `deleted_at` integer,
77
140
  `preferences` text DEFAULT '{}',
78
141
  `metadata` text DEFAULT '{}',
79
142
  `onboarding` integer,
@@ -98,12 +161,25 @@ CREATE TABLE `notification_devices` (
98
161
  --> statement-breakpoint
99
162
  CREATE UNIQUE INDEX `notification_devices_endpoint_unique` ON `notification_devices` (`endpoint`);--> statement-breakpoint
100
163
  CREATE UNIQUE INDEX `notification_devices_token_unique` ON `notification_devices` (`token`);--> statement-breakpoint
164
+ CREATE TABLE `notification_preferences` (
165
+ `id` text PRIMARY KEY NOT NULL,
166
+ `member_id` text NOT NULL,
167
+ `kind` text NOT NULL,
168
+ `channel` text NOT NULL,
169
+ `created_at` integer NOT NULL,
170
+ `updated_at` integer NOT NULL,
171
+ FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON UPDATE no action ON DELETE cascade
172
+ );
173
+ --> statement-breakpoint
174
+ CREATE UNIQUE INDEX `notification_preferences_member_kind_channel_unique` ON `notification_preferences` (`member_id`,`kind`,`channel`);--> statement-breakpoint
101
175
  CREATE TABLE `notification_send_logs` (
102
176
  `id` text PRIMARY KEY NOT NULL,
103
177
  `batch_id` text NOT NULL,
178
+ `notification_id` text NOT NULL,
104
179
  `user_id` text NOT NULL,
105
- `device_id` text NOT NULL,
106
- `provider` text NOT NULL,
180
+ `device_id` text,
181
+ `channel` text NOT NULL,
182
+ `provider` text,
107
183
  `title` text NOT NULL,
108
184
  `body` text NOT NULL,
109
185
  `data` text,
@@ -112,8 +188,29 @@ CREATE TABLE `notification_send_logs` (
112
188
  `job_id` text,
113
189
  `created_at` integer NOT NULL,
114
190
  `updated_at` integer NOT NULL,
191
+ FOREIGN KEY (`notification_id`) REFERENCES `notifications`(`id`) ON UPDATE no action ON DELETE cascade,
115
192
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade,
116
- FOREIGN KEY (`device_id`) REFERENCES `notification_devices`(`id`) ON UPDATE no action ON DELETE cascade
193
+ FOREIGN KEY (`device_id`) REFERENCES `notification_devices`(`id`) ON UPDATE no action ON DELETE set null
194
+ );
195
+ --> statement-breakpoint
196
+ CREATE TABLE `notifications` (
197
+ `id` text PRIMARY KEY NOT NULL,
198
+ `member_id` text NOT NULL,
199
+ `user_id` text NOT NULL,
200
+ `kind` text NOT NULL,
201
+ `title` text NOT NULL,
202
+ `body` text NOT NULL,
203
+ `data` text,
204
+ `visible_in_inbox` integer DEFAULT false NOT NULL,
205
+ `armed_channels` text DEFAULT '[]' NOT NULL,
206
+ `web_pushed_at` integer,
207
+ `mobile_pushed_at` integer,
208
+ `emailed_at` integer,
209
+ `read_at` integer,
210
+ `created_at` integer NOT NULL,
211
+ `updated_at` integer NOT NULL,
212
+ FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON UPDATE no action ON DELETE cascade,
213
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
117
214
  );
118
215
  --> statement-breakpoint
119
216
  CREATE TABLE `organizations` (
@@ -136,6 +233,7 @@ CREATE UNIQUE INDEX `organizations_slug_unique` ON `organizations` (`slug`);-->
136
233
  CREATE TABLE `posts` (
137
234
  `id` text PRIMARY KEY NOT NULL,
138
235
  `author_user_id` text,
236
+ `member_id` text,
139
237
  `organization_id` text,
140
238
  `team_id` text,
141
239
  `title` text NOT NULL,
@@ -148,6 +246,7 @@ CREATE TABLE `posts` (
148
246
  `updated_at` integer,
149
247
  `deleted_at` integer,
150
248
  FOREIGN KEY (`author_user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE set null,
249
+ FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON UPDATE no action ON DELETE set null,
151
250
  FOREIGN KEY (`organization_id`) REFERENCES `organizations`(`id`) ON UPDATE no action ON DELETE set null,
152
251
  FOREIGN KEY (`team_id`) REFERENCES `teams`(`id`) ON UPDATE no action ON DELETE set null
153
252
  );
@@ -0,0 +1,26 @@
1
+ PRAGMA foreign_keys=OFF;--> statement-breakpoint
2
+ CREATE TABLE `__new_members` (
3
+ `id` text PRIMARY KEY NOT NULL,
4
+ `organization_id` text NOT NULL,
5
+ `user_id` text,
6
+ `email` text,
7
+ `name` text DEFAULT '' NOT NULL,
8
+ `image` text,
9
+ `role` text NOT NULL,
10
+ `created_at` integer NOT NULL,
11
+ `deleted_at` integer,
12
+ `preferences` text DEFAULT '{}',
13
+ `metadata` text DEFAULT '{}',
14
+ `onboarding` integer,
15
+ `flags` text DEFAULT '[]',
16
+ FOREIGN KEY (`organization_id`) REFERENCES `organizations`(`id`) ON UPDATE no action ON DELETE no action,
17
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
18
+ );
19
+ --> statement-breakpoint
20
+ INSERT INTO `__new_members`("id", "organization_id", "user_id", "email", "name", "image", "role", "created_at", "deleted_at", "preferences", "metadata", "onboarding", "flags") SELECT "id", "organization_id", "user_id", NULL, "name", "image", "role", "created_at", "deleted_at", "preferences", "metadata", "onboarding", "flags" FROM `members`;--> statement-breakpoint
21
+ DROP TABLE `members`;--> statement-breakpoint
22
+ ALTER TABLE `__new_members` RENAME TO `members`;--> statement-breakpoint
23
+ PRAGMA foreign_keys=ON;--> statement-breakpoint
24
+ CREATE UNIQUE INDEX `members_attached_user_organization_unique` ON `members` (`user_id`,`organization_id`) WHERE "members"."user_id" is not null;--> statement-breakpoint
25
+ CREATE UNIQUE INDEX `members_live_pending_email_organization_unique` ON `members` (`email`,`organization_id`) WHERE "members"."user_id" is null and "members"."deleted_at" is null;--> statement-breakpoint
26
+ ALTER TABLE `invitations` ADD `member_id` text REFERENCES members(id);
@@ -0,0 +1,47 @@
1
+ CREATE TABLE `account_claims` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `claim_user_id` text NOT NULL,
4
+ `status` text NOT NULL,
5
+ `code` text,
6
+ `expires_at` integer,
7
+ `claimed_at` integer,
8
+ `claimed_email` text,
9
+ `created_at` integer NOT NULL,
10
+ `updated_at` integer,
11
+ FOREIGN KEY (`claim_user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
12
+ );
13
+ --> statement-breakpoint
14
+ PRAGMA foreign_keys=OFF;--> statement-breakpoint
15
+ CREATE TABLE `__new_account_claim_magic_links` (
16
+ `id` text PRIMARY KEY NOT NULL,
17
+ `claim_id` text NOT NULL,
18
+ `user_id` text NOT NULL,
19
+ `email` text NOT NULL,
20
+ `token` text NOT NULL,
21
+ `url` text NOT NULL,
22
+ `expires_at` integer,
23
+ `created_at` integer NOT NULL,
24
+ FOREIGN KEY (`claim_id`) REFERENCES `account_claims`(`id`) ON UPDATE no action ON DELETE cascade,
25
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
26
+ );
27
+ --> statement-breakpoint
28
+ INSERT INTO `__new_account_claim_magic_links`("id", "claim_id", "user_id", "email", "token", "url", "expires_at", "created_at") SELECT "id", "claim_id", "user_id", "email", "token", "url", "expires_at", "created_at" FROM `account_claim_magic_links`;--> statement-breakpoint
29
+ DROP TABLE `account_claim_magic_links`;--> statement-breakpoint
30
+ ALTER TABLE `__new_account_claim_magic_links` RENAME TO `account_claim_magic_links`;--> statement-breakpoint
31
+ PRAGMA foreign_keys=ON;--> statement-breakpoint
32
+ CREATE TABLE `__new_waitlist` (
33
+ `id` text PRIMARY KEY NOT NULL,
34
+ `name` text,
35
+ `email` text,
36
+ `created_at` integer NOT NULL,
37
+ `updated_at` integer,
38
+ `status` text DEFAULT 'WAITLIST' NOT NULL,
39
+ `code` text,
40
+ `expires_at` integer,
41
+ `user_id` text,
42
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
43
+ );
44
+ --> statement-breakpoint
45
+ INSERT INTO `__new_waitlist`("id", "name", "email", "created_at", "updated_at", "status", "code", "expires_at", "user_id") SELECT "id", "name", "email", "created_at", "updated_at", "status", "code", "expires_at", "user_id" FROM `waitlist`;--> statement-breakpoint
46
+ DROP TABLE `waitlist`;--> statement-breakpoint
47
+ ALTER TABLE `__new_waitlist` RENAME TO `waitlist`;
@@ -0,0 +1,4 @@
1
+ DROP INDEX `users_payment_customer_id_unique`;--> statement-breakpoint
2
+ ALTER TABLE `users` DROP COLUMN `payment_customer_id`;--> statement-breakpoint
3
+ ALTER TABLE `users` DROP COLUMN `payment_plan_tier`;--> statement-breakpoint
4
+ ALTER TABLE `users` DROP COLUMN `payment_plan_expires_at`;
@@ -0,0 +1,99 @@
1
+ DROP TABLE `teammembers`;--> statement-breakpoint
2
+ DROP TABLE `teams`;--> statement-breakpoint
3
+ PRAGMA foreign_keys=OFF;--> statement-breakpoint
4
+ CREATE TABLE `__new_ai_usage` (
5
+ `id` text PRIMARY KEY NOT NULL,
6
+ `user_id` text,
7
+ `member_id` text,
8
+ `team_id` text,
9
+ `organization_id` text,
10
+ `feature` text NOT NULL,
11
+ `provider` text NOT NULL,
12
+ `model` text NOT NULL,
13
+ `input_tokens` integer,
14
+ `output_tokens` integer,
15
+ `total_tokens` integer,
16
+ `cost` real,
17
+ `trace_id` text,
18
+ `created_at` integer NOT NULL,
19
+ `metadata` text,
20
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE set null,
21
+ FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON UPDATE no action ON DELETE set null,
22
+ FOREIGN KEY (`organization_id`) REFERENCES `organizations`(`id`) ON UPDATE no action ON DELETE set null
23
+ );
24
+ --> statement-breakpoint
25
+ INSERT INTO `__new_ai_usage`("id", "user_id", "member_id", "team_id", "organization_id", "feature", "provider", "model", "input_tokens", "output_tokens", "total_tokens", "cost", "trace_id", "created_at", "metadata") SELECT "id", "user_id", "member_id", "team_id", "organization_id", "feature", "provider", "model", "input_tokens", "output_tokens", "total_tokens", "cost", "trace_id", "created_at", "metadata" FROM `ai_usage`;--> statement-breakpoint
26
+ DROP TABLE `ai_usage`;--> statement-breakpoint
27
+ ALTER TABLE `__new_ai_usage` RENAME TO `ai_usage`;--> statement-breakpoint
28
+ PRAGMA foreign_keys=ON;--> statement-breakpoint
29
+ CREATE TABLE `__new_files` (
30
+ `id` text PRIMARY KEY NOT NULL,
31
+ `created_at` integer NOT NULL,
32
+ `updated_at` integer,
33
+ `deleted_at` integer,
34
+ `user_id` text,
35
+ `member_id` text,
36
+ `organization_id` text,
37
+ `team_id` text,
38
+ `bucket` text NOT NULL,
39
+ `key` text NOT NULL,
40
+ `original_name` text NOT NULL,
41
+ `original_extension` text,
42
+ `content_type` text NOT NULL,
43
+ `size_bytes` integer,
44
+ `etag` text,
45
+ `checksum_sha256` text,
46
+ `metadata` text,
47
+ `status` text NOT NULL,
48
+ `uploaded_at` integer,
49
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE set null,
50
+ FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON UPDATE no action ON DELETE set null,
51
+ FOREIGN KEY (`organization_id`) REFERENCES `organizations`(`id`) ON UPDATE no action ON DELETE set null
52
+ );
53
+ --> statement-breakpoint
54
+ INSERT INTO `__new_files`("id", "created_at", "updated_at", "deleted_at", "user_id", "member_id", "organization_id", "team_id", "bucket", "key", "original_name", "original_extension", "content_type", "size_bytes", "etag", "checksum_sha256", "metadata", "status", "uploaded_at") SELECT "id", "created_at", "updated_at", "deleted_at", "user_id", "member_id", "organization_id", "team_id", "bucket", "key", "original_name", "original_extension", "content_type", "size_bytes", "etag", "checksum_sha256", "metadata", "status", "uploaded_at" FROM `files`;--> statement-breakpoint
55
+ DROP TABLE `files`;--> statement-breakpoint
56
+ ALTER TABLE `__new_files` RENAME TO `files`;--> statement-breakpoint
57
+ CREATE UNIQUE INDEX `files_bucket_key_unique` ON `files` (`bucket`,`key`);--> statement-breakpoint
58
+ CREATE TABLE `__new_invitations` (
59
+ `id` text PRIMARY KEY NOT NULL,
60
+ `organization_id` text NOT NULL,
61
+ `member_id` text,
62
+ `email` text NOT NULL,
63
+ `role` text,
64
+ `status` text NOT NULL,
65
+ `created_at` integer NOT NULL,
66
+ `expires_at` integer NOT NULL,
67
+ `inviter_id` text NOT NULL,
68
+ FOREIGN KEY (`organization_id`) REFERENCES `organizations`(`id`) ON UPDATE no action ON DELETE no action,
69
+ FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON UPDATE no action ON DELETE no action,
70
+ FOREIGN KEY (`inviter_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
71
+ );
72
+ --> statement-breakpoint
73
+ INSERT INTO `__new_invitations`("id", "organization_id", "member_id", "email", "role", "status", "created_at", "expires_at", "inviter_id") SELECT "id", "organization_id", "member_id", "email", "role", "status", "created_at", "expires_at", "inviter_id" FROM `invitations`;--> statement-breakpoint
74
+ DROP TABLE `invitations`;--> statement-breakpoint
75
+ ALTER TABLE `__new_invitations` RENAME TO `invitations`;--> statement-breakpoint
76
+ CREATE TABLE `__new_posts` (
77
+ `id` text PRIMARY KEY NOT NULL,
78
+ `author_user_id` text,
79
+ `member_id` text,
80
+ `organization_id` text,
81
+ `team_id` text,
82
+ `title` text NOT NULL,
83
+ `slug` text NOT NULL,
84
+ `excerpt` text,
85
+ `content` text NOT NULL,
86
+ `status` text DEFAULT 'draft' NOT NULL,
87
+ `published_at` integer,
88
+ `created_at` integer NOT NULL,
89
+ `updated_at` integer,
90
+ `deleted_at` integer,
91
+ FOREIGN KEY (`author_user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE set null,
92
+ FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON UPDATE no action ON DELETE set null,
93
+ FOREIGN KEY (`organization_id`) REFERENCES `organizations`(`id`) ON UPDATE no action ON DELETE set null
94
+ );
95
+ --> statement-breakpoint
96
+ INSERT INTO `__new_posts`("id", "author_user_id", "member_id", "organization_id", "team_id", "title", "slug", "excerpt", "content", "status", "published_at", "created_at", "updated_at", "deleted_at") SELECT "id", "author_user_id", "member_id", "organization_id", "team_id", "title", "slug", "excerpt", "content", "status", "published_at", "created_at", "updated_at", "deleted_at" FROM `posts`;--> statement-breakpoint
97
+ DROP TABLE `posts`;--> statement-breakpoint
98
+ ALTER TABLE `__new_posts` RENAME TO `posts`;--> statement-breakpoint
99
+ CREATE UNIQUE INDEX `posts_slug_unique` ON `posts` (`slug`);
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `sessions` DROP COLUMN `active_team_id`;--> statement-breakpoint
2
+ ALTER TABLE `sessions` DROP COLUMN `active_team_role`;