Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions .claude/context/backend-development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Backend Development Context

**When to load:** Working on Go backend API, handlers, or Kubernetes integration

## Quick Reference

- **Language:** Go 1.21+
- **Framework:** Gin (HTTP router)
- **K8s Client:** client-go + dynamic client
- **Primary Files:** `components/backend/handlers/*.go`, `components/backend/types/*.go`

## Critical Rules

### Authentication & Authorization

**ALWAYS use user-scoped clients for API operations:**

```go
reqK8s, reqDyn := GetK8sClientsForRequest(c)
if reqK8s == nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or missing token"})
c.Abort()
return
}
```

**FORBIDDEN:** Using backend service account (`DynamicClient`, `K8sClient`) for user-initiated operations

**Backend service account ONLY for:**

- Writing CRs after validation (handlers/sessions.go:417)
- Minting tokens/secrets for runners (handlers/sessions.go:449)
- Cross-namespace operations backend is authorized for

### Token Security

**NEVER log tokens:**

```go
// ❌ BAD
log.Printf("Token: %s", token)

// ✅ GOOD
log.Printf("Processing request with token (len=%d)", len(token))
```

**Token redaction in logs:** See `server/server.go:22-34` for custom formatter

### Error Handling

**Pattern for handler errors:**

```go
// Resource not found
if errors.IsNotFound(err) {
c.JSON(http.StatusNotFound, gin.H{"error": "Session not found"})
return
}

// Generic error
if err != nil {
log.Printf("Failed to create session %s in project %s: %v", name, project, err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create session"})
return
}
```

### Type-Safe Unstructured Access

**FORBIDDEN:** Direct type assertions

```go
// ❌ BAD - will panic if type is wrong
spec := obj.Object["spec"].(map[string]interface{})
```

**REQUIRED:** Use unstructured helpers

```go
// ✅ GOOD
spec, found, err := unstructured.NestedMap(obj.Object, "spec")
if !found || err != nil {
return fmt.Errorf("spec not found")
}
```

## Common Tasks

### Adding a New API Endpoint

1. **Define route:** `routes.go` with middleware chain
2. **Create handler:** `handlers/[resource].go`
3. **Validate project context:** Use `ValidateProjectContext()` middleware
4. **Get user clients:** `GetK8sClientsForRequest(c)`
5. **Perform operation:** Use `reqDyn` for K8s resources
6. **Return response:** Structured JSON with appropriate status code

### Adding a New Custom Resource Field

1. **Update CRD:** `components/manifests/base/[resource]-crd.yaml`
2. **Update types:** `components/backend/types/[resource].go`
3. **Update handlers:** Extract/validate new field in handlers
4. **Update operator:** Handle new field in reconciliation
5. **Test:** Create sample CR with new field

## Pre-Commit Checklist

- [ ] All user operations use `GetK8sClientsForRequest`
- [ ] No tokens in logs
- [ ] Errors logged with context
- [ ] Type-safe unstructured access
- [ ] `gofmt -w .` applied
- [ ] `go vet ./...` passes
- [ ] `golangci-lint run` passes

## Key Files

- `handlers/sessions.go` - AgenticSession lifecycle (3906 lines)
- `handlers/middleware.go` - Auth, RBAC validation
- `handlers/helpers.go` - Utility functions (StringPtr, BoolPtr)
- `types/session.go` - Type definitions
- `server/server.go` - Server setup, token redaction

## Recent Issues & Learnings

- **2024-11-15:** Fixed token leak in logs - never log raw tokens
- **2024-11-10:** Multi-repo support added - `mainRepoIndex` specifies working directory
- **2024-10-20:** Added RBAC validation middleware - always check permissions
183 changes: 183 additions & 0 deletions .claude/context/frontend-development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Frontend Development Context

**When to load:** Working on NextJS application, UI components, or React Query integration

## Quick Reference

- **Framework:** Next.js 14 (App Router)
- **UI Library:** Shadcn UI (built on Radix UI primitives)
- **Styling:** Tailwind CSS
- **Data Fetching:** TanStack React Query
- **Primary Directory:** `components/frontend/src/`

## Critical Rules (Zero Tolerance)

