TeamIDE-methodology/templates/TauriStarter/CLAUDE.md

538 lines
18 KiB
Markdown

# Project Guidelines
## Protecting This File
**IMPORTANT**: This file (CLAUDE.md) can be lost during branch operations!
Git doesn't protect untracked/ignored files during `git checkout` or branch switches. Before major git operations:
```bash
cp CLAUDE.md CLAUDE.md.backup
```
## Project Structure
This project follows a standardized structure for Tauri desktop apps.
```
ProjectRoot/
├── CLAUDE.md # AI assistant guidelines
├── README.md # Project documentation
├── build_spec.md # Full project specification
├── build_plan.md # Phased task checklist
├── .gitignore
├── docs/ # Technical documentation
│ ├── README.md # Docs index with table of contents
│ ├── getting-started.md
│ ├── architecture.md
│ ├── development.md
│ ├── deployment.md
│ └── feature-*.md # Feature docs (added per phase)
└── app/ # ALL project code lives here
├── build.sh # Build script
├── package.json
├── vite.config.ts
├── tsconfig.json
├── index.html
├── src/
│ ├── main.ts
│ ├── App.vue
│ ├── boot/
│ │ └── console-logger.ts
│ ├── components/
│ ├── composables/
│ ├── css/
│ ├── layouts/
│ ├── pages/
│ ├── router/
│ ├── stores/
│ ├── services/
│ └── types/
└── src-tauri/
├── Cargo.toml
├── tauri.conf.json
├── icons/
└── src/
└── main.rs
```
## TeamIDE Project Management
If this project was scaffolded from Ideation, `.teamide/` PM files (plans, tasks, project.yml) should already exist — generated from `build_plan.md` during scaffolding. See the Ideation workspace's `claude.md` for the PM generation workflow and format details.
## Terminology
- **"build spec"** or **"spec"** refers to `build_spec.md` - the full project description
- **"build plan"** or **"plan"** refers to `build_plan.md` - the phased task checklist
## Onboarding Questions (Ask at Project Start)
At the start of every new project conversation, gather these details before writing any code:
1. **Brand colors & fonts** - Primary, secondary, accent colors. Typography preferences. Any existing brand guidelines or color palette?
2. **App personality & tone** - Formal or casual? Dark or light default theme? Dense or spacious layout? Any design inspiration or reference apps?
3. **Target platform** - Desktop-first, mobile-first, or responsive? Specific OS targets (macOS, Windows, Linux)? Minimum screen sizes?
4. **Auth requirements** - Login method (email/password, OAuth, magic link)? User roles and permissions? Public or private app?
Don't assume defaults for any of these. Ask, get answers, then document them in the Project-Specific Configuration section at the bottom of this file.
## Tech Stack
- **Frontend**: Quasar Framework (Vue 3) + Vite
- **Desktop**: Tauri (Rust) - Cross-platform builds (macOS, Windows, Linux)
- **State**: Pinia
- **Routing**: Vue Router
- **Backend** (optional): Nhost (self-hosted or cloud)
- PostgreSQL - Database
- Hasura - GraphQL API
- Auth - Authentication service
- Storage - File storage
- Functions - Serverless functions (Node.js)
## Testing Changes (CRITICAL)
**After every code editing session, you MUST rebuild the app so the user can test your changes.**
```bash
cd app
./build.sh -dev -open
```
### Why This Matters
- This uses a **build-and-run** approach, not hot reload
- Your code changes are NOT visible until you rebuild
- Always rebuild before asking the user to test
- If the user reports issues, check the logs first: `./build.sh logs`
## Build Script
**Always use `build.sh` for building the app.** This ensures consistent builds and logging for collaborative debugging.
```bash
cd app
./build.sh -dev -open # Build dev and open app
./build.sh -prod # Build prod to build/prod/
./build.sh -install # Build prod and open Finder for drag-to-Applications
./build.sh logs # View latest console output (last 100 lines)
./build.sh clean # Clean build artifacts (preserves logs)
./build.sh clean-logs # Remove all logs
```
### Commands
| Command | Description |
|---------|-------------|
| `-dev` | Development build. Bundle ID: `com.[app].dev` |
| `-prod` | Production build. Builds to `build/prod/`. |
| `-install` | Build prod and open Finder for drag-to-Applications. |
| `-open` | Open the app after building (use with `-dev` or `-prod`) |
| `-secure` | Build without automation (no HTTP server on port 9876) |
| `logs` | Show last 100 lines of console output |
| `clean` | Remove build artifacts (preserves logs) |
| `clean-logs` | Remove all log files |
### Why Build-and-Run (No Hot Reload)
This project uses a **build-and-run** approach instead of hot reload:
| Aspect | Hot Reload | Build-and-Run |
|--------|------------|---------------|
| Speed | Instant updates | Full rebuild required |
| Dev/Prod parity | Different environments | Identical to production |
| Debugging | Dev-only issues possible | What you test = what ships |
| Logging | Console only | Full logs to files |
The tradeoff is slower iteration, but you always test exactly what will ship.
### What the Build Does
1. **Build with Tauri** - `npx tauri build` does all of the following:
- Build frontend (`npm run build` → `dist/`)
- Build Rust binary with embedded frontend
- Create .app bundle in `src-tauri/target/release/bundle/macos/`
2. **Copy to build folder** - Copies bundle to `build/dev/` or `build/prod/`
3. **Update Info.plist** - Sets correct bundle ID for dev/prod
4. **Install (prod only)** - Copies to `~/Applications`
**Important**: Using `npx tauri build` ensures the frontend is properly embedded in the binary. Manual `cargo build --release` does NOT embed the frontend.
### Build Output
Builds are organized in separate folders:
```
app/build/
├── dev/
│ └── AppName.app # Dev build (bundle ID: .dev)
├── prod/
│ └── AppName.app # Prod build
├── logs/
│ ├── build_dev_*.log # Build output logs
│ └── build_latest.log # Symlink to latest
└── console/
├── console_*.log # App runtime console output
└── console_latest.log # Symlink to latest
```
Dev and prod have different bundle IDs, so both can run simultaneously.
### Logging
All build output and app console output is logged:
- **Build logs**: `build/logs/build_latest.log` - compilation output, errors
- **Console logs**: `build/console/console_latest.log` - runtime `console.log()`, errors
When debugging, run `./build.sh logs` to see the latest console output.
### Console Logging (Already Configured)
This template includes console logging out of the box. Frontend `console.log()` calls are forwarded to Rust and captured in log files.
**How it works:**
```
console.log() → console-logger.ts → invoke('log_to_stdout') → Rust println!() → stdout → build.sh logs
```
## Automation Plugin (Already Configured)
This template includes an automation HTTP server for external testing and AI-assisted development.
**How it works:**
```
External Tool (curl) → HTTP Server (port 9876) → Rust → JavaScript → DOM
```
### Automation API
When the app is running, these endpoints are available:
```bash
# Health check
curl http://localhost:9876/automation/health
# Execute a command
curl -X POST http://localhost:9876/automation/execute \
-H "Content-Type: application/json" \
-d '{"command": "click", "args": {"selector": "#my-button"}}'
# Take a screenshot
curl http://localhost:9876/automation/screenshot --output screenshot.png
```
### Available Commands
| Command | Args | Description |
|---------|------|-------------|
| `navigate` | `{path}` | Navigate to route |
| `click` | `{selector}` | Click element |
| `type` | `{selector, text}` | Type into input |
| `getText` | `{selector}` | Get element text |
| `getValue` | `{selector}` | Get input value |
| `exists` | `{selector}` | Check if element exists |
| `waitFor` | `{selector, timeout?}` | Wait for element |
| `getUrl` | `{}` | Get current URL |
| `screenshot` | - | Capture page (via endpoint) |
Full command list in `src/automation/README.md`.
### Disabling Automation
**Option 1: Build flag (recommended)**
Use the `-secure` flag to build without automation:
```bash
./build.sh -prod -secure # Production build without automation
```
**Option 2: Permanently disable**
Remove `automation` from the default features in `Cargo.toml`:
```toml
[features]
default = ["custom-protocol"] # Remove "automation"
```
### When to Clean
Run `./build.sh clean` when:
- Switching between major dependency versions
- Build errors reference stale/cached files
- Rust compilation issues after Tauri config changes
- Before creating a fresh production build
## Node.js Environment
**Node.js version**: Always match Debian stable (currently Node.js 18.x for Debian 12 Bookworm)
Check current Debian stable Node version: https://packages.debian.org/stable/nodejs
**Package manager**: Use npm. Commit lock files for reproducible builds.
Rules:
- Always commit `package-lock.json` - required for deterministic installs
- Never ignore lock files (`package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`)
- Use `npm install` to install dependencies
- Use `npm run <script>` to run package scripts
## Communication Rules
**Always explain before acting.** Before running any command, SSH, database query, or making changes:
- Give a short, concise explanation of WHAT you're about to do and WHY
- Wait for approval on anything that modifies production data or server state
- Don't chain multiple server commands without explaining each step
## Database Rules (If Using Nhost Backend)
**NEVER make direct database changes via Hasura MCP or Hasura Console.**
All database changes MUST be done through migrations so they:
1. Are tracked in version control
2. Persist across restarts (`nhost down` / `nhost up`)
3. Can be reproduced in production
### Hasura MCP Usage
- **READ-ONLY**: Use Hasura MCP only to inspect schema, check what tables exist, verify tracking status
- **NO MUTATIONS**: Never use it to create tables, add columns, track tables, or modify permissions
- **MIGRATIONS ONLY**: All schema changes go in `app/nhost/migrations/default/`
- **METADATA ONLY**: All Hasura config (tracking, permissions, relationships) go in `app/nhost/metadata/`
### How to Make Database Changes
1. Write SQL migration in `app/nhost/migrations/default/<N>_<name>/up.sql` (N = next version number)
2. Write rollback in `app/nhost/migrations/default/<N>_<name>/down.sql`
3. Add Hasura metadata YAML in `app/nhost/metadata/databases/default/tables/`
4. Restart dev environment to apply migrations
5. Commit and push
### Hasura Role Permissions (CRITICAL)
**NEVER define permissions for the `admin` role in Hasura metadata.**
Hasura reserves `admin` as a special role with **full unrestricted access**. Defining explicit permissions for `admin` causes metadata errors.
Define permissions only for `user`, `public`, and custom roles.
## Development Approach
**Integrate-as-you-go** - Connect real backend services as you build. Don't build elaborate mock systems.
## Persistence Rules (CRITICAL)
**All persistence requires an explicit user action. No exceptions.**
Never auto-save. Never sync state in the background. Never write to the database on a timer or watcher. Every single write to a database, file, or storage must be traceable to a deliberate user action.
### The Rule
Data is only persisted when the user deliberately triggers it — clicking "Save", submitting a form, confirming a dialog, toggling a setting, etc.
### WRONG — Never Do This
- Auto-saving form fields as the user types
- Syncing component state to the database on mount/unmount
- Watchers that write to storage when reactive data changes
- Debounced save on input change
- Persisting UI state automatically (sidebar position, tab selection, scroll position)
- Writing to the database during navigation or route changes
- Background sync intervals or polling that writes data
### RIGHT — Always Do This
- User clicks "Save" → write to database
- User submits a form → persist the data
- User explicitly toggles a setting → save that setting
- User clicks "Delete" → confirm, then remove from database
- User drags an item to reorder → save on drop (explicit action)
### Why This Matters
Auto-save creates unpredictable behavior, race conditions, and persists data the user didn't intend to save. Every write should be traceable to a conscious user decision. If you can't point to the button or action the user took to trigger the save, it shouldn't be saving.
### Implementation Pattern
```
User Action → Service Call → Database Write → Confirm Success to User
```
1. User triggers action (click, submit, confirm)
2. Call the appropriate service/API
3. Write to database
4. Show success feedback (Quasar Notify or UI update)
5. If it fails, show an error — don't silently retry
## Code Quality
### TypeScript
- Use TypeScript strict mode
- Define interfaces/types for all data structures in `src/types/`
- No `any` types unless absolutely unavoidable — use `unknown` and narrow instead
- Type all function parameters and return values
### Vue / Quasar Conventions
- Use Composition API with `<script setup lang="ts">` for all components
- One component per file, named in PascalCase (e.g., `UserProfile.vue`)
- Composables go in `src/composables/`, prefixed with `use` (e.g., `useAuth.ts`)
- Keep components focused — if it's doing too much, split it
- Props down, events up — don't mutate props, emit events to parent
### Naming
- **Files**: PascalCase for components (`UserCard.vue`), camelCase for everything else (`userService.ts`)
- **Variables/functions**: camelCase
- **Constants**: UPPER_SNAKE_CASE for true constants, camelCase for derived/computed values
- **Types/Interfaces**: PascalCase, no `I` prefix (use `User` not `IUser`)
- **CSS classes**: kebab-case
### General
- No magic numbers or strings — use named constants
- Keep functions short and single-purpose
- Colocate related code — don't scatter logic across files unnecessarily
- Delete dead code, don't comment it out
## Error Handling
### User-Facing Errors
- Always show human-readable messages — never expose raw error objects, stack traces, or technical details to the user
- Use Quasar's `Notify` plugin for transient feedback (success, warning, error)
- Use inline error messages for form validation
### Technical Errors
- Log technical details to console for debugging (`console.error` with context)
- Include the operation that failed and relevant IDs in log messages
- Never swallow errors silently — if you catch it, either handle it or log it
### Pattern
```typescript
try {
const result = await userService.updateProfile(data)
Notify.create({ type: 'positive', message: 'Profile updated' })
} catch (error) {
console.error('Failed to update profile:', error)
Notify.create({ type: 'negative', message: 'Could not update profile. Try again.' })
}
```
### Where to Catch
- Catch at **service boundaries** (API calls, database operations), not deep in utility functions
- Let errors propagate up to where they can be meaningfully handled
- Don't wrap every line in try/catch — catch at the level where you can show the user feedback
## Documentation
**Every phase ends with documentation.** After completing a feature or phase:
1. **Create feature docs** - Copy `docs/TEMPLATE-feature.md` to `docs/feature-[name].md`
2. **Update the index** - Add links to `docs/README.md` table of contents
3. **Update core docs** - Keep `architecture.md`, `development.md` current
### Docs Structure
| File | Purpose |
|------|---------|
| `docs/README.md` | Index with table of contents |
| `docs/getting-started.md` | Installation & setup |
| `docs/architecture.md` | Tech stack & design decisions |
| `docs/development.md` | Development workflow |
| `docs/deployment.md` | Build & deployment |
| `docs/feature-*.md` | Feature-specific documentation |
### Naming Convention
- `feature-[name].md` - Feature docs (e.g., `feature-authentication.md`)
- `component-[name].md` - Component docs
- `integration-[name].md` - Integration docs
- `guide-[topic].md` - How-to guides
## Commit Rules
- **Never mention Claude, AI, or "Generated with Claude Code" in commits**
- All commits are authored by the developer - no co-author tags
- Write commit messages in first person as the developer
- Keep commit messages concise and descriptive of the changes
## Branch Strategy
- **main** - Production branch
- **test** - Staging/testing branch
**Workflow:**
1. Develop and test locally
2. Push to `test` branch for staging
3. Verify on staging
4. Merge `test` → `main` for production
## Customization Checklist
When using this template for a new project:
1. Update `app/src-tauri/tauri.conf.json`:
- `productName`
- `identifier` (e.g., `com.yourapp.app`)
- `title`
2. Update `app/package.json`:
- `name`
- `description`
3. Update `app/build.sh`:
- `APP_NAME`
- `BINARY_NAME` (must match productName)
- `BUNDLE_ID_DEV`
- `BUNDLE_ID_PROD`
4. Replace placeholder icons in `app/src-tauri/icons/`
5. Update documentation:
- Replace `[Project Name]` in all `docs/*.md` files
- Update `docs/architecture.md` with project-specific tech decisions
- Update `docs/getting-started.md` with project-specific setup
6. Add your pages, components, and stores
7. Add Tauri commands to `src-tauri/src/main.rs`
---
# Project-Specific Configuration
<!-- Everything below this line is customized per project -->
## Project Name
[PROJECT_NAME]
## Description
[Brief description from build_spec.md]
## Backend (If Applicable)
| Service | URL |
|---------|-----|
| GraphQL | |
| Auth | |
| Storage | |
## Database Schema (If Applicable)
[Tables and relationships]
## TeamIDE Hosting (If Applicable)
- **Workspace ID**: `your-workspace-id-here`
- Use `teamide_deploy` to deploy changes
- Use `teamide_set_env_vars` to configure environment variables
- Use `teamide_get_logs` to check build status