> ## Documentation Index
> Fetch the complete documentation index at: https://system.muzemus.online/llms.txt
> Use this file to discover all available pages before exploring further.

# Coding Conventions

> Code style, patterns, and conventions used throughout MUZE

## General principles

| Principle    | Description                                   |
| ------------ | --------------------------------------------- |
| Consistency  | Follow existing patterns in the codebase      |
| Explicitness | Prefer explicit code over clever abstractions |
| Simplicity   | Avoid premature optimization                  |
| Type safety  | Use TypeScript's type system fully            |

## Backend conventions (NestJS)

### File naming

| Type       | Convention        | Example                             |
| ---------- | ----------------- | ----------------------------------- |
| Module     | `*.module.ts`     | `orders.module.ts`                  |
| Controller | `*.controller.ts` | `orders.controller.ts`              |
| Service    | `*.service.ts`    | `orders.service.ts`                 |
| DTO        | `*.dto.ts`        | `create-order.dto.ts`               |
| Guard      | `*.guard.ts`      | `session.guard.ts`                  |
| Filter     | `*.filter.ts`     | `prisma-exception.filter.ts`        |
| Entity     | `*.entity.ts`     | Not used; Prisma supplies the types |

### Module structure

Each feature module follows the same structure:

```typescript theme={null}
@Module({
  imports: [PrismaModule],
  controllers: [OrdersController],
  providers: [OrdersService],
  exports: [OrdersService],
})
export class OrdersModule {}
```

### Controller pattern

```typescript theme={null}
@Controller('orders')
@UseGuards(SessionGuard, PermissionsGuard, ScopeGuard)
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Get()
  @Permissions(Permission.ORDERS_VIEW_ALL)
  async findAll(@Request() req: RequestWithPermissions) {
    return this.ordersService.findAll(req);
  }

  @Post()
  @Permissions(Permission.ORDERS_CREATE)
  async create(
    @Body() dto: CreateOrderDto,
    @Request() req: RequestWithPermissions,
  ) {
    return this.ordersService.create(dto, req);
  }
}
```

### Service pattern

```typescript theme={null}
@Injectable()
export class OrdersService {
  private readonly logger = new Logger(OrdersService.name);

  constructor(private prisma: PrismaService) {}

  async findAll(request: RequestWithPermissions) {
    const where = this.buildScopeFilter(request);
    return this.prisma.order.findMany({ where, include: { items: true } });
  }
}
```

## Frontend conventions (React)

### File naming

| Type            | Convention          | Example       |
| --------------- | ------------------- | ------------- |
| Page component  | `*.tsx` (lowercase) | `orders.tsx`  |
| UI component    | `*.tsx` (lowercase) | `button.tsx`  |
| Custom hook     | `use-*.ts`          | `use-auth.ts` |
| Utility         | `*.ts` (lowercase)  | `utils.ts`    |
| Type definition | `*.ts` (lowercase)  | `types.ts`    |

### Component pattern

```typescript theme={null}
export function OrderCard({ order }: { order: Order }) {
  return (
    <Card>
      <CardHeader>
        <CardTitle>{order.orderNumber}</CardTitle>
      </CardHeader>
      <CardContent>
        <Badge>{order.status}</Badge>
      </CardContent>
    </Card>
  );
}
```

### Page component pattern

```typescript theme={null}
export default function OrdersPage() {
  const { data: orders, isLoading, error } = useOrders();

  if (isLoading) return <LoadingSpinner />;
  if (error) return <ErrorMessage error={error} />;
  if (!orders?.length) return <EmptyState message="No orders found" />;

  return (
    <div>
      <h1>Orders</h1>
      <OrderTable orders={orders} />
    </div>
  );
}
```

## Styling conventions

### Tailwind classes

* Use Tailwind utility classes exclusively
* No custom CSS unless absolutely necessary
* Use `cn()` utility for conditional classes:

```typescript theme={null}
import { cn } from '@/lib/utils';

<div className={cn(
  'base classes',
  isActive && 'active classes',
  variant === 'primary' && 'primary classes',
)} />
```

### shadcn/ui components

All UI primitives come from shadcn/ui. Do not create custom button, input, or table components; use the existing ones:

```typescript theme={null}
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
```

## Error handling

### Backend

* Use NestJS exception filters for consistent error responses
* Throw specific exceptions (`NotFoundException`, `ForbiddenException`)
* Log errors with context using NestJS Logger

### Frontend

* Use React Query's error state for API errors
* Display errors via toast notifications (sonner)
* Use Error Boundaries for component-level error isolation

## Git conventions

| Type          | Prefix      | Example                                       |
| ------------- | ----------- | --------------------------------------------- |
| Feature       | `feat:`     | `feat: add order approval flow`               |
| Bug fix       | `fix:`      | `fix: correct entitlement budget calculation` |
| Refactor      | `refactor:` | `refactor: extract criteria evaluation`       |
| Documentation | `docs:`     | `docs: update API documentation`              |
| Test          | `test:`     | `test: add entitlement engine unit tests`     |
