Loading...
Loading...
Owns repositories, data sources and mapping for Compose and Compose Multiplatform apps: DTO to domain to UiModel boundaries, Ktor clients and bearer auth, WebSocket and SSE, Room, DataStore, Paging 3, offline-first and data-layer tests. Use when writing or reviewing a repository, data source, DTO, mapper, HttpClient, bearer token, WebSocket, SSE, Room DAO, migration, DataStore, PagingSource, RemoteMediator, offline cache or MockEngine test. Do NOT use for ViewModel or UI wiring (compose-feature), composables (compose-ui), the MVI contract or error tiers (compose-architecture), Gradle modules (compose-project), or commonMain vs platform splits (compose-platform).
npx skill4agent add meet-miyani/compose-skill compose-datatemplates/coreBaseViewModellaunchGuardedAppErrorNetworkExceptioncompose-architecturegradle/libs.versions.tomlcompose-architecture| Task | Use instead |
|---|---|
| Route first: decide the task path and files to read | the |
ViewModel, Contract, Route, error tier choice, | the |
| Composables, lists, stability, resources | the |
| the |
| Modules, convention plugins, version catalog, CI | the |
## Project decisionscompose-architectureexisting-projects.mdinternalkotlin.time.Instant@SerializabletoDomain()data/remote/mapper/compose-architecturenulllaunchGuardedcatchClientRequestExceptionnullnetworking-ktor.mdNetworkExceptiononErrorPagingDataFlowUiStatelaunchGuardedLoadStatecompose-architecturenullexpectSuccess = trueClientRequestExceptionServerResponseExceptionNetworkException.Httpcompose-uisinglecommonMainsuspend fun getX(…)fun getXStream(…): Flow<…>observeXgetXFlowgetXPagercompose-architecturegradle/libs.versions.tomlcommonMaingetXgetXStreamdomain/repository/toDomain()gradle/libs.versions.tomlcompose-architecture| Need | Store |
|---|---|
| Key-value settings, flags, tokens | Preferences DataStore (rule 10) |
| Structured settings object | One JSON string key in Preferences DataStore (rule 10) |
| Queries, indexes, relations, more than ~100 entries | Room |
| Large blobs (images, files) | Filesystem, with only the path in Room or DataStore |
| Need | Transport |
|---|---|
| Server-push text feed over HTTP, auto-reconnect wanted | SSE |
| Bidirectional, binary, or realtime collaboration | WebSocket |
RemoteMediatorRemoteMediator.initializeSKIP_INITIAL_REFRESHLAUNCH_INITIAL_REFRESH| Thought | Reality |
|---|---|
| "I'll import the DTO into the ViewModel; the fields are identical." | No. Rule 1: DTOs stay |
| "I'll keep the timestamp as a string in the domain; parsing is cheap." | No. Rule 2: domain carries |
| "I'll default the missing reminder to now so the field is never null." | No. Rule 4: absence stays |
"I'll catch | No. Rule 5: failures propagate to |
"I'll map the timeout to | No. The |
"I'll put | No. Rule 6: a separate |
| "I'll resolve the detail note from the cached list; it is faster." | No. Rule 7: fetch by identity. The cache is cold after restore. |
| "I'll check the status code at each call site for control." | No. Rule 8: |
"I'll use | No. The |
"I'll add a | No. Rule 3 and the M-11 triggers in the |
| "This method probably exists on the client builder." | Stop and verify now (stance item 1). Inventing a third-party API does not compile. |
scripts/composekit/run-checks.shscripts/run-checks.sh <project-root>*Dto*Entitygrep -rn "public .*Dto\|^class .*Dto\|^data class .*Dto" --include='*.kt' <data-root>internalgrep -rn "String.*[Aa]t\b\|.*Date.*String\|@SerialName\|@Serializable" --include='*.kt' <domain-model-root>grep -rn "catch.*NetworkException" --include='*.kt' <data-root>FlowStreamcompose-architectureobserveXgetXFlowgetXPagercommonMain^import (java|android)\.libs.versions.tomlexpectSuccessPagingDatacachedInLoadStateRemoteMediatorInitializeActionMockEngine