38 lines
1.1 KiB
Cheetah
38 lines
1.1 KiB
Cheetah
---
|
|
description: "json_serializable conventions for {{PROJECT_NAME}} — Pillar 4"
|
|
alwaysApply: true
|
|
---
|
|
|
|
# json_serializable Standards — {{PROJECT_NAME}}
|
|
|
|
## Model annotation
|
|
```dart
|
|
@JsonSerializable(explicitToJson: true) // explicitToJson for nested objects
|
|
class ProductDto {
|
|
final String id;
|
|
final String name;
|
|
@JsonKey(name: 'unit_price') // snake_case API → camelCase Dart
|
|
final double unitPrice;
|
|
@JsonKey(defaultValue: false)
|
|
final bool isActive;
|
|
final DateTime createdAt; // auto-converted from ISO 8601 string
|
|
|
|
const ProductDto({
|
|
required this.id,
|
|
required this.name,
|
|
required this.unitPrice,
|
|
required this.isActive,
|
|
required this.createdAt,
|
|
});
|
|
|
|
factory ProductDto.fromJson(Map<String, dynamic> json) => _$ProductDtoFromJson(json);
|
|
Map<String, dynamic> toJson() => _$ProductDtoToJson(this);
|
|
}
|
|
```
|
|
|
|
## Critical rules
|
|
- **NEVER** edit `*.g.dart` files
|
|
- Use `@JsonKey(defaultValue: ...)` for nullable API fields — API contracts change
|
|
- Use `explicitToJson: true` whenever the model has nested objects
|
|
- Null safety: API fields not guaranteed to be non-null should be `String?` not `String`
|