You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .claude/CLAUDE-KNOWLEDGE.md
+119-1Lines changed: 119 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -122,4 +122,122 @@ A: ESLint may remove "unused" imports. Always verify your changes after auto-fix
122
122
A: Missing newline at end of file. ESLint requires files to end with a newline character.
123
123
124
124
### Q: How do you handle TypeScript errors about missing exports?
125
-
A: Double-check that you're only importing what's actually exported from a module. The error "Module declares 'X' locally, but it is not exported" means you're trying to import something that isn't exported.
125
+
A: Double-check that you're only importing what's actually exported from a module. The error "Module declares 'X' locally, but it is not exported" means you're trying to import something that isn't exported.
126
+
127
+
## Project Transfer Implementation
128
+
129
+
### Q: How do I add a new API endpoint to the internal project?
130
+
A: Create a new route file in `/apps/backend/src/app/api/latest/internal/` using the `createSmartRouteHandler` pattern. Internal endpoints should check `auth.project.id === "internal"` and throw `KnownErrors.ExpectedInternalProject()` if not.
131
+
132
+
### Q: How do team permissions work in Stack Auth?
133
+
A: Team permissions are defined in `/apps/backend/src/lib/permissions.tsx`. The permission `team_admin` (not `$team_admin`) is a normal permission that happens to be defined by default on the internal project. Use `ensureUserTeamPermissionExists` to check if a user has a specific permission.
134
+
135
+
### Q: How do I check team permissions in the backend?
136
+
A: Use `ensureUserTeamPermissionExists` from `/apps/backend/src/lib/request-checks.tsx`. Example:
137
+
```typescript
138
+
awaitensureUserTeamPermissionExists(prisma, {
139
+
tenancy: internalTenancy,
140
+
teamId: teamId,
141
+
userId: userId,
142
+
permissionId: "team_admin",
143
+
errorType: "required",
144
+
recursive: true,
145
+
});
146
+
```
147
+
148
+
### Q: How do I add new functionality to the admin interface?
149
+
A: Don't use server actions. Instead, implement the endpoint functions on the admin-app and admin-interface. Add methods to the AdminProject class in the SDK packages that call the backend API endpoints.
150
+
151
+
### Q: How do I use TeamSwitcher component in the dashboard?
152
+
A: Import `TeamSwitcher` from `@stackframe/stack` and use it like:
153
+
```typescript
154
+
<TeamSwitcher
155
+
triggerClassName="w-full"
156
+
teamId={selectedTeamId}
157
+
onChange={async (team) => {
158
+
setSelectedTeamId(team.id);
159
+
}}
160
+
/>
161
+
```
162
+
163
+
### Q: How do I write E2E tests for backend endpoints?
164
+
A: Import `it` from helpers (not vitest), and set up the project context inside each test:
### Q: What's the difference between ensureTeamMembershipExists and ensureUserTeamPermissionExists?
196
+
A: `ensureTeamMembershipExists` only checks if a user is a member of a team. `ensureUserTeamPermissionExists` checks if a user has a specific permission (like `team_admin`) within that team. The latter also calls `ensureTeamMembershipExists` internally.
197
+
198
+
### Q: How do I handle errors in the backend API?
199
+
A: Use `KnownErrors` from `@stackframe/stack-shared` for standard errors (e.g., `KnownErrors.ProjectNotFound()`). For custom errors, use `StatusError` from `@stackframe/stack-shared/dist/utils/errors` with an HTTP status code and message.
200
+
201
+
### Q: What's the pattern for TypeScript schema validation in API routes?
202
+
A: Use yup schemas from `@stackframe/stack-shared/dist/schema-fields`. Don't use regular yup imports. Example:
### Q: How are teams and projects related in Stack Auth?
208
+
A: Projects belong to teams via the `ownerTeamId` field. Teams exist within the internal project. Users can be members of multiple teams and have different permissions in each team.
209
+
210
+
### Q: How do I properly escape quotes in React components to avoid lint errors?
211
+
A: Use template literals with backticks instead of quotes in JSX text content:
212
+
```typescript
213
+
<Typography>{`Text with "quotes" inside`}</Typography>
214
+
```
215
+
216
+
### Q: What auth headers are needed for internal API calls?
217
+
A: Internal API calls need:
218
+
-`X-Stack-Access-Type: 'server'`
219
+
-`X-Stack-Project-Id: 'internal'`
220
+
-`X-Stack-Secret-Server-Key: <server key>`
221
+
- Either `X-Stack-Auth: Bearer <token>` or a session cookie
222
+
223
+
### Q: How do I reload the page after a successful action in the dashboard?
224
+
A: Use `window.location.reload()` after the action completes. This ensures the UI reflects the latest state from the server.
225
+
226
+
### Q: What's the file structure for API routes in the backend?
227
+
A: Routes follow Next.js App Router conventions in `/apps/backend/src/app/api/latest/`. Each route has a `route.tsx` file that exports HTTP method handlers (GET, POST, etc.).
228
+
229
+
### Q: How do I get all teams a user is a member of in the dashboard?
230
+
A: Use `user.useTeams()` where `user` is from `useUser({ or: 'redirect', projectIdMustMatch: "internal" })`.
231
+
232
+
### Q: What's the difference between client and server access types?
233
+
A: Client access type is for frontend applications and has limited permissions. Server access type is for backend operations and requires a secret key. Admin access type is for dashboard operations with full permissions.
234
+
235
+
### Q: How to avoid TypeScript "unnecessary conditional" errors when checking auth.user?
236
+
A: If the schema defines `auth.user` as `.defined()`, TypeScript knows it can't be null, so checking `if (!auth.user)` causes a lint error. Remove the check or adjust the schema if the field can be undefined.
237
+
238
+
### Q: What to do when TypeScript can't find module '@stackframe/stack' declarations?
239
+
A: This happens when packages haven't been built yet. Run these commands in order:
constcurrentOwnerTeam=teams.find(team=>team.id===project.ownerTeamId)??throwErr(`Owner team of project ${project.id} not found in user's teams?`,{projectId: project.id, teams });
31
+
32
+
// Check if user has team_admin permission for the current team
0 commit comments