Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
143 changes: 143 additions & 0 deletions .agents/planning/00-index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# UI Framework Migration Planning

## Overview

Planning documents for migrating the Antenna UI from Vite + React Router to a more opinionated framework. Two options are evaluated: **Next.js** and **Remix**.

**Recommendation**: Remix is better aligned with our motivations (reducing boilerplate, prescribed patterns, DRF-like experience).

---

## Document Index

### Context & Motivations

| # | Document | Description |
|---|----------|-------------|
| 01 | [Current State](./01-current-state.md) | Analysis of current UI and API architecture |
| 08 | [**Motivations**](./08-motivations.md) | Why we're considering migration (small team, patterns, maintenance) |
| 09 | [**E2E Testing Strategy**](./09-e2e-testing-strategy.md) | Playwright setup, test generation strategies, analytics-driven prioritization |

### Next.js Assessment

| # | Document | Description |
|---|----------|-------------|
| 02 | [Next.js Benefits](./02-nextjs-benefits.md) | What Next.js offers and can replace |
| 03 | [Required Changes](./03-required-changes.md) | Everything that needs to change for Next.js |
| 04 | [Custom/Bespoke](./04-custom-bespoke.md) | What stays custom (Next.js) |
| 05 | [Migration Steps](./05-migration-steps.md) | Phased implementation plan (Next.js) |
| 06 | [Questions & Risks](./06-questions-risks.md) | Risks, alternatives, benefits (Next.js) |
| 07 | [Testing & Evaluation](./07-testing-evaluation.md) | Testing plan (Next.js) |

### Remix Assessment (Recommended)

| # | Document | Description |
|---|----------|-------------|
| R1 | [Remix Benefits](./remix/01-remix-benefits.md) | What Remix offers - loaders, actions, forms |
| R2 | [Required Changes](./remix/02-required-changes.md) | Everything that needs to change for Remix |
| R3 | [Custom/Bespoke](./remix/03-custom-bespoke.md) | What stays custom (Remix) |
| R4 | [Migration Steps](./remix/04-migration-steps.md) | Phased implementation plan (Remix) |
| R5 | [Questions & Risks](./remix/05-questions-risks.md) | Risks, alternatives, benefits (Remix) |
| R6 | [Testing & Evaluation](./remix/06-testing-evaluation.md) | Testing plan (Remix) |
| R7 | [**AI-Driven Migration**](./remix/07-ai-driven-migration.md) | How Claude Code executes migration in 1-2 hours |

---

## Quick Comparison

### Current Stack
- **Build**: Vite 4.5.3
- **Routing**: React Router v6.8.2
- **State**: React Query + Context
- **Styling**: Tailwind CSS + SCSS
- **Components**: Radix UI + nova-ui-kit

### Option A: Next.js
- **Build**: Next.js 14 (App Router)
- **Routing**: File-based (app/)
- **State**: React Query + Context (keep)
- **Data loading**: Flexible (server components, client)
- **Forms**: Manual (Server Actions basic)

### Option B: Remix (Recommended)
- **Build**: Remix 2.x (Vite-based)
- **Routing**: File-based (routes/)
- **State**: Minimal (loaders handle server state)
- **Data loading**: Prescribed (loaders)
- **Forms**: First-class (`<Form>`, actions)

---

## Comparison Matrix

| Factor | Current | Next.js | Remix |
|--------|---------|---------|-------|
| Boilerplate | High | Medium | **Low** |
| Prescribed Patterns | None | Some | **Many** |
| Form Handling | Manual | Basic | **Built-in** |
| Data Flow Opinions | None | Low | **High** |
| Files to Remove | - | ~10 | **~43** |
| DRF-like Feel | No | Somewhat | **Yes** |
| Learning Curve | - | Medium | Medium |
| Community Size | - | **Largest** | Medium |
| Migration Time | - | 6-8 weeks | 6-7 weeks |

---

## Key Metrics

### Next.js Migration
| Aspect | Value |
|--------|-------|
| Estimated Duration | 6-8 weeks |
| Routes to Migrate | ~25 |
| Files to Change | ~150 |
| Custom Code Preserved | ~85% |
| Boilerplate Reduction | Low |

