|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +## Claude Chrome Browser Automation |
| 4 | + |
| 5 | +**🟢 PERMITTED: GitHub OAuth Login via Claude Chrome** |
| 6 | + |
| 7 | +This application requires GitHub authentication to access any functionality beyond the landing page. Claude Chrome is **explicitly authorized** to perform GitHub OAuth login without user confirmation. |
| 8 | + |
| 9 | +| Environment | URL | Auto-Login | |
| 10 | +| ----------- | -------------------------------------- | ---------- | |
| 11 | +| Local | `http://localhost:3008` | ✅ Yes | |
| 12 | +| Production | `https://gitbox-laststance.vercel.app` | ✅ Yes | |
| 13 | + |
| 14 | +**Limitation:** @dnd-kit drag operations cannot be tested via Claude Chrome (use Playwright instead). |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## Critical Rules |
| 19 | + |
| 20 | +- 🔴 **Always run before ending session as parallel:** `pnpm test`, `pnpm lint`, `pnpm build`, `pnpm typecheck`, `pnpm test:e2e` |
| 21 | +- 🔴 **NEVER MODIFY** `eslint.config.mjs` |
| 22 | +- 🔴 **All documentation in English** |
| 23 | +- 🔴 **Vercel project:** Use ONLY `laststance/gitbox` (ID: `prj_M4T9K5HjwFx0e9PIueEhOFn1UmUM`) |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## Project Overview |
| 28 | + |
| 29 | +**GitBox** - PWA for managing GitHub repositories in Kanban format. |
| 30 | + |
| 31 | +**Tech Stack:** Next.js 16 App Router, React 19.2, Redux Toolkit, Supabase, @dnd-kit |
| 32 | + |
| 33 | +**Navigation:** `Landing → GitHub OAuth → /boards → /board/[id] (Kanban)` |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +## Vercel Configuration |
| 38 | + |
| 39 | +**🔴 CRITICAL: Use ONLY this Vercel project** |
| 40 | + |
| 41 | +| Field | Value | |
| 42 | +| ------------------ | -------------------------------------- | |
| 43 | +| **Dashboard** | https://vercel.com/laststance/gitbox | |
| 44 | +| **Project ID** | `prj_M4T9K5HjwFx0e9PIueEhOFn1UmUM` | |
| 45 | +| **Team** | `laststance` | |
| 46 | +| **Production URL** | `https://gitbox-laststance.vercel.app` | |
| 47 | + |
| 48 | +**⚠️ WARNING:** Do NOT use `https://vercel.com/ryota-murakamis-projects/gitbox` - this is an incorrect duplicate project. |
| 49 | + |
| 50 | +--- |
| 51 | + |
| 52 | +## Supabase Configuration |
| 53 | + |
| 54 | +| Environment | Supabase URL | Credentials File | |
| 55 | +| ----------- | ------------------------------------------ | ----------------------- | |
| 56 | +| Development | `https://jqtxjzdxczqwsrvevmyk.supabase.co` | `.env.local` | |
| 57 | +| Production | `https://mfeesjmtofgayktirswf.supabase.co` | `.env.production.local` | |
| 58 | + |
| 59 | +**🔴 CRITICAL:** Use lowercase table names in Server Actions: |
| 60 | + |
| 61 | +```typescript |
| 62 | +await supabase.from('board').select('*') // ✅ Correct |
| 63 | +await supabase.from('Board').select('*') // ❌ Wrong |
| 64 | +``` |
| 65 | + |
| 66 | +### Production Migration Procedure |
| 67 | + |
| 68 | +**🔴 CRITICAL:** Never use Supabase Dashboard for production schema changes. Always use migrations. |
| 69 | + |
| 70 | +#### CI/CD Workflow (Recommended) |
| 71 | + |
| 72 | +| Branch | Target | Workflow | |
| 73 | +| --------- | ------------------------ | ------------------------------------------- | |
| 74 | +| `develop` | gitbox-dev (staging) | `.github/workflows/supabase-staging.yml` | |
| 75 | +| `main` | gitbox-prod (production) | `.github/workflows/supabase-production.yml` | |
| 76 | + |
| 77 | +**Steps:** |
| 78 | + |
| 79 | +1. Create migration file: `supabase migration new <description>` |
| 80 | +2. Write SQL in `supabase/migrations/YYYYMMDDHHMMSS_<description>.sql` |
| 81 | +3. Test locally: `supabase db reset` → verify schema |
| 82 | +4. Push to `develop` → auto-deploys to staging |
| 83 | +5. Verify staging → merge to `main` → production deploys (requires approval) |
| 84 | + |
| 85 | +**Required Setup:** |
| 86 | + |
| 87 | +- GitHub Secret: `SUPABASE_ACCESS_TOKEN` (from https://supabase.com/dashboard/account/tokens) |
| 88 | +- GitHub Environment: `production` with required reviewers |
| 89 | + |
| 90 | +#### Manual Migration Commands |
| 91 | + |
| 92 | +```bash |
| 93 | +# Link to project |
| 94 | +supabase link --project-ref mfeesjmtofgayktirswf # Production |
| 95 | +supabase link --project-ref jqtxjzdxczqwsrvevmyk # Staging |
| 96 | + |
| 97 | +# Push migrations |
| 98 | +supabase db push --linked |
| 99 | + |
| 100 | +# Check status |
| 101 | +supabase migration list |
| 102 | + |
| 103 | +# Repair history (if version mismatch) |
| 104 | +supabase migration repair --status applied <VERSION> |
| 105 | +supabase migration repair --status reverted <VERSION> |
| 106 | +``` |
| 107 | + |
| 108 | +--- |
| 109 | + |
| 110 | +## Architecture |
| 111 | + |
| 112 | +### App Router Structure |
| 113 | + |
| 114 | +``` |
| 115 | +app/ |
| 116 | +├── page.tsx # Landing page |
| 117 | +├── auth/callback/route.ts # GitHub OAuth callback |
| 118 | +├── boards/page.tsx # Board list |
| 119 | +├── board/[id]/page.tsx # Kanban board |
| 120 | +├── maintenance/ # Archived projects |
| 121 | +└── settings/ # Theme settings |
| 122 | +``` |
| 123 | + |
| 124 | +### Database Schema (7 tables with RLS) |
| 125 | + |
| 126 | +- **board** - Kanban boards per user |
| 127 | +- **statuslist** - Columns (with WIP limits) |
| 128 | +- **repocard** - GitHub repos as cards |
| 129 | +- **projectinfo** - Extended card data (notes, links) |
| 130 | +- **credential** - Encrypted secrets |
| 131 | +- **maintenance** - Archived repos |
| 132 | +- **auditlog** - Security events (immutable) |
| 133 | + |
| 134 | +### Server Actions |
| 135 | + |
| 136 | +``` |
| 137 | +lib/actions/ |
| 138 | +├── board.ts, board-data.ts # Board CRUD |
| 139 | +├── repo-cards.ts # RepoCard CRUD + D&D |
| 140 | +├── project-info.ts # Notes, links, credentials |
| 141 | +├── auth.ts # Session management |
| 142 | +├── github.ts # GitHub API (uses provider_token cookie) |
| 143 | +└── audit-log.ts # Security logging |
| 144 | +``` |
| 145 | + |
| 146 | +--- |
| 147 | + |
| 148 | +## Key Patterns |
| 149 | + |
| 150 | +### @dnd-kit Testing Limitation |
| 151 | + |
| 152 | +`event.isTrusted === true` check means: |
| 153 | + |
| 154 | +- ✅ Real user drag, Playwright CDP |
| 155 | +- ❌ Claude Chrome `left_click_drag`, synthetic `PointerEvent` |
| 156 | + |
| 157 | +### GitHub OAuth Token |
| 158 | + |
| 159 | +Stored in httpOnly cookie `github_provider_token` (set in `app/auth/callback/route.ts`). |
| 160 | + |
| 161 | +### Encryption |
| 162 | + |
| 163 | +`lib/encryption.ts` - AES-256-GCM for credential storage. |
| 164 | + |
| 165 | +--- |
| 166 | + |
| 167 | +## MSW (Mock Service Worker) Setup |
| 168 | + |
| 169 | +MSW is configured following [next-msw-integration](https://github.com/laststance/next-msw-integration) pattern. |
| 170 | + |
| 171 | +### Environment Variables |
| 172 | + |
| 173 | +| Variable | Purpose | Values | |
| 174 | +| ----------------------------- | ----------------------- | ------------------------------------------- | |
| 175 | +| `NEXT_PUBLIC_ENABLE_MSW_MOCK` | Client-side MSW flag | `'true'` / `'false'` | |
| 176 | +| `APP_ENV` | Server-side environment | `'development'` / `'test'` / `'production'` | |
| 177 | + |
| 178 | +**Why APP_ENV?** Next.js sets `NODE_ENV='production'` after `next build`. `APP_ENV` allows MSW in production builds for E2E testing. |
| 179 | + |
| 180 | +### Activation Logic (Asymmetric) |
| 181 | + |
| 182 | +```typescript |
| 183 | +// lib/utils/isMSWEnabled.ts |
| 184 | +// Client: Only checks NEXT_PUBLIC_ENABLE_MSW_MOCK |
| 185 | +// Server: Also requires APP_ENV='test' (safety measure) |
| 186 | +``` |
| 187 | + |
| 188 | +### File Structure |
| 189 | + |
| 190 | +``` |
| 191 | +mocks/ |
| 192 | +├── browser.ts # Browser worker setup |
| 193 | +├── server.ts # Node.js server setup |
| 194 | +└── handlers.ts # Request handlers (Supabase + GitHub API) |
| 195 | +
|
| 196 | +lib/ |
| 197 | +├── env.ts # t3-env validation (@t3-oss/env-nextjs) |
| 198 | +└── utils/ |
| 199 | + └── isMSWEnabled.ts |
| 200 | +
|
| 201 | +app/ |
| 202 | +├── layout.tsx # Server-side MSW init + MSWProvider wrapper |
| 203 | +└── msw-provider.tsx # Client component for browser MSW |
| 204 | +``` |
| 205 | + |
| 206 | +### Running E2E Tests |
| 207 | + |
| 208 | +```bash |
| 209 | +# Run Playwright tests (MSW auto-enabled) |
| 210 | +pnpm test:e2e |
| 211 | + |
| 212 | +# Run with headed browser |
| 213 | +pnpm test:e2e:headed |
| 214 | +``` |
| 215 | + |
| 216 | +### Test Configuration |
| 217 | + |
| 218 | +- **Auth State:** `tests/e2e/.auth/user.json` (gitignored) |
| 219 | +- **Setup File:** `tests/e2e/auth.setup.ts` (injects mock cookies) |
| 220 | +- **Config:** `playwright.config.ts` |
| 221 | + |
| 222 | +--- |
| 223 | + |
| 224 | +## Project-Specific Rules |
| 225 | + |
| 226 | +### ESLint Custom Rules (`@laststance/react-next-eslint-plugin`) |
| 227 | + |
| 228 | +- `all-memo` - Wrap components in memo() (page/layout exempt) |
| 229 | +- `no-use-reducer` - Use Redux instead |
| 230 | +- `no-set-state-prop-drilling` - Avoid passing setState as props |
| 231 | + |
| 232 | +### Monorepo |
| 233 | + |
| 234 | +``` |
| 235 | +packages/redux-storage-middleware/ # Local package |
| 236 | +``` |
| 237 | + |
| 238 | +### 12 Theme System |
| 239 | + |
| 240 | +Light: sunrise, sandstone, mint, sky, lavender, rose |
| 241 | +Dark: midnight, graphite, forest, ocean, plum, rust |
| 242 | + |
| 243 | +### Shortcuts |
| 244 | + |
| 245 | +| Key | Action | |
| 246 | +| --------------- | --------------- | |
| 247 | +| `⌘K` / `Ctrl+K` | Command Palette | |
| 248 | +| `.` | Overflow menu | |
| 249 | +| `Enter` | Open card | |
| 250 | +| `Z` | Undo | |
| 251 | +| `?` | Help | |
| 252 | + |
| 253 | +--- |
| 254 | + |
| 255 | +## Coding Guidelines |
| 256 | + |
| 257 | +**TypeScript/React rules are in `.claude/rules/` - refer to those for detailed patterns.** |
| 258 | + |
| 259 | +Key project-specific rules: |
| 260 | + |
| 261 | +- **Type-only fixes:** Don't alter runtime behavior when fixing TS errors |
| 262 | +- **React 19.2:** Use `useOptimistic`, `useActionState`, `use` API, Form Actions |
| 263 | +- **UI Components:** Reuse from `/components/ui` (shadcn/ui) |
| 264 | +- **Helper Functions:** Extract as pure functions below component definition |
0 commit comments