### 1. Zero `any` Types

**FORBIDDEN:**

```typescript
// ❌ BAD
function processData(data: any) { ... }
```

**REQUIRED:**

```typescript
// ✅ GOOD - use proper types
function processData(data: AgenticSession) { ... }

// ✅ GOOD - use unknown if type truly unknown
function processData(data: unknown) {
if (isAgenticSession(data)) { ... }
}
```

### 2. Shadcn UI Components Only

**FORBIDDEN:** Creating custom UI components from scratch for buttons, inputs, dialogs, etc.

**REQUIRED:** Use `@/components/ui/*` components

```typescript
// ❌ BAD
<button className="px-4 py-2 bg-blue-500">Click</button>

// ✅ GOOD
import { Button } from "@/components/ui/button"
<Button>Click</Button>
```

**Available Shadcn components:** button, card, dialog, form, input, select, table, toast, etc.
**Check:** `components/frontend/src/components/ui/` for full list

### 3. React Query for ALL Data Operations

**FORBIDDEN:** Manual `fetch()` calls in components

**REQUIRED:** Use hooks from `@/services/queries/*`

```typescript
// ❌ BAD
const [sessions, setSessions] = useState([])
useEffect(() => {
fetch('/api/sessions').then(r => r.json()).then(setSessions)
}, [])

// ✅ GOOD
import { useSessions } from "@/services/queries/sessions"
const { data: sessions, isLoading } = useSessions(projectName)
```

### 4. Use `type` Over `interface`

**REQUIRED:** Always prefer `type` for type definitions

```typescript
// ❌ AVOID
interface User { name: string }

// ✅ PREFERRED
type User = { name: string }
```

### 5. Colocate Single-Use Components

**FORBIDDEN:** Creating components in shared directories if only used once

**REQUIRED:** Keep page-specific components with their pages

```
app/
projects/
[projectName]/
sessions/
_components/ # Components only used in sessions pages
session-card.tsx
page.tsx # Uses session-card
```

## Common Patterns

### Page Structure

```typescript
// app/projects/[projectName]/sessions/page.tsx
import { useSessions } from "@/services/queries/sessions"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"

export default function SessionsPage({
params,
}: {
params: { projectName: string }
}) {
const { data: sessions, isLoading, error } = useSessions(params.projectName)

if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
if (!sessions?.length) return <div>No sessions found</div>

return (
<div>
{sessions.map(session => (
<Card key={session.metadata.name}>
{/* ... */}
</Card>
))}
</div>
)
}
```

### React Query Hook Pattern

```typescript
// services/queries/sessions.ts
import { useQuery, useMutation } from "@tanstack/react-query"
import { sessionApi } from "@/services/api/sessions"

export function useSessions(projectName: string) {
return useQuery({
queryKey: ["sessions", projectName],
queryFn: () => sessionApi.list(projectName),
})
}

export function useCreateSession(projectName: string) {
return useMutation({
mutationFn: (data: CreateSessionRequest) =>
sessionApi.create(projectName, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["sessions", projectName] })
},
})
}
```

## Pre-Commit Checklist

- [ ] Zero `any` types (or justified with eslint-disable)
- [ ] All UI uses Shadcn components
- [ ] All data operations use React Query
- [ ] Components under 200 lines
- [ ] Single-use components colocated
- [ ] All buttons have loading states
- [ ] All lists have empty states
- [ ] All nested pages have breadcrumbs
- [ ] `npm run build` passes with 0 errors, 0 warnings
- [ ] All types use `type` instead of `interface`

## Key Files

- `components/frontend/DESIGN_GUIDELINES.md` - Comprehensive patterns
- `components/frontend/COMPONENT_PATTERNS.md` - Architecture patterns
- `src/components/ui/` - Shadcn UI components
- `src/services/queries/` - React Query hooks
- `src/services/api/` - API client layer

## Recent Issues & Learnings

- **2024-11-18:** Migrated all data fetching to React Query - no more manual fetch calls
- **2024-11-15:** Enforced Shadcn UI only - removed custom button components
- **2024-11-10:** Added breadcrumb pattern for nested pages
Loading
Loading