- Pass episode_id filter to backend API instead of client-side filtering, reducing payload size when an episode is selected - Skip getShot refetch in ShotDetailPanel when initialShot prop is provided - Fix redundant DB query in list_shots: read project.custom_task_statuses directly from the already-fetched project object - Add missing indexes on Task.shot_id, Task.assigned_user_id, Task.deleted_at and Episode.project_id; add add_perf_indexes.py migration script to apply them to existing databases - Center login page layout - Update CLAUDE.md and AGENTS.md with correct venv path Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.0 KiB
AGENTS.md
Guidance for AI coding agents working in this repository.
Project Overview
LinkDesk is a VFX/animation production management system: FastAPI backend + Vue 3 frontend, run as separate dev servers with a Vite proxy bridging them.
Architecture
Backend (backend/) — FastAPI + SQLAlchemy (SQLite by default, set via DATABASE_URL env var).
main.py— entry point; registers all routers and mounts/uploadsstatic dir.database.py— SQLAlchemy engine andget_dbsession dependency.models/— ORM models: project, shot, asset, task, episode, user, notification, activity, api_key.routers/— one file per resource, each prefixed inmain.py.schemas/— Pydantic request/response schemas (separate from ORM models).utils/— shared helpers (file handling, notifications).
Frontend (frontend/src/) — Vue 3 + TypeScript + Pinia + Vue Router + shadcn-vue + TanStack Table.
router/index.ts— routes withrequiresAuth, role (roles: [...]), and admin-only (adminPermission: 'required') guards.stores/— Pinia stores per domain (auth, projects, assets, tasks, episodes, notifications, user, settings, taskStatuses).services/— axios wrappers per resource;api.tsis the base client. All calls use/apiprefix, proxied by Vite tohttp://localhost:8000.components/— domain folders (asset/,shot/,project/,layout/,auth/,episode/,task/) +ui/for shadcn primitives.views/— page-level components; project detail uses nested child routes under/projects/:projectId.composables/— shared composition logic.types/— shared TypeScript interfaces.
Auth: JWT access + refresh tokens in localStorage. api.ts interceptor auto-refreshes on 401. Router guard initializes auth from stored token on first navigation.
Roles: coordinator, director, developer + isAdmin flag. Admins can access any role-gated route.
Commands
Backend
# venv lives at repo root, not inside backend/
cd backend
..\venv\Scripts\activate # Windows PowerShell
uvicorn main:app --reload --port 8000
# or invoke directly: D:\Repo\LinkDesk\.venv\Scripts\uvicorn.exe main:app --reload --port 8000
Frontend
cd frontend
npm install
npm run dev # http://localhost:5173
npm run type-check # vue-tsc --noEmit
npm run build
First-time setup
Copy backend/.env.example to backend/.env and set SECRET_KEY. The database schema is created automatically on first run via Base.metadata.create_all.
Coding conventions
- Backend: follow existing router/schema/model separation. Pydantic schemas live in
schemas/, ORM models inmodels/. Never mix them. - Frontend: services call the API; stores hold state; components consume stores. Don't call
apiClientdirectly from components. - Use
@/alias for all frontend imports (maps tofrontend/src/). - Match existing style exactly — don't refactor adjacent code while fixing something.
- Minimum code that solves the problem. No speculative features or abstractions.