|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides architectural guidance and coding standards for AI agents |
| 4 | +interacting with this repository." |
| 5 | + |
| 6 | +## Project Overview |
| 7 | + |
| 8 | +This is the Unraid API monorepo containing multiple packages that provide API functionality for Unraid servers. It uses pnpm workspaces with the following structure: |
| 9 | + |
| 10 | +- `/api` - Core NestJS API server with GraphQL |
| 11 | +- `/web` - Vue 3 frontend application |
| 12 | +- `/unraid-ui` - Vue 3 component library |
| 13 | +- `/plugin` - Unraid plugin package (.plg) |
| 14 | +- `/packages` - Shared packages and API plugins |
| 15 | + |
| 16 | +## Essential Commands |
| 17 | + |
| 18 | +### Development |
| 19 | + |
| 20 | +```bash |
| 21 | +pnpm install # Install all dependencies |
| 22 | +pnpm dev # Run all dev servers concurrently |
| 23 | +pnpm build # Build all packages |
| 24 | +pnpm build:watch # Watch mode with local plugin build |
| 25 | +``` |
| 26 | + |
| 27 | +### Testing & Code Quality |
| 28 | + |
| 29 | +```bash |
| 30 | +pnpm test # Run all tests |
| 31 | +pnpm lint # Run linting |
| 32 | +pnpm lint:fix # Fix linting issues |
| 33 | +pnpm type-check # TypeScript type checking |
| 34 | +``` |
| 35 | + |
| 36 | +### API Development |
| 37 | + |
| 38 | +```bash |
| 39 | +cd api && pnpm dev # Run API server (http://localhost:3001) |
| 40 | +cd api && pnpm test:watch # Run tests in watch mode |
| 41 | +cd api && pnpm codegen # Generate GraphQL types |
| 42 | +``` |
| 43 | + |
| 44 | +### Deployment |
| 45 | + |
| 46 | +```bash |
| 47 | +pnpm unraid:deploy <SERVER_IP> # Deploy all to Unraid server |
| 48 | +``` |
| 49 | + |
| 50 | +### Developer Tools |
| 51 | + |
| 52 | +```bash |
| 53 | +unraid-api developer # Interactive prompt for tools |
| 54 | +unraid-api developer --sandbox true # Enable GraphQL sandbox |
| 55 | +unraid-api developer --sandbox false # Disable GraphQL sandbox |
| 56 | +unraid-api developer --enable-modal # Enable modal testing tool |
| 57 | +unraid-api developer --disable-modal # Disable modal testing tool |
| 58 | +``` |
| 59 | + |
| 60 | +## Architecture Notes |
| 61 | + |
| 62 | +### API Structure (NestJS) |
| 63 | + |
| 64 | +- Modules: `auth`, `config`, `plugins`, `emhttp`, `monitoring` |
| 65 | +- GraphQL API with Apollo Server at `/graphql` |
| 66 | +- Redux store for state management in `src/store/` |
| 67 | +- Plugin system for extending functionality |
| 68 | +- Entry points: `src/index.ts` (server), `src/cli.ts` (CLI) |
| 69 | + |
| 70 | +### Key Patterns |
| 71 | + |
| 72 | +- TypeScript imports use `.js` extensions (ESM compatibility) |
| 73 | +- NestJS dependency injection with decorators |
| 74 | +- GraphQL schema-first approach with code generation |
| 75 | +- API plugins follow specific structure (see `api/docs/developer/api-plugins.md`) |
| 76 | + |
| 77 | +### Authentication |
| 78 | + |
| 79 | +- API key authentication via headers |
| 80 | +- Cookie-based session management |
| 81 | +- Keys stored in `/boot/config/plugins/unraid-api/` |
| 82 | + |
| 83 | +### Development Workflow |
| 84 | + |
| 85 | +1. Work Intent required before starting development |
| 86 | +2. Fork from `main` branch |
| 87 | +3. Reference Work Intent in PR |
| 88 | +4. No direct pushes to main |
| 89 | + |
| 90 | +### Debug Mode |
| 91 | + |
| 92 | +```bash |
| 93 | +LOG_LEVEL=debug unraid-api start --debug |
| 94 | +``` |
| 95 | + |
| 96 | +Enables GraphQL playground at `http://tower.local/graphql` |
| 97 | + |
| 98 | +## Coding Guidelines |
| 99 | + |
| 100 | +### General Rules |
| 101 | + |
| 102 | +- Never add comments unless they are needed for clarity of function |
| 103 | +- Never add comments for obvious things, and avoid commenting when starting and ending code blocks |
| 104 | +- Be CONCISE, keep replies shorter than a paragraph if at all possible |
| 105 | + |
| 106 | +### API Development Rules (`api/**/*`) |
| 107 | + |
| 108 | +- Use pnpm ONLY for package management |
| 109 | +- Always run scripts from api/package.json unless requested |
| 110 | +- Prefer adding new files to the NestJS repo located at `api/src/unraid-api/` instead of the legacy code |
| 111 | +- Test suite is VITEST, do not use jest |
| 112 | +- Run tests with: `pnpm --filter ./api test` |
| 113 | +- Prefer to not mock simple dependencies |
| 114 | + |
| 115 | +### Web Development Rules (`web/**/*`) |
| 116 | + |
| 117 | +- Always run `pnpm codegen` for GraphQL code generation in the web directory |
| 118 | +- GraphQL queries must be placed in `.query.ts` files |
| 119 | +- GraphQL mutations must be placed in `.mutation.ts` files |
| 120 | +- All GraphQL under `web/` must follow this naming convention |
| 121 | + |
| 122 | +### Testing Guidelines |
| 123 | + |
| 124 | +#### General Testing Best Practices |
| 125 | + |
| 126 | +- **Error Testing:** Use `.rejects.toThrow()` without arguments to test that functions throw errors. Don't test exact error message strings unless the message format is specifically what you're testing |
| 127 | +- **Focus on Behavior:** Test what the code does, not implementation details like exact error message wording |
| 128 | +- **Avoid Brittleness:** Don't write tests that break when minor changes are made to error messages, log formats, or other non-essential details |
| 129 | +- **Use Mocks Correctly**: Mocks should be used as nouns, not verbs. |
| 130 | + |
| 131 | +#### Vue Component Testing |
| 132 | +- Use pnpm when running terminal commands and stay within the web directory |
| 133 | +- Tests are located under `web/__test__`, run with `pnpm test` |
| 134 | +- Use `mount` from Vue Test Utils for component testing |
| 135 | +- Stub complex child components that aren't the focus of the test |
| 136 | +- Mock external dependencies and services |
| 137 | +- Test component behavior and output, not implementation details |
| 138 | +- Use `createTestingPinia()` for mocking stores in components |
| 139 | +- Find elements with semantic queries like `find('button')` rather than data-test IDs |
| 140 | +- Use `await nextTick()` for DOM updates |
| 141 | +- Always await async operations before making assertions |
| 142 | + |
| 143 | +#### Store Testing with Pinia |
| 144 | + |
| 145 | +- Use `createPinia()` and `setActivePinia` when testing Store files |
| 146 | +- Only use `createTestingPinia` if you specifically need its testing features |
| 147 | +- Let stores initialize with their natural default state |
| 148 | +- Don't mock the store being tested |
| 149 | +- Ensure Vue reactivity imports are added to store files (computed, ref, watchEffect) |
| 150 | +- Place all mock declarations at the top level |
| 151 | +- Use factory functions for module mocks to avoid hoisting issues |
| 152 | +- Clear mocks between tests to ensure isolation |
| 153 | + |
| 154 | +## Development Memories |
| 155 | + |
| 156 | +- We are using tailwind v4 we do not need a tailwind config anymore |
| 157 | +- always search the internet for tailwind v4 documentation when making tailwind related style changes |
| 158 | +- never run or restart the API server or web server. I will handle the lifecycle, simply wait and ask me to do this for you |
| 159 | +- Never use the `any` type. Always prefer proper typing |
| 160 | +- Avoid using casting whenever possible, prefer proper typing from the start |
| 161 | +- **IMPORTANT:** cache-manager v7 expects TTL values in **milliseconds**, not seconds. Always use milliseconds when setting cache TTL (e.g., 600000 for 10 minutes, not 600) |
0 commit comments