clqms-fe1/AGENTS.md

169 lines
4.2 KiB
Markdown

# AGENTS.md - Coding Guidelines for CLQMS Frontend
## Project Overview
SvelteKit frontend for Clinical Laboratory Quality Management System (CLQMS). Uses Svelte 5 runes, TailwindCSS 4, DaisyUI, and Lucide icons.
## Build Commands
```bash
# Development server
npm run dev
# Production build
npm run build
# Preview production build
npm run preview
# Sync SvelteKit (runs automatically on install)
npm run prepare
```
## Testing
**No test framework configured yet.** When adding tests:
- Use Vitest for unit tests (recommended with SvelteKit)
- Use Playwright for E2E tests
- Run single test: `vitest run src/path/to/test.js`
- Run tests in watch mode: `vitest`
## Code Style Guidelines
### JavaScript/TypeScript
- **ES Modules**: Always use `import`/`export` (type: "module" in package.json)
- **Semicolons**: Use semicolons consistently
- **Quotes**: Use single quotes for strings
- **Indentation**: 2 spaces
- **Trailing commas**: Use in multi-line objects/arrays
- **JSDoc**: Document all exported functions with JSDoc comments
### Svelte Components
```svelte
<script>
// 1. Imports first - group by: Svelte, $lib, external
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
import { auth } from '$lib/stores/auth.js';
import { login } from '$lib/api/auth.js';
import { Icon } from 'lucide-svelte';
// 2. Props (Svelte 5 runes)
let { children, data } = $props();
// 3. State
let loading = $state(false);
let error = $state('');
// 4. Derived state (if needed)
let isValid = $derived(username.length > 0);
// 5. Effects
$effect(() => {
// side effects
});
// 6. Functions
function handleSubmit() {
// implementation
}
</script>
```
### Naming Conventions
- **Components**: PascalCase (`LoginForm.svelte`)
- **Files/Routes**: lowercase with hyphens (`+page.svelte`, `user-profile/`)
- **Variables**: camelCase (`isLoading`, `userName`)
- **Constants**: UPPER_SNAKE_CASE (`API_URL`, `STORAGE_KEY`)
- **Stores**: camelCase, descriptive (`auth`, `userStore`)
- **Event handlers**: prefix with `handle` (`handleSubmit`, `handleClick`)
### Imports Order
1. Svelte imports (`svelte`, `$app/*`)
2. $lib aliases (`$lib/stores/*`, `$lib/api/*`, `$lib/components/*`)
3. External libraries (`lucide-svelte`)
4. Relative imports (minimize these, prefer `$lib`)
### Project Structure
```
src/
lib/
api/ # API client and endpoints
stores/ # Svelte stores
components/ # Reusable components
assets/ # Static assets
routes/ # SvelteKit routes
(app)/ # Route groups
login/
dashboard/
```
### API Client Patterns
```javascript
// src/lib/api/client.js - Base client handles auth
import { apiClient, get, post, put, del } from '$lib/api/client.js';
// src/lib/api/feature.js - Feature-specific endpoints
export async function getItem(id) {
return get(`/api/items/${id}`);
}
export async function createItem(data) {
return post('/api/items', data);
}
```
### Error Handling
```javascript
// API errors are thrown with message
try {
const result = await api.login(username, password);
} catch (err) {
error = err.message || 'An unexpected error occurred';
console.error('Login failed:', err);
}
```
### Styling with Tailwind & DaisyUI
- Use Tailwind utility classes
- DaisyUI components: `btn`, `card`, `alert`, `input`, `navbar`
- Color scheme: `primary` (emerald), `base-100`, `base-200`
- Custom colors in `app.css` with `@theme`
### Authentication Patterns
- Auth state in `$lib/stores/auth.js`
- Check auth in layout `onMount`
- Redirect to `/login` if unauthenticated
- API client auto-redirects on 401
### Environment Variables
```javascript
const API_URL = import.meta.env.VITE_API_URL || '';
```
### LocalStorage
- Only access in browser: check `browser` from `$app/environment`
- Use descriptive keys: `clqms_username`, `clqms_remember`
## Proxy Configuration
API requests to `/api` are proxied to `http://localhost:8000` in dev.
## Important Notes
- No ESLint or Prettier configured yet - add if needed
- No test framework configured yet
- Uses Svelte 5 runes: `$props`, `$state`, `$derived`, `$effect`
- SvelteKit file-based routing with `+page.svelte`, `+layout.svelte`