# Controller Layer Guide

이 디렉토리에는 API 엔드포인트 핸들러 함수를 정의합니다.

## 컨트롤러 작성 규칙

### 기본 구조

```python
from pydantic import validate_call
from sawsi.handler.controller_decorator import controller


@controller
def my_endpoint(param1: str, param2: int):
    return {
        'result': 'value'
    }
```

### 필수 요소

- `@controller`: 라우터 레지스트리에 함수를 등록함. 모듈 경로 + 함수명이 엔드포인트 경로가 됨
  - 예: `{{app}}.controller.sample_login.login`
- `@validate_call`: pydantic 타입 검증. 잘못된 타입이 들어오면 자동으로 에러 발생

### 동작 방식

1. 클라이언트가 `cmd: "{{app}}.controller.module.function"` 으로 요청
2. 라우터가 해당 함수를 찾아서 호출
3. request body의 키-값이 함수 파라미터에 자동 매핑됨
4. 반환값이 JSON으로 직렬화되어 응답

### 모델 사용 패턴

```python
from app.model.sample_user import User

@controller
def get_user(user_id: str):
    user = User.get(user_id)
    return {'user': user.view()}
```

### 에러 발생

```python
import errs

@controller
def protected_endpoint(session_id: str):
    if not session_id:
        raise errs.no_session
    # ...
```

- 에러는 `errs.py`에 `AppError`로 정의
- `raise`하면 클라이언트에 에러 코드와 메시지가 반환됨

### 주의사항

- `@controller`가 붙은 함수는 내부 헬퍼로도 사용 가능하지만, `allowed_cmd_prefixes`에 해당하는 경로의 함수만 외부에서 호출 가능
- 파라미터 이름은 request body의 키와 일치해야 함
- 반환값은 반드시 JSON 직렬화 가능한 dict여야 함