### Remix Migration
| Aspect | Value |
|--------|-------|
| Estimated Duration | 6-7 weeks |
| Routes to Migrate | ~25 |
| Files to Delete | ~43 (hooks → loaders) |
| Custom Code Preserved | ~85% |
| Boilerplate Reduction | **High** |

Comment on lines +85 to +106
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix markdown formatting: Add blank lines before tables.

The tables at lines 90 and 99 need blank lines before them to comply with markdown best practices (MD058).

📝 Proposed formatting fix
 ### Next.js Migration
+
 | Aspect | Value |
 |--------|-------|
 ### Remix Migration
+
 | Aspect | Value |
 |--------|-------|
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
---
## Key Metrics
### Next.js Migration
| Aspect | Value |
|--------|-------|
| Estimated Duration | 6-8 weeks |
| Routes to Migrate | ~25 |
| Files to Change | ~150 |
| Custom Code Preserved | ~85% |
| Boilerplate Reduction | Low |
### Remix Migration
| Aspect | Value |
|--------|-------|
| Estimated Duration | 6-7 weeks |
| Routes to Migrate | ~25 |
| Files to Delete | ~43 (hooks → loaders) |
| Custom Code Preserved | ~85% |
| Boilerplate Reduction | **High** |
---
## Key Metrics
### Next.js Migration
| Aspect | Value |
|--------|-------|
| Estimated Duration | 6-8 weeks |
| Routes to Migrate | ~25 |
| Files to Change | ~150 |
| Custom Code Preserved | ~85% |
| Boilerplate Reduction | Low |
### Remix Migration
| Aspect | Value |
|--------|-------|
| Estimated Duration | 6-7 weeks |
| Routes to Migrate | ~25 |
| Files to Delete | ~43 (hooks → loaders) |
| Custom Code Preserved | ~85% |
| Boilerplate Reduction | **High** |
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 90-90: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 99-99: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

