From ded35d8c40ade66a9eeef231634833c35e602c7d Mon Sep 17 00:00:00 2001 From: "A.Shakhmatov" Date: Thu, 12 Feb 2026 12:18:20 +0300 Subject: [PATCH] docs: add CLAUDE.md with project architecture and dev commands Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..016dd1e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,66 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Tusk is a PostgreSQL database management GUI built with Tauri 2 (Rust backend) and React (TypeScript frontend). + +## Development Commands + +```bash +npm run tauri dev # Start full app in dev mode (Vite HMR + Rust backend) +npm run dev # Start only the Vite frontend dev server (port 5173) +npm run build # Build frontend (tsc + vite build) +npm run tauri build # Build production desktop executable +npm run lint # ESLint +``` + +Rust backend builds automatically via Tauri when running `npm run tauri dev/build`. To check Rust compilation independently: +```bash +cd src-tauri && cargo check +``` + +## Architecture + +``` +Frontend (React/TS) ──IPC invoke()──> Backend (Rust/Tauri) ──sqlx──> PostgreSQL +``` + +### IPC Communication Pattern + +All frontend-backend communication goes through Tauri's typed IPC. The full pipeline for adding a new backend-exposed feature: + +1. **Rust command** — `#[tauri::command]` async fn in `src-tauri/src/commands/.rs` +2. **Register** — add to `invoke_handler` in `src-tauri/src/lib.rs` +3. **TS wrapper** — typed `invoke()` call in `src/lib/tauri.ts` +4. **React hook** — TanStack React Query hook in `src/hooks/use-.ts` +5. **Types** — shared interfaces in `src/types/index.ts` + +### Backend (src-tauri/src/) + +- **`state.rs`** — `AppState`: holds `RwLock>`, read-only flags, config path. Connections default to read-only. +- **`error.rs`** — `TuskError` enum with `thiserror`, serialized as string for IPC. `TuskResult` type alias. +- **`utils.rs`** — `escape_ident()` for safe SQL identifier quoting. +- **`commands/`** — one module per domain (connections, queries, schema, data, export, management, history, saved_queries). Each function takes `State<'_, AppState>` and returns `TuskResult`. +- **`models/`** — serde-serializable structs matching TypeScript types. + +SQL safety: identifiers use `escape_ident()`, data queries use sqlx parameterized queries. Read-only mode wraps queries in `SET TRANSACTION READ ONLY` + `ROLLBACK`. + +### Frontend (src/) + +- **State**: Zustand store (`stores/app-store.ts`) — connections, active connection/database, tabs, read-only flags, pg version. +- **Data fetching**: TanStack React Query hooks in `hooks/` — one hook per domain, wrapping `src/lib/tauri.ts` functions. +- **UI**: shadcn/ui + Radix primitives, Tailwind CSS 4, dark mode via next-themes. SQL editor uses CodeMirror. +- **Layout**: resizable panels (sidebar + main area with tab bar). + +### Stored Data + +Connections are persisted to `~/.config/tusk/connections.json`. History and saved queries are stored in similar JSON files in the same config directory. + +## Conventions + +- **Frontend files**: Components `PascalCase.tsx`, hooks `use-kebab-case.ts`, one feature per directory under `components/` +- **Path alias**: `@` maps to `./src` +- **Rust errors**: always use `TuskError` variants, never `unwrap()` in commands +- **New PG types**: add conversion case in `pg_value_to_json()` in `commands/queries.rs`