create-dtolisted
Install: claude install-skill NarekManukyan/flutter-mobx-kit
# Create a DTO
Governed by [ADR-0011](../../../docs/adr/0011-retrofit-typed-api-layer.md). DTOs live in `packages/api`, never in `lib/`.
## Location
DTOs are owned by the resource provider that returns them:
```
packages/api/lib/src/providers/{resource}_provider/
{resource}_api_provider.dart
{resource}_provider.dart barrel: exports models + provider
models/
models.dart export 'src/models.dart';
src/
models.dart export every dto in this dir
{name}_dto.dart
```
Cross-resource models (`ListResponseDto`, shared envelopes) go in `packages/api/lib/src/models/`.
Naming: `{name}_dto.dart` for responses, `{name}_request_dto.dart` for request bodies.
## Shape
```dart
import 'package:freezed_annotation/freezed_annotation.dart';
part 'todo_dto.freezed.dart';
part 'todo_dto.g.dart';
@freezed
sealed class TodoDto with _$TodoDto {
factory TodoDto({
required String id,
required String title,
required bool completed,
}) = _TodoDto;
factory TodoDto.fromJson(Map<String, dynamic> json) =>
_$TodoDtoFromJson(json);
}
```
- `@freezed sealed class` — the repo's freezed 3.x convention.
- Both `part` directives, in this order.
- `fromJson` factory always present, even on request-only DTOs (cheap, and mock interceptors need it).
- `build.yaml` sets `explicit_to_json: true` and `any_map: true` globally — nested DTOs serialise correctly and `Map<dynamic, dynamic>` payloads parse. Do not re-declare