# ADR-0002: DTI server response envelope болон REST status standard

## Status

Accepted

## Context

`@napp/dti-server` нь DTI client болон энгийн REST API client аль алинд ойлгомжтой response format буцаах шаардлагатай.

Өмнөх шийдвэрээр `@napp/dti-server` нь `@napp/dti-client`-ээс runtime хамааралгүй, standalone REST API байдлаар ажиллана гэж тогтсон. Иймээс response body нь DTI client-д тогтвортой contract өгөхөөс гадна HTTP status code нь REST API standard болон external tooling-д зөв signal өгөх ёстой.

## Decision

DTI server амжилттай result буцаахдаа дараах envelope ашиглана:

```json
{
  "success": true,
  "data": {}
}
```

Response body зөвшөөрсөн JSON success result дээр `success` нь `true`, `data` талбар заавал байна. Bodyless HTTP status-ийн exception-ийг доор тодорхойлсон.

Success response-ийн default HTTP status нь `200 OK` байна. Library action method эсвэл path-аас success status болон response header автоматаар infer хийхгүй. Тухайлбал:

- `POST` action дээр `201 Created` автоматаар сонгохгүй;
- `DELETE` action дээр `204 No Content` автоматаар сонгохгүй;
- `Location` header автоматаар үүсгэхгүй.

Default-оос өөр success status болон response headers шаардлагатай бол application server handler өөрөө удирдана. Library application-ийн тохируулсан status болон headers-ийг override хийхгүй.

```ts
dti.action(tenantCreate, async ({ body, res }) => {
    const tenant = await createTenant(body);

    res.status(201);
    res.setHeader("Location", `/tenants/${tenant.id}`);

    return tenant;
});
```

`201 Created` зэрэг body зөвшөөрдөг status дээр JSON success envelope хэвээр ашиглана.

Application `204 No Content` зэрэг response body хориглосон HTTP status сонговол HTTP semantics нь JSON envelope дүрмээс давуу үйлчилнэ. Энэ үед response body болон success envelope буцаахгүй. DTI client bodyless success response-ийг successful `undefined` result гэж ойлгоно. Application action result contract болон сонгосон status/body semantics-ийг хооронд нь нийцүүлэх үүрэгтэй.

DTI server error result буцаахдаа дараах envelope ашиглана:

```json
{
  "success": false,
  "code": "DTI_BODY_VALIDATE_ERROR",
  "message": "Invalid action body",
  "details": {}
}
```

Error result дээр `success` нь `false` байна. `code` болон `message` талбарууд заавал байна.

`message` нь хэрэглэгчид ойлгомжтой алдааны message байна.

`code` нь алдааг ялгах identifier байна. `code` дээр тогтсон format шаардахгүй. Тухайн app өөрийн convention-оор шийднэ.

`details` field нь optional байна. Server-ээс ирэхгүй байж болно. Ирвэл any JSON object байна. Library level дээр `details`-ийн дотоод бүтэц заахгүй.

Error result дээр HTTP status code нь REST API standard дагана. Жишээ нь:

- Request schema/format-level validation алдаа: `400`
- Authentication шаардлагатай үед: `401`
- Permission алдаа: `403`
- Resource эсвэл route олдохгүй үед: `404`
- Business conflict үед: `409`
- Request syntax зөв боловч domain/business validation fail үед: `422`
- Server/internal/result validation алдаа: `500`

`400` status нь DTI contract schema эсвэл request format буруу үед хэрэглэгдэнэ. Жишээ нь required field байхгүй, field type буруу, body/query schema-д нийцэхгүй байх.

`422` status нь request schema болон format зөв боловч domain/business rule fail үед хэрэглэгдэнэ. Жишээ нь username давхцах, balance хүрэхгүй, тухайн төлөвт operation хийх боломжгүй байх.

DTI envelope нь response body contract-ийг тогтвортой байлгана. HTTP status code нь REST integration, monitoring, proxy, external client-д зориулсан protocol-level signal байна.

## Consequences

- DTI client нь `success`, `data`, `code`, `message`, `details` field-үүдээр response parse хийх боломжтой байна.
- DTI client ашиглаагүй REST API consumer HTTP status code-оор алдааны төрлийг стандарт байдлаар ойлгоно.
- Бүх error response дээр `200` буцаахгүй. Энэ нь REST tooling болон monitoring-д буруу signal өгөхөөс сэргийлнэ.
- Success response default `200` байна; method-based automatic status inference хийхгүй.
- Custom success status болон headers application-ийн ownership байна.
- Bodyless success status дээр DTI envelope буцаахгүй.
- Error details илүү structured хэлбэрээр дамжих боломжтой болно.
- `details` дотор sensitive мэдээлэл оруулахгүй байх шаардлагатай.
- `code` format нь library-level constraint биш тул app бүр өөрийн error naming convention ашиглах боломжтой.

## Alternatives Considered

### Бүх response дээр `200` status буцаах

DTI client implementation энгийн болох боловч REST API standard болон external tooling-тэй нийцэл муудна. Monitoring, retry policy, proxy, Postman, curl зэрэг хэрэглээнд error signal алдагдана.

### Error body дээр зөвхөн `message` буцаах

Хэрэглэгчид уншихад энгийн боловч programmatic error handling хийхэд хангалтгүй. `code` болон `details` байхгүй бол client талд алдааг ангилах, UI mapping хийх, logging хийх боломж хязгаарлагдана.

### Error details-ийг string хэлбэрээр буцаах

Энгийн боловч field-level validation, nested schema error, integration diagnostic зэрэг structured мэдээлэл дамжуулахад тохиромжгүй.

### HTTP method-оос success status автоматаар infer хийх

`POST` дээр `201`, `DELETE` дээр `204` сонгох нь зарим CRUD endpoint-д тохиромжтой. Гэхдээ method дангаараа operation-ийн бодит outcome, response body болон resource location-ийг тодорхойлохгүй. Иймээс library default `200` ашиглаж, бусад status болон headers-ийг application удирдана.
