authentik now working with convex auth
This commit is contained in:
281
AGENTS.md
Normal file
281
AGENTS.md
Normal file
@@ -0,0 +1,281 @@
|
||||
# AGENTS.md - Convex Turbo Monorepo
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Build/Lint/Test Commands
|
||||
|
||||
```bash
|
||||
# Development
|
||||
bun dev # Run all apps (Next.js + Expo + Backend)
|
||||
bun dev:next # Run Next.js + Convex backend only
|
||||
bun dev:expo # Run Expo + Convex backend only
|
||||
bun dev:backend # Run Convex backend only
|
||||
bun dev:expo:tunnel # Expo with tunnel for physical device
|
||||
|
||||
# Quality
|
||||
bun lint # Lint all packages
|
||||
bun lint:fix # Lint and auto-fix
|
||||
bun format # Check formatting
|
||||
bun format:fix # Fix formatting
|
||||
bun typecheck # TypeScript type checking
|
||||
|
||||
# Build
|
||||
bun build # Build all packages
|
||||
|
||||
# Single Package Commands (use Turborepo filters)
|
||||
bun turbo run dev -F @gib/next # Single app dev
|
||||
bun turbo run lint -F @gib/backend # Lint single package
|
||||
bun turbo run typecheck -F @gib/ui # Typecheck single package
|
||||
|
||||
# Cleanup
|
||||
bun clean # Clean all node_modules (git clean)
|
||||
bun clean:ws # Clean workspace caches
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
convex-monorepo/
|
||||
├── apps/
|
||||
│ ├── next/ # Next.js 16 web app (@gib/next)
|
||||
│ └── expo/ # Expo 54 mobile app (@gib/expo)
|
||||
├── packages/
|
||||
│ ├── backend/ # Convex backend (@gib/backend)
|
||||
│ │ └── convex/ # Convex functions, schema, auth
|
||||
│ └── ui/ # Shared shadcn/ui components (@gib/ui)
|
||||
├── tools/
|
||||
│ ├── eslint/ # @gib/eslint-config
|
||||
│ ├── prettier/ # @gib/prettier-config
|
||||
│ ├── tailwind/ # @gib/tailwind-config
|
||||
│ └── typescript/ # @gib/tsconfig
|
||||
├── docker/ # Self-hosted Convex deployment
|
||||
└── .env # Central environment variables
|
||||
```
|
||||
|
||||
## Dependency Management
|
||||
|
||||
### Catalogs (Single Source of Truth)
|
||||
|
||||
All shared dependencies are defined in root `package.json` catalogs:
|
||||
|
||||
```json
|
||||
"catalog": {
|
||||
"prettier": "^3.6.2",
|
||||
"typescript": "^5.9.3",
|
||||
"eslint": "^9.38.0"
|
||||
},
|
||||
"catalogs": {
|
||||
"convex": { "convex": "^1.28.0", "@convex-dev/auth": "^0.0.81" },
|
||||
"react19": { "react": "^19.1.4", "react-dom": "19.1.4" }
|
||||
}
|
||||
```
|
||||
|
||||
### Using Catalogs in Packages
|
||||
|
||||
```json
|
||||
"dependencies": {
|
||||
"convex": "catalog:convex",
|
||||
"react": "catalog:react19",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gib/eslint-config": "workspace:*",
|
||||
"@gib/ui": "workspace:*"
|
||||
}
|
||||
```
|
||||
|
||||
### Updating Dependencies
|
||||
|
||||
**IMPORTANT:** Do NOT use `bun update` directly - it may replace catalog: with versions.
|
||||
|
||||
```bash
|
||||
# Correct workflow:
|
||||
1. Edit version in root package.json catalog section
|
||||
2. Run: bun install
|
||||
3. Verify with: bun lint:ws (runs sherif)
|
||||
```
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
### Imports (via @gib/prettier-config)
|
||||
|
||||
```typescript
|
||||
// Order: Types → React → Next/Expo → Third-party → @gib/* → Local
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { api } from '@/convex/_generated/api';
|
||||
import { ConvexError } from 'convex/values';
|
||||
|
||||
import { cn } from '@gib/ui';
|
||||
|
||||
import type { User } from './types';
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
|
||||
- Strict mode enabled (`noUncheckedIndexedAccess: true`)
|
||||
- Use `type` imports: `import type { X } from 'y'`
|
||||
- Prefix unused vars with `_`: `const _unused = ...`
|
||||
- Avoid `any` - use `unknown` with type guards
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
- Components: `PascalCase` (`UserProfile.tsx`)
|
||||
- Functions/variables: `camelCase`
|
||||
- Constants: `SCREAMING_SNAKE_CASE`
|
||||
- Files: `kebab-case.ts` (except components)
|
||||
|
||||
### Error Handling
|
||||
|
||||
```typescript
|
||||
// Convex functions - use ConvexError
|
||||
import { ConvexError } from 'convex/values';
|
||||
throw new ConvexError('User not found.');
|
||||
|
||||
// Client-side - handle gracefully
|
||||
try { ... } catch (e) {
|
||||
if (e instanceof ConvexError) { /* handle */ }
|
||||
}
|
||||
```
|
||||
|
||||
### Formatting
|
||||
|
||||
- Single quotes, trailing commas
|
||||
- 80 char line width, 2 space indent
|
||||
- Tailwind classes sorted via prettier-plugin-tailwindcss
|
||||
- Use `cn()` for conditional classes: `cn('base', condition && 'active')`
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### Central .env (root)
|
||||
|
||||
All env vars in `/.env`. Apps load via `with-env` script:
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"dev": "bun with-env next dev --turbo",
|
||||
"with-env": "dotenv -e ../../.env --"
|
||||
}
|
||||
```
|
||||
|
||||
### Required Variables
|
||||
|
||||
```bash
|
||||
# Convex
|
||||
CONVEX_SELF_HOSTED_URL=https://api.convex.example.com
|
||||
CONVEX_SELF_HOSTED_ADMIN_KEY=<generated>
|
||||
CONVEX_SITE_URL=https://convex.example.com
|
||||
NEXT_PUBLIC_CONVEX_URL=https://api.convex.example.com
|
||||
|
||||
# Auth (sync to Convex deployment)
|
||||
AUTH_AUTHENTIK_ID=
|
||||
AUTH_AUTHENTIK_SECRET=
|
||||
AUTH_AUTHENTIK_ISSUER=
|
||||
USESEND_API_KEY=
|
||||
```
|
||||
|
||||
### Syncing to Convex Deployment
|
||||
|
||||
```bash
|
||||
# Upload env vars to self-hosted Convex
|
||||
npx convex env set AUTH_AUTHENTIK_ID "value"
|
||||
npx convex env set AUTH_AUTHENTIK_SECRET "value"
|
||||
npx convex env set AUTH_AUTHENTIK_ISSUER "value"
|
||||
npx convex env set USESEND_API_KEY "value"
|
||||
npx convex env set CONVEX_SITE_URL "https://convex.example.com"
|
||||
```
|
||||
|
||||
## Convex Backend Patterns
|
||||
|
||||
### Schema (`packages/backend/convex/schema.ts`)
|
||||
|
||||
```typescript
|
||||
import { defineSchema, defineTable } from 'convex/server';
|
||||
import { authTables } from '@convex-dev/auth/server';
|
||||
|
||||
export default defineSchema({
|
||||
...authTables,
|
||||
users: defineTable({ ... }).index('email', ['email']),
|
||||
});
|
||||
```
|
||||
|
||||
### Queries & Mutations
|
||||
|
||||
```typescript
|
||||
import { v } from 'convex/values';
|
||||
|
||||
import { mutation, query } from './_generated/server';
|
||||
|
||||
export const getUser = query({
|
||||
args: { userId: v.id('users') },
|
||||
handler: async (ctx, args) => {
|
||||
return await ctx.db.get(args.userId);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Auth
|
||||
|
||||
```typescript
|
||||
import { getAuthUserId } from '@convex-dev/auth/server';
|
||||
|
||||
// In any query/mutation:
|
||||
const userId = await getAuthUserId(ctx);
|
||||
if (!userId) throw new ConvexError('Not authenticated.');
|
||||
```
|
||||
|
||||
## Next.js Patterns
|
||||
|
||||
### Convex Provider Setup
|
||||
|
||||
```tsx
|
||||
// src/components/providers/ConvexClientProvider.tsx
|
||||
'use client';
|
||||
|
||||
import { ConvexAuthNextjsProvider } from '@convex-dev/auth/nextjs';
|
||||
import { ConvexReactClient } from 'convex/react';
|
||||
|
||||
const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
|
||||
|
||||
export const ConvexClientProvider = ({ children }) => (
|
||||
<ConvexAuthNextjsProvider client={convex}>
|
||||
{children}
|
||||
</ConvexAuthNextjsProvider>
|
||||
);
|
||||
```
|
||||
|
||||
### Path Aliases
|
||||
|
||||
- `@/*` → `./src/*` (Next.js)
|
||||
- `~/*` → `./src/*` (Expo)
|
||||
|
||||
## Expo Patterns
|
||||
|
||||
### NativeWind (Tailwind for RN)
|
||||
|
||||
```tsx
|
||||
import '../styles.css';
|
||||
|
||||
// Use className like web: <View className="flex-1 bg-background" />
|
||||
```
|
||||
|
||||
### Secure Storage for Auth
|
||||
|
||||
```typescript
|
||||
import * as SecureStore from 'expo-secure-store';
|
||||
|
||||
// Tokens stored via SecureStore, not AsyncStorage
|
||||
```
|
||||
|
||||
## Known Issues / Cleanup Needed
|
||||
|
||||
1. **Apps reference @acme/_ instead of @gib/_** - Legacy T3 template imports
|
||||
2. **TRPC imports exist but no TRPC** - Replace with Convex client
|
||||
3. **Expo uses better-auth** - Should use @convex-dev/auth
|
||||
4. **@gib/ui uses pnpm dlx** - Should use bunx for shadcn
|
||||
|
||||
## Adding UI Components
|
||||
|
||||
```bash
|
||||
bun ui-add # Interactive shadcn/ui component addition
|
||||
```
|
||||
Reference in New Issue
Block a user