dograh/ui/AGENTS.md
Matt Van Horn dd85c4a1b4
fix: support object and array parameters in custom HTTP tools (#373)
* fix: support object and array parameters in custom HTTP tools

* feat(ui): expose object and array types in the custom tool parameter editor

* fix: error handling and schema generation

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
2026-06-02 11:35:38 +05:30

94 lines
3.7 KiB
Markdown

# UI - Frontend Application
Next.js 15 frontend for the Dograh voice AI platform.
## Project Structure
```
ui/
├── src/
│ ├── app/ # Next.js App Router pages
│ ├── components/ # React components
│ ├── lib/ # Utilities and configurations
│ ├── client/ # Auto-generated API client
│ ├── context/ # React context providers
│ ├── hooks/ # Custom React hooks
│ ├── constants/ # Application constants
│ └── types/ # TypeScript type definitions
├── public/ # Static assets
└── package.json
```
## Where to Find Things
| Looking for... | Go to... |
| ------------------- | ---------------------------------------------------- |
| Pages/routes | `src/app/` - Next.js App Router (file-based routing) |
| Reusable components | `src/components/` - organized by feature |
| Base UI primitives | `src/components/ui/` - shadcn/ui components |
| Workflow builder | `src/components/flow/` - React Flow based |
| API calls | `src/client/` - auto-generated from OpenAPI spec |
| Auth utilities | `src/lib/auth/` |
| Helper functions | `src/lib/utils.ts` |
| Global state | `src/context/` - React context providers |
## Tech Stack
- Next.js 15 with App Router, React 19, TypeScript
- Tailwind CSS with shadcn/ui components
- Zustand for state management
- @xyflow/react for workflow builder
## API Client
The `src/client/` directory is auto-generated from the backend OpenAPI spec. Whenever you add a
new api route in backend, and wish to use it in the UI, generate the client using below command.
```bash
npm run generate-client
```
## Conventions
### File Uploads
Always use a hidden `<input type="file">` with a visible `<Button>` that triggers it via `fileInputRef.current?.click()`. Never use a visible `<Input type="file">` — the native file input styling is inconsistent and confusing. Show the selected filename next to or below the button.
### Authenticated API Calls
Components that make API calls must wait for auth to be ready before fetching. Use `useAuth()` and guard the `useEffect` with `authLoading` and `user`:
```tsx
const { user, loading: authLoading } = useAuth();
const hasFetched = useRef(false);
useEffect(() => {
if (authLoading || !user || hasFetched.current) return;
hasFetched.current = true;
fetchData();
}, [authLoading, user]);
```
The auth interceptor (which attaches the Bearer token) is only registered once auth is fully loaded. Fetching before that sends unauthenticated requests that silently fail.
### API Error Handling
The generated client does **not** throw on HTTP error responses — it resolves to `{ data, error }`. A `try/catch` only catches network failures, so a 4xx/5xx slips through silently if you only check `response.data`. Always check `response.error`:
```tsx
const response = await someApiCall({ ... });
if (response.error) {
setError(detailFromError(response.error, "Failed to save thing"));
return;
}
// ...use response.data
```
Use `detailFromError` from `@/lib/apiError` to turn the error into a string — never render `error.detail` directly. FastAPI returns `detail` as a string for `HTTPException` but as an **array** of `{ msg, loc, ... }` objects for 422 validation errors; passing that array to React (`{error}`) crashes the page with "Objects are not valid as a React child". The helper normalizes both shapes and takes an optional fallback message.
## Development
```bash
npm install
npm run dev # Runs on port 3000
```