-
Notifications
You must be signed in to change notification settings - Fork 0
Data Layer Agent
Ali Sadeghi edited this page May 28, 2026
·
3 revisions
Implements the data layer for KMP features. Invoked by creating-kmp-feature skill in Phase 4 (Implementation).
Model: sonnet · Color: blue · Allowed tools: Read, Write, Edit, Glob, Grep, ./gradlew
- Domain DTOs with
@Serializableindata/model/ - Ktor Resources (type-safe API routes) in
data/remote/ -
{Entity}RemoteDataSourceinterface +…Implindata/datasource/ -
{Entity}Repositoryinterface +…Implindata/repository/ -
feature/{featurename}/build.gradle.ktsfrom the gradle template - All using
Either<T>for error handling
The gradle template intentionally does NOT redeclare compileSdk, minSdk, or jvmTarget — root config handles them.
- Load architecture references (
_shared/patterns.md,creating-kmp-feature/architecture/data.md) on demand. - Create module structure using the gradle template.
- Implement models (
data/model/). - Implement Ktor Resources (
data/remote/). - Implement DataSource interface + impl.
- Implement Repository interface + impl.
- Validate:
./gradlew :feature:{featurename}:assembleAndroidMain.
// feature/productcatalog/data/model/Product.kt
@Serializable
data class Product(
val id: String,
val name: String,
val price: Double,
val imageUrl: String?,
)
// feature/productcatalog/data/remote/ProductResources.kt
@Resource("/products")
class ProductResource {
@Resource("{id}")
data class Id(val parent: ProductResource, val id: String)
}
// feature/productcatalog/data/datasource/ProductRemoteDataSource.kt
interface ProductRemoteDataSource {
suspend fun getProducts(): Either<List<Product>>
suspend fun getProduct(id: String): Either<Product>
}
class ProductRemoteDataSourceImpl(
private val client: ApiClient,
) : ProductRemoteDataSource {
override suspend fun getProducts(): Either<List<Product>> =
client.get(ProductResource())
override suspend fun getProduct(id: String): Either<Product> =
client.get(ProductResource.Id(ProductResource(), id))
}
// feature/productcatalog/data/repository/ProductRepository.kt
interface ProductRepository {
suspend fun getProducts(): Either<List<Product>>
suspend fun getProduct(id: String): Either<Product>
}
class ProductRepositoryImpl(
private val dataSource: ProductRemoteDataSource,
) : ProductRepository {
override suspend fun getProducts() = dataSource.getProducts()
override suspend fun getProduct(id: String) = dataSource.getProduct(id)
}Uses ErrorConst from {CORE_DATA_PKG}:
| Constant | Triggered when |
|---|---|
ErrorConst.NoNetwork |
Connection errors |
ErrorConst.Unauthorized |
HTTP 401 |
ErrorConst.SerializationError |
JSON parsing failures |
ErrorConst.ServerUnknownError(httpCode) |
Unknown errors |
Loads troubleshooting/data.md on demand, identifies the error pattern, fixes, retries (max 3).
## Data Layer Complete: {featurename}
### Files Created
- build.gradle.kts
- data/model/*.kt
- data/remote/{Feature}Resources.kt
- data/datasource/{Feature}RemoteDataSource.kt + Impl
- data/repository/{Feature}Repository.kt + Impl
### Rules Followed
✅ Interface + Impl pairs
✅ Either<T> returns
✅ Lowercase packages
✅ Build successful
Back to Feature-Development-Agents | Agents