🤖 Prompt for AI Agents
In @.agents/planning/00-index.md around lines 85 - 106, Add a blank line before
each markdown table under the "### Next.js Migration" and "### Remix Migration"
sections so the tables are separated from the preceding headings/text (fixing
MD058); locate the tables shown in the diff (the pipe rows beginning with "|
Aspect | Value |") and insert one empty line immediately above each table so the
markdown linter accepts them.

---

## Recommendation

**Go with Remix** because:

1. **Loaders replace ~22 data hooks** - prescribed pattern for data fetching
2. **Actions replace ~15 mutation hooks** - prescribed pattern for mutations
3. **URL state is built-in** - no more useFilters, useSort, usePagination
4. **Forms are first-class** - `<Form>` with automatic pending states
5. **More opinionated** - closer to "DRF for frontend" philosophy
6. **Same migration effort** - ~6-7 weeks vs 6-8 weeks for Next.js

### Suggested Approach

1. **POC (1 week)**: Migrate login + projects list + one occurrence page
2. **Evaluate**: Does it reduce boilerplate? Is the pattern clear?
3. **Decide**: Continue or reconsider
4. **Full migration (5-6 weeks)**: If POC successful

---

## Team Context

- **2 developers** + periodic interns + AI agents
- Need **prescribed patterns** for fast onboarding
- Want to **reduce custom code** maintenance burden
- Looking for **DRF-like productivity** on frontend

See [Motivations](./08-motivations.md) for full context.

---

## Created
- **Date**: 2026-02-04
- **Branch**: claude/nextjs-migration-planning-nx9Cd
- **Updated**: 2026-02-04 (added Remix assessment)
209 changes: 209 additions & 0 deletions .agents/planning/01-current-state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# Current State of UI and API

## Overview

The Antenna UI is a React 18 single-page application (SPA) built with Vite, serving as the frontend for the Automated Monitoring of Insects ML Platform. It interfaces with a Django REST Framework backend via a versioned JSON API.

---

## UI Architecture

### Build System
- **Bundler**: Vite 4.5.3
- **Language**: TypeScript 4.4.2 (strict mode)
- **Output**: Static bundle deployed to `./build`
- **Dev Server**: Port 3000 with HMR
- **Proxy**: Dev server proxies `/api` and `/media` to Django backend

### Routing
- **Library**: React Router v6.8.2
- **Pattern**: Client-side SPA routing
- **Structure**: Nested routes with `<Outlet />` for layout composition
- **Modal Pattern**: Detail dialogs controlled via URL params (e.g., `/occurrences/:id?`)

**Route Hierarchy:**
```
/
├── /auth
│ ├── /login
│ ├── /reset-password
│ └── /reset-password-confirm
├── /projects (list)
└── /projects/:projectId
├── /summary
├── /deployments/:id?
├── /sessions/:id?
├── /captures
├── /occurrences/:id?
├── /taxa/:id?
├── /jobs/:id?
├── /collections
├── /exports/:id?
├── /pipelines/:id?
├── /algorithms/:id?
├── /processing-services/:id?
├── /sites, /devices, /general, /team
├── /default-filters, /storage, /processing
├── /terms-of-service
└── /code-of-conduct
```
Comment on lines +25 to +49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language identifiers to fenced code blocks.

markdownlint flags missing languages; specify one (e.g., text) for the route tree block.

🧹 Suggested fix
-```
+```text
 /
 ├── /auth
 │   ├── /login
 │   ├── /reset-password
 │   └── /reset-password-confirm
 ├── /projects (list)
 └── /projects/:projectId
     ├── /summary
     ├── /deployments/:id?
     ├── /sessions/:id?
     ├── /captures
     ├── /occurrences/:id?
     ├── /taxa/:id?
     ├── /jobs/:id?
     ├── /collections
     ├── /exports/:id?
     ├── /pipelines/:id?
     ├── /algorithms/:id?
     ├── /processing-services/:id?
     ├── /sites, /devices, /general, /team
     ├── /default-filters, /storage, /processing
 ├── /terms-of-service
 └── /code-of-conduct
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 25-25: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In @.agents/planning/01-current-state.md around lines 25 - 49, The fenced code
block that contains the route tree in .agents/planning/01-current-state.md is
missing a language identifier, which triggers markdownlint; update the opening
fence from ``` to include a language (e.g., use ```text) so the block becomes a
fenced code block with a language identifier; locate the block showing the route
tree (the tree starting with "/ ├── /auth ...") and replace the opening
backticks accordingly.


### State Management

**Server State**: TanStack React Query v4.29.5
- Automatic caching and background refetching
- Query invalidation on mutations
- DevTools for debugging

**Client State**: React Context API
- `UserContext` - Authentication token and login state
- `UserInfoContext` - Current user profile
- `UserPreferencesContext` - UI preferences (localStorage-backed)
- `BreadcrumbContext` - Navigation breadcrumbs
- `CookieConsentContext` - GDPR compliance

### Data Fetching

**Pattern**: Custom hooks wrapping React Query

```typescript
// List queries
useOccurrences(params?: FetchParams) → { occurrences, total, isLoading }
useJobs(params?: FetchParams) → { jobs, total, isLoading }

// Detail queries
useOccurrenceDetails(id) → { occurrence, isLoading }
useProjectDetails(projectId) → { project, isLoading }

// Mutations
useCreateJob(onSuccess) → { createJob, isLoading, error }
useCreateIdentification(onSuccess) → { createIdentification, isLoading }
```

**HTTP Client**: Axios with auth header injection

**Query Key Pattern**: `[API_ROUTE, params]`

### Component Organization

```
ui/src/
├── components/ # Reusable UI components (filtering, forms, gallery)
├── design-system/ # Custom primitives (34 component directories)
│ ├── components/ # Button, Dialog, Table, etc.
│ └── map/ # Geospatial components
├── pages/ # Route-level components (21 page directories)
├── data-services/ # API integration
│ ├── hooks/ # React Query hooks (22 domain directories)
│ ├── models/ # Client-side model classes
│ └── constants.ts # API routes
└── utils/ # Shared utilities and contexts
```
Comment on lines +89 to +101
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language identifiers to fenced code blocks.

Same markdownlint issue for the directory tree block.

🧹 Suggested fix
-```
+```text
 ui/src/
 ├── components/          # Reusable UI components (filtering, forms, gallery)
 ├── design-system/       # Custom primitives (34 component directories)
 │   ├── components/      # Button, Dialog, Table, etc.
 │   └── map/             # Geospatial components
 ├── pages/               # Route-level components (21 page directories)
 ├── data-services/       # API integration
 │   ├── hooks/           # React Query hooks (22 domain directories)
 │   ├── models/          # Client-side model classes
 │   └── constants.ts     # API routes
 └── utils/               # Shared utilities and contexts
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 89-89: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In @.agents/planning/01-current-state.md around lines 89 - 101, Update the
fenced code block that begins with the directory-tree line "ui/src/" so the
opening fence includes a language identifier (change ``` to ```text); this will
annotate the directory tree block with the "text" language for markdownlint and
rendering.


### Styling
- **Primary**: Tailwind CSS v3.4.14
- **Secondary**: SCSS modules for component-specific styles
- **Design Tokens**: `nova-ui-kit` library for colors and variables
- **Breakpoints**: SM (720px), MD (1024px), LG (1440px)

### Key Dependencies
| Category | Libraries |
|----------|-----------|
| UI Components | Radix UI (7 packages), nova-ui-kit, lucide-react |
| Forms | react-hook-form v7.43.9 |
| Maps | leaflet + react-leaflet |
| Charts | plotly.js + react-plotly.js |
| Utilities | lodash, date-fns, classnames |
| Monitoring | @sentry/react |

Comment on lines +109 to +118
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add blank lines around tables.

markdownlint (MD058) expects blank lines before/after tables for readability.

🧹 Suggested fix
 ### Key Dependencies
+
 | Category | Libraries |
 |----------|-----------|
 | UI Components | Radix UI (7 packages), nova-ui-kit, lucide-react |
 | Forms | react-hook-form v7.43.9 |
 | Maps | leaflet + react-leaflet |
 | Charts | plotly.js + react-plotly.js |
 | Utilities | lodash, date-fns, classnames |
 | Monitoring | `@sentry/react` |
+
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Key Dependencies
| Category | Libraries |
|----------|-----------|
| UI Components | Radix UI (7 packages), nova-ui-kit, lucide-react |
| Forms | react-hook-form v7.43.9 |
| Maps | leaflet + react-leaflet |
| Charts | plotly.js + react-plotly.js |
| Utilities | lodash, date-fns, classnames |
| Monitoring | @sentry/react |
### Key Dependencies
| Category | Libraries |
|----------|-----------|
| UI Components | Radix UI (7 packages), nova-ui-kit, lucide-react |
| Forms | react-hook-form v7.43.9 |
| Maps | leaflet + react-leaflet |
| Charts | plotly.js + react-plotly.js |
| Utilities | lodash, date-fns, classnames |
| Monitoring | `@sentry/react` |
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 110-110: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

🤖 Prompt for AI Agents
In @.agents/planning/01-current-state.md around lines 109 - 118, The table under
the "Key Dependencies" section is missing surrounding blank lines (markdownlint
MD058); update the markdown in .agents/planning/01-current-state.md by inserting
a blank line immediately before the table header row (the line starting with "|
Category | Libraries |") and a blank line immediately after the table's closing
line ("| Monitoring | `@sentry/react` |") so there is an empty line between the
surrounding text/headers and the table.

### Authentication
- **Method**: Token-based (djoser)
- **Storage**: localStorage
- **Header**: `Authorization: Token {token}`
- **Auto-logout**: On 403 responses

---

## API Architecture

### Base Configuration
- **URL**: `/api/v2/`
- **Framework**: Django REST Framework
- **Schema**: OpenAPI via drf-spectacular
- **Docs**: Swagger UI at `/api/v2/docs/`

### Versioning
- Namespace versioning (`/api/v2/`)
- Single version currently deployed

### Authentication Endpoints
```
POST /api/v2/auth/token/login/ # Get token (email + password)
POST /api/v2/auth/token/logout/ # Logout
GET /api/v2/users/me/ # Current user
POST /api/v2/users/reset_password/ # Password reset
```

### REST Patterns
Standard CRUD for all resources:
```
GET /api/v2/{resource}/ # List (paginated)
POST /api/v2/{resource}/ # Create
GET /api/v2/{resource}/{id}/ # Retrieve
PUT /api/v2/{resource}/{id}/ # Update
DELETE /api/v2/{resource}/{id}/ # Delete
```
Comment on lines +140 to +155
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language identifiers to fenced code blocks.

markdownlint flags missing languages for these API examples too.

🧹 Suggested fix
-```
+```http
 POST /api/v2/auth/token/login/     # Get token (email + password)
 POST /api/v2/auth/token/logout/    # Logout
 GET  /api/v2/users/me/             # Current user
 POST /api/v2/users/reset_password/ # Password reset

```diff
-```
+```http
 GET    /api/v2/{resource}/         # List (paginated)
 POST   /api/v2/{resource}/         # Create
 GET    /api/v2/{resource}/{id}/    # Retrieve
 PUT    /api/v2/{resource}/{id}/    # Update
 DELETE /api/v2/{resource}/{id}/    # Delete
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 140-140: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 149-149: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In @.agents/planning/01-current-state.md around lines 140 - 155, The fenced code
blocks containing the API examples (the block with lines like "POST
/api/v2/auth/token/login/     # Get token (email + password)" and the REST
patterns block starting with "GET    /api/v2/{resource}/         # List
(paginated)") are missing language identifiers; add the language tag "http" to
both opening triple-backtick fences so markdownlint stops flagging them and
syntax highlighting is applied.


### Key Resources
| Resource | Endpoint | Custom Actions |
|----------|----------|----------------|
| Projects | `/projects/` | `charts/` |
| Deployments | `/deployments/` | `sync/` |
| Events | `/events/` | `timeline/` |
| Captures | `/captures/` | `star/`, `unstar/` |
| Occurrences | `/occurrences/` | `add/`, `remove/`, `suggest/` |
| Jobs | `/jobs/` | `run/`, `cancel/`, `retry/`, `tasks/`, `result/` |
| Pipelines | `/ml/pipelines/` | `test_process/` |
| Processing Services | `/ml/processing_services/` | `status/`, `register_pipelines/` |

Comment on lines +157 to +168
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add blank lines around tables.

Same MD058 formatting issue for the resources table.

🧹 Suggested fix
 ### Key Resources
+
 | Resource | Endpoint | Custom Actions |
 |----------|----------|----------------|
 | Projects | `/projects/` | `charts/` |
 | Deployments | `/deployments/` | `sync/` |
 | Events | `/events/` | `timeline/` |
 | Captures | `/captures/` | `star/`, `unstar/` |
 | Occurrences | `/occurrences/` | `add/`, `remove/`, `suggest/` |
 | Jobs | `/jobs/` | `run/`, `cancel/`, `retry/`, `tasks/`, `result/` |
 | Pipelines | `/ml/pipelines/` | `test_process/` |
 | Processing Services | `/ml/processing_services/` | `status/`, `register_pipelines/` |
+
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Key Resources
| Resource | Endpoint | Custom Actions |
|----------|----------|----------------|
| Projects | `/projects/` | `charts/` |
| Deployments | `/deployments/` | `sync/` |
| Events | `/events/` | `timeline/` |
| Captures | `/captures/` | `star/`, `unstar/` |
| Occurrences | `/occurrences/` | `add/`, `remove/`, `suggest/` |
| Jobs | `/jobs/` | `run/`, `cancel/`, `retry/`, `tasks/`, `result/` |
| Pipelines | `/ml/pipelines/` | `test_process/` |
| Processing Services | `/ml/processing_services/` | `status/`, `register_pipelines/` |
### Key Resources
| Resource | Endpoint | Custom Actions |
|----------|----------|----------------|
| Projects | `/projects/` | `charts/` |
| Deployments | `/deployments/` | `sync/` |
| Events | `/events/` | `timeline/` |
| Captures | `/captures/` | `star/`, `unstar/` |
| Occurrences | `/occurrences/` | `add/`, `remove/`, `suggest/` |
| Jobs | `/jobs/` | `run/`, `cancel/`, `retry/`, `tasks/`, `result/` |
| Pipelines | `/ml/pipelines/` | `test_process/` |
| Processing Services | `/ml/processing_services/` | `status/`, `register_pipelines/` |
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 158-158: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

🤖 Prompt for AI Agents
In @.agents/planning/01-current-state.md around lines 157 - 168, The Markdown
table under the "### Key Resources" header violates MD058 because there are no
blank lines around it; add a single blank line immediately before the table
start (the line with "| Resource | Endpoint | Custom Actions |") and a single
blank line immediately after the table end (after the last row "| Processing
Services | `/ml/processing_services/` | `status/`, `register_pipelines/` |") so
the block is separated from surrounding text/headers.

### Pagination
- **Type**: Limit-Offset
- **Default Page Size**: 10
- **Response**: `{ count, next, previous, results, user_permissions }`

### Filtering
- Field filtering: `?field=value`
- Ordering: `?ordering=field` or `?ordering=-field`
- Search: `?search=query`
- Custom threshold filters for numeric comparisons

### Nested Resources
```
/api/v2/projects/{project_id}/members/
```
Comment on lines +181 to +183
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language identifiers to fenced code blocks.

Same markdownlint issue for the nested resource example.

🧹 Suggested fix
-```
+```http
 /api/v2/projects/{project_id}/members/
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.20.0)</summary>

[warning] 181-181: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In @.agents/planning/01-current-state.md around lines 181 - 183, Add a language
identifier to the fenced code block containing the API path
"/api/v2/projects/{project_id}/members/" by changing the opening triple-backtick
from tohttp so the block becomes a proper HTTP code block; locate the
fenced block around the string "/api/v2/projects/{project_id}/members/" and add
the "http" tag to the opening fence.


</details>

<!-- fingerprinting:phantom:triton:eagle -->

<!-- This is an auto-generated comment by CodeRabbit -->


---

## Current Pain Points

### Development Experience
1. **No SSR**: Initial page load shows blank screen, then hydrates
2. **No Static Generation**: All pages require client-side data fetching
3. **Manual Route Management**: Route constants must match router config
4. **No Built-in API Routes**: Can't add BFF (Backend for Frontend) endpoints
5. **Environment Config**: Manual Vite environment variable setup

### Performance
1. **Client-side Rendering Only**: No server-side rendering for SEO or performance
2. **Large Bundle**: Single bundle for entire app (no automatic code splitting by route)
3. **Image Optimization**: Manual image handling, no built-in optimization

### SEO/Accessibility
1. **Dynamic Titles**: Managed via react-helmet-async instead of native
2. **No Metadata API**: Must manually manage Open Graph tags
3. **Crawler Issues**: SPA content not visible to crawlers without JS

### Architecture
1. **Proxy Dependency**: Development requires Vite proxy to Django
2. **No Edge/Middleware**: Can't intercept requests at edge
3. **Manual Caching**: No built-in data caching beyond React Query
Comment on lines +187 to +191
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace placeholder pain-point text with finalized content.

Line 189 is a TODO-style placeholder; leaving it in merged planning docs reduces credibility and clarity.

📝 Suggested fix (template)
-needs rewriting - pain points are about where to put X, and relying more on external opensource community rather than writing custom aspects.
-2. **No Edge/Middleware**: Can't intercept requests at edge
-3. **Manual Caching**: No built-in data caching beyond React Query
+1. **[Pain point title]**: [Concise description].
+2. **No Edge/Middleware**: Can't intercept requests at edge.
+3. **Manual Caching**: No built-in data caching beyond React Query.
🤖 Prompt for AI Agents
In @.agents/planning/01-current-state.md around lines 187 - 191, Replace the
TODO placeholder text "needs rewriting - pain points are about where to put X,
and relying more on external opensource community rather than writing custom
aspects." under the "## Current Pain Points" section with a finalized,
professional bullet list describing concrete issues: 1) ambiguity about where to
place shared concerns/features (refer to "where to put X"), 2) over-reliance on
external open-source solutions instead of tailored internal implementations, 3)
lack of Edge/Middleware to intercept and manage requests, and 4) manual caching
limitations (only using React Query) and the impact on performance and developer
ergonomics; remove the placeholder line entirely and ensure the bullets replace
it verbatim in that section.

Loading