Skip to content

Commit 7abf23f

Browse files
committed
Document helper APIs and add agent CI guidance
- expand README with auth/admin helper usage examples - document `createPrimitives` and Zod helpers behavior - add AGENTS.md and CLAUDE.md notes to run `pnpm run ci`
1 parent 65a5214 commit 7abf23f

File tree

3 files changed

+87
-4
lines changed

3 files changed

+87
-4
lines changed

AGENTS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Agent Notes
2+
3+
Verify your changes with:
4+
5+
```bash
6+
pnpm run ci
7+
```

CLAUDE.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Agent Notes
2+
3+
Verify your changes with:
4+
5+
```bash
6+
pnpm run ci
7+
```

README.md

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,29 @@ export const {
4242
});
4343
```
4444

45+
`createPrimitives` returns six helpers:
46+
47+
- `authQuery`: Query that requires an authenticated user.
48+
- `authMutation`: Mutation that requires an authenticated user.
49+
- `authAction`: Action that requires an authenticated user.
50+
- `adminQuery`: Query that requires an authenticated admin user.
51+
- `adminMutation`: Mutation that requires an authenticated admin user.
52+
- `adminAction`: Action that requires an authenticated admin user.
53+
54+
All six helpers resolve your user through `resolveUser`. They add `ctx.user` and `ctx.userId` to the handler context, and the `admin*` variants also enforce `isAdmin(user)`.
55+
4556
## Usage
4657

4758
```ts
48-
import { adminMutation, authQuery, createError } from './primitives';
59+
import {
60+
adminAction,
61+
adminMutation,
62+
adminQuery,
63+
authAction,
64+
authMutation,
65+
authQuery,
66+
createError,
67+
} from '@amadeni/convex-lib';
4968

5069
export const getProfile = authQuery({
5170
args: {},
@@ -54,23 +73,73 @@ export const getProfile = authQuery({
5473
},
5574
});
5675

76+
export const updateProfile = authMutation({
77+
args: {},
78+
handler: async ctx => {
79+
return { userId: ctx.userId };
80+
},
81+
});
82+
83+
export const syncProfile = authAction({
84+
args: {},
85+
handler: async ctx => {
86+
return { email: ctx.user.email };
87+
},
88+
});
89+
90+
export const listUsers = adminQuery({
91+
args: {},
92+
handler: async ctx => {
93+
return { requestedBy: ctx.user.email };
94+
},
95+
});
96+
5797
export const deleteAccount = adminMutation({
5898
args: {},
5999
handler: async (ctx, args) => {
60100
void args;
61101
throw createError.forbidden();
62102
},
63103
});
104+
105+
export const rebuildSearchIndex = adminAction({
106+
args: {},
107+
handler: async ctx => {
108+
return { requestedBy: ctx.userId };
109+
},
110+
});
64111
```
65112

113+
## Zod Helpers
114+
66115
```ts
67116
import { addSystemFields, zid } from '@amadeni/convex-lib';
68117
import { z } from 'zod';
69118

70119
const userId = zid('users');
71120

72-
const userShape = addSystemFields('users', {
73-
email: z.string().email(),
74-
role: z.string(),
121+
const userSchema = z.object(
122+
addSystemFields('users', {
123+
email: z.string().email(),
124+
role: z.string(),
125+
}),
126+
);
127+
```
128+
129+
`zid('users')` gives you a Zod validator for a Convex document ID represented as a string. The table name is mainly for readability and type intent.
130+
131+
`addSystemFields('users', shape)` is useful when you already have a base document shape and want to extend it with the Convex-managed fields every stored document has:
132+
133+
- `_id`: The document ID for that table.
134+
- `_creationTime`: The timestamp assigned by Convex.
135+
136+
It returns a Zod object shape, not a finished schema, so wrap it with `z.object(...)` as shown above.
137+
138+
```ts
139+
const parsedUser = userSchema.parse({
140+
_id: 'abc123',
141+
_creationTime: Date.now(),
142+
email: 'hello@example.com',
143+
role: 'admin',
75144
});
76145
```

0 commit comments

Comments
 (0)