Integrate local business workflow and SaaS redesign

This commit is contained in:
2026-06-12 21:08:35 +02:00
parent f00c5a3193
commit 21c7e4c9a4
88 changed files with 2683 additions and 849 deletions

View File

@@ -96,7 +96,7 @@ export default defineSchema({
userId: v.string(),
message: v.string(),
read: v.boolean(),
}).index("by_user", ["userId"]),
}).index("by_user_read", ["userId", "read"]),
});
```
@@ -131,8 +131,9 @@ export const listUnread = query({
handler: async (ctx, args) => {
return await ctx.db
.query("notifications")
.withIndex("by_user", (q) => q.eq("userId", args.userId))
.filter((q) => q.eq(q.field("read"), false))
.withIndex("by_user_read", (q) =>
q.eq("userId", args.userId).eq("read", false),
)
.collect();
},
});
@@ -208,6 +209,8 @@ Note the reference path shape: a function in
- If the component needs pagination, use `paginator` from `convex-helpers`
instead of built-in `.paginate()`, because `.paginate()` does not work across
the component boundary.
- Define indexes for queried fields instead of using Convex `.filter()` after a
database query.
- Add `args` and `returns` validators to all public component functions, because
the component boundary requires explicit type contracts.
@@ -263,14 +266,14 @@ export const sendNotification = mutation({
```ts
// Bad: parent app table IDs are not valid component validators
args: {
userId: v.id("users");
userId: v.id("users"),
}
```
```ts
// Good: treat parent-owned IDs as strings at the boundary
args: {
userId: v.string();
userId: v.string(),
}
```

View File

@@ -10,7 +10,7 @@ for Convex schema and data migrations.
users: defineTable({
name: v.string(),
role: v.optional(v.union(v.literal("user"), v.literal("admin"))),
});
}).index("by_role", ["role"]);
// Migration: backfill the field
export const addDefaultRole = migrations.define({
@@ -225,7 +225,7 @@ export const verifyMigration = query({
handler: async (ctx) => {
const remaining = await ctx.db
.query("users")
.filter((q) => q.eq(q.field("role"), undefined))
.withIndex("by_role", (q) => q.eq("role", undefined))
.take(10);
return {