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.
- package/package.json +3 -3
- package/templates/minimal-app/.dockerignore.tpl +6 -0
- package/templates/minimal-app/apps/e2e/playwright.config.ts.tpl +3 -0
- package/templates/minimal-app/apps/e2e/servers.ts.tpl +4 -0
- package/templates/minimal-app/apps/e2e/tests/expo-helpers.ts.tpl +2 -34
- package/templates/minimal-app/apps/e2e/tests/expo-standard.spec.ts.tpl +225 -5
- package/templates/minimal-app/apps/e2e/tests/helpers.ts.tpl +47 -1
- package/templates/minimal-app/apps/e2e/tests/mcp-helpers.ts.tpl +406 -0
- package/templates/minimal-app/apps/e2e/tests/mcp.spec.ts.tpl +108 -0
- package/templates/minimal-app/apps/e2e/tests/standard.spec.ts.tpl +290 -8
- package/templates/minimal-app/apps/expo/app.json.tpl +1 -0
- package/templates/minimal-app/apps/expo/package.json.tpl +4 -0
- package/templates/minimal-app/apps/expo/src/app/_layout.tsx.tpl +4 -1
- package/templates/minimal-app/apps/expo/src/app/notifications.tsx.tpl +70 -0
- package/templates/minimal-app/apps/expo/src/app/organization/accept-invitation.tsx.tpl +8 -16
- package/templates/minimal-app/apps/expo/src/app/posts.tsx.tpl +4 -1
- package/templates/minimal-app/apps/expo/src/lib/trpc.ts.tpl +11 -2
- package/templates/minimal-app/apps/landing/vite.config.ts.tpl +2 -3
- package/templates/minimal-app/apps/server/AGENTS.md.tpl +10 -0
- package/templates/minimal-app/apps/server/db.e2e.ts.tpl +6 -40
- package/templates/minimal-app/apps/server/db.ts.tpl +6 -42
- package/templates/minimal-app/apps/server/drizzle/{0000_wealthy_absorbing_man.sql → 0000_whole_echo.sql} +102 -3
- package/templates/minimal-app/apps/server/drizzle/0001_yummy_spectrum.sql +26 -0
- package/templates/minimal-app/apps/server/drizzle/0002_crazy_lilith.sql +47 -0
- package/templates/minimal-app/apps/server/drizzle/0003_freezing_fantastic_four.sql +4 -0
- package/templates/minimal-app/apps/server/drizzle/0004_slow_ezekiel_stane.sql +99 -0
- package/templates/minimal-app/apps/server/drizzle/0005_wonderful_the_professor.sql +2 -0
- package/templates/minimal-app/apps/server/drizzle/0006_lazy_blue_marvel.sql +159 -0
- package/templates/minimal-app/apps/server/drizzle/0007_abnormal_ultimo.sql +2 -0
- package/templates/minimal-app/apps/server/drizzle/0008_steady_nekra.sql +87 -0
- package/templates/minimal-app/apps/server/drizzle/meta/0000_snapshot.json.tpl +2625 -1780
- package/templates/minimal-app/apps/server/drizzle/meta/0001_snapshot.json.tpl +2671 -1796
- package/templates/minimal-app/apps/server/drizzle/meta/0002_snapshot.json.tpl +2716 -1818
- package/templates/minimal-app/apps/server/drizzle/meta/0003_snapshot.json.tpl +715 -164
- package/templates/minimal-app/apps/server/drizzle/meta/0004_snapshot.json.tpl +2498 -0
- package/templates/minimal-app/apps/server/drizzle/meta/0005_snapshot.json.tpl +2484 -0
- package/templates/minimal-app/apps/server/drizzle/meta/0006_snapshot.json.tpl +3603 -0
- package/templates/minimal-app/apps/server/drizzle/meta/0007_snapshot.json.tpl +3620 -0
- package/templates/minimal-app/apps/server/drizzle/meta/0008_snapshot.json.tpl +3620 -0
- package/templates/minimal-app/apps/server/drizzle/meta/_journal.json.tpl +44 -9
- package/templates/minimal-app/apps/server/src/app.ts.tpl +12 -2
- package/templates/minimal-app/apps/server/src/modules/posts/posts.db.ts.tpl +2 -2
- package/templates/minimal-app/apps/server/src/modules/posts/posts.mcp.ts.tpl +17 -0
- package/templates/minimal-app/apps/server/src/modules/posts/posts.module.ts.tpl +11 -0
- package/templates/minimal-app/apps/server/src/modules/posts/posts.service.ts.tpl +14 -5
- package/templates/minimal-app/apps/server/src/modules/test-harness/test-harness.module.ts.tpl +13 -36
- package/templates/minimal-app/apps/server/src/schema.ts.tpl +16 -2
- package/templates/minimal-app/apps/shared/package.json.tpl +1 -0
- package/templates/minimal-app/apps/shared/src/modules/app/app.constants.ts.tpl +1 -1
- package/templates/minimal-app/apps/shared/src/modules/notification/notification.constants.ts.tpl +5 -0
- package/templates/minimal-app/apps/shared/src/modules/notification/notification.schema.ts.tpl +1 -1
- package/templates/minimal-app/apps/webapp/src/Layout.tsx.tpl +17 -1
- package/templates/minimal-app/apps/webapp/src/Router.tsx.tpl +10 -8
- package/templates/minimal-app/apps/webapp/src/modules/notification/NotificationPreferencesRoute.tsx.tpl +29 -0
- package/templates/minimal-app/apps/webapp/src/modules/notification/StarterWebPush.tsx.tpl +44 -0
- package/templates/minimal-app/apps/webapp/translations/en/{{APP_SLUG}}.json.tpl +8 -0
- package/templates/minimal-app/pnpm-workspace.yaml.tpl +14 -13
- package/templates/minimal-app/template.manifest.json +9 -0
- package/templates/minimal-app/apps/server/drizzle/0001_third_ink.sql +0 -1
- package/templates/minimal-app/apps/server/drizzle/0002_concerned_proudstar.sql +0 -3
- 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
|
|
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
|
-
|
|
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.
|
|
245
|
-
.where(eq(schema.
|
|
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.
|
|
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
|
|
17
|
-
await seedPosts({ orm, userId: user.id, organizationId
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
106
|
-
`
|
|
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
|
|
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`);
|