# CLQMS Frontend - Agent Guidelines
## Build Commands
```bash
# Development
pnpm dev # Start dev server (http://localhost:5173)
# Production
pnpm build # Build for production (outputs to build/)
pnpm preview # Preview production build locally
# Type Checking
pnpm check # Run svelte-check TypeScript validation
pnpm check:watch # Run type checker in watch mode
# Package Management
pnpm install # Install dependencies
pnpm prepare # Sync SvelteKit (runs automatically)
```
## Code Style Guidelines
### TypeScript & Svelte
- Use TypeScript strict mode (configured in tsconfig.json)
- Prefer explicit types over `any`
- Use Svelte 5 runes: `$state`, `$derived`, `$effect`, `$props`
- Components use `.svelte` extension with `
{title}
```
### Styling (Tailwind + DaisyUI)
- Use Tailwind utility classes
- DaisyUI components: `btn`, `card`, `input`, `modal`, etc.
- Theme: Forest (medical green primary: #2d6a4f)
- Color utilities: `text-emerald-600`, `bg-emerald-100`
- Responsive: `sm:`, `md:`, `lg:` prefixes
- Spacing: 4px base unit (e.g., `p-4` = 16px)
### Error Handling
```typescript
import { api } from '$server/api';
async function fetchData() {
const { data, error, success } = await api.get('/api/patients');
if (!success || error) {
console.error('Failed to fetch:', error?.message);
return;
}
// Use data
}
```
### Form Handling (Superforms + Zod)
```typescript
import { superForm } from 'sveltekit-superforms';
import { zodClient } from 'sveltekit-superforms/adapters';
import { z } from 'zod';
const schema = z.object({
username: z.string().min(1, 'Required'),
email: z.string().email('Invalid email')
});
const { form, errors, enhance } = superForm(data?.form, {
validators: zodClient(schema)
});
```
### State Management
```typescript
import { writable } from 'svelte/store';
interface AuthState {
user: User | null;
isAuthenticated: boolean;
}
function createAuthStore() {
const { subscribe, set, update } = writable({
user: null,
isAuthenticated: false
});
return {
subscribe,
login: (user: User) => update(s => ({ ...s, user, isAuthenticated: true })),
logout: () => set({ user: null, isAuthenticated: false })
};
}
export const auth = createAuthStore();
```
### Route Structure
```
src/routes/
├── +layout.svelte # Root layout
├── +page.svelte # Landing page (redirects)
├── (app)/ # Group: Protected routes
│ ├── +layout.svelte # App layout with sidebar
│ └── dashboard/
│ └── +page.svelte
└── (auth)/ # Group: Public routes
├── +layout.svelte # Auth layout (centered)
└── login/
└── +page.svelte
```
### API Client Usage
```typescript
import { api } from '$server/api';
// GET
const { data } = await api.get('/api/users');
// POST
const { data } = await api.post('/api/users', { name: 'John' });
// PATCH
const { data } = await api.patch('/api/users/1', { name: 'Jane' });
// DELETE
const { data } = await api.delete('/api/users/1');
```
### Environment Variables
```typescript
// Use only PUBLIC_ prefix for client-side
import { PUBLIC_API_BASE_URL } from '$env/static/public';
```
### Git Workflow
- Commit messages: imperative mood (e.g., "Add patient form validation")
- Branch naming: `feature/`, `fix/`, `refactor/` prefixes
- Never commit secrets or `.env.local`
## Testing (To Be Configured)
Test framework not yet configured. When added:
- Unit tests: Vitest (planned per checklist)
- E2E tests: Playwright (planned per checklist)