
Secure, modular SDK for remote data access: pluggable HTTP/WebSocket transports, centralized execution pipeline, consistent error classification, credential/session management, certificate pinning, and guides.
| Módulo | Maven Central |
|---|---|
network-core |
|
network-ktor |
|
network-ws-core |
|
network-ws-ktor |
|
security-core |
|
sample-api |
SDK Kotlin Multiplatform para Acceso Remoto Seguro de Datos
Una librería Kotlin Multiplatform (KMP) reutilizable y modular diseñada para proveer una base segura, escalable y agnóstica de transporte para operaciones de datos remotos en aplicaciones Android e iOS.
data: estructura de carpetas, DTOs vs modelos de dominio, DataSource, Repository, DI, y referencias a escenarios avanzados// 1. Crea el repository (configuración por defecto incluida)
val repository = SampleApiFactory.create()
// 2. Llama un endpoint
val result: NetworkResult<List<User>> = repository.getUsers()
// 3. Maneja el resultado
result.fold(
onSuccess = { users ->
users.forEach { println("${it.displayName} (@${it.handle})") }
},
onFailure = { error ->
println("Error: ${error.message}")
}
)
SampleApiFactory.create()ensambla internamente todo el pipeline: configuración → engine HTTP → executor con reintentos → data source → repository. Tú solo interactúas conUserRepositoryyNetworkResult<User>.
Para configuración avanzada (auth, timeouts personalizados, interceptors), consulta la Guía de Integración o las guías rápidas para Android / iOS.
El SDK está publicado en Maven Central. Agrega los módulos que necesites en tu build.gradle.kts:
repositories {
mavenCentral()
}
dependencies {
// Contratos core (siempre requeridos)
implementation("io.github.dancrrdz93:network-core:0.4.0")
// Implementación de transporte HTTP (elige uno)
implementation("io.github.dancrrdz93:network-ktor:0.4.0")
// WebSocket (si necesitas conexiones persistentes bidireccionales)
implementation("io.github.dancrrdz93:network-ws-core:0.4.0")
implementation("io.github.dancrrdz93:network-ws-ktor:0.4.0")
// Seguridad (auth, almacenamiento seguro, gestión de sesiones)
implementation("io.github.dancrrdz93:security-core:0.4.0")
// Módulo de referencia (opcional — para ver el patrón de integración)
implementation("io.github.dancrrdz93:sample-api:0.4.0")
}Si el SDK se consume como módulo local (composite build), usa implementation(project(":network-core")) en su lugar.
Core Data Platform es un SDK interno construido con Kotlin Multiplatform que provee una base unificada, segura y extensible para hacer llamadas a APIs remotas desde aplicaciones móviles. Está diseñado para ser consumido por múltiples apps a gran escala sin acoplarlas a ningún cliente HTTP, librería de serialización o contrato de backend específico.
En organizaciones que mantienen múltiples aplicaciones móviles, cada equipo tiende a construir su propio stack de networking y seguridad. Esto lleva a:
Core Data Platform resuelve esto proveyendo una única base bien testeada y dirigida por contratos que todas las apps comparten, manteniendo cada app libre de definir su propia lógica de dominio, serialización y UI.
| Objetivo | Cómo se logra |
|---|---|
| Reutilizable | Contratos puros en network-core y security-core — sin lógica específica de app, sin suposiciones de backend |
| Desacoplado |
network-core tiene cero conocimiento de Ktor, OkHttp o cualquier librería HTTP. El transporte es pluggable vía HttpEngine
|
| Seguro | Abstracción de credenciales, almacenamiento seguro de plataforma, sanitización de logs, políticas de confianza TLS — todo como contratos de primera clase |
| Escalable | Nuevos módulos de dominio (pagos, fidelidad, etc.) se agregan sin modificar módulos core |
| Portable | Kotlin Multiplatform con contratos en commonMain e implementaciones de plataforma en androidMain/iosMain
|
| Mantenible | Interfaces pequeñas y enfocadas. Clases open para extensión. Tipos sealed para manejo exhaustivo. Sin God objects |
La arquitectura sigue tres principios fundamentales:
Contratos sobre implementaciones — Cada componente principal se define como una interfaz o clase abstracta en commonMain. Las implementaciones concretas se inyectan, nunca se hardcodean.
Separación por capas — El proyecto separa qué hace el SDK (contratos) de cómo lo hace (implementaciones) y quién lo usa (módulos de dominio).
Cero acoplamiento lateral — network-core y security-core son módulos completamente independientes. Ninguno sabe que el otro existe. Solo se componen en el punto de consumo (módulos de dominio o la app).
Estos módulos abordan preocupaciones fundamentalmente diferentes:
network-core responde: "¿Cómo ejecuto, valido, reintento y clasifico operaciones HTTP de forma segura?"
security-core responde: "¿Cómo almaceno secretos, gestiono sesiones, evalúo confianza y protejo datos sensibles?"
Mantenerlos independientes significa:
CredentialHeaderMapper) que vive en security-core y retorna un simple Map<String, String> — sin tipos de red requeridos.┌──────────────────────────────────────────────────────────────┐
│ YOUR APPLICATION │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Feature A│ │ Feature B│ │ Feature C│ ← App layers │
│ └────┬─────┘ └─────┬────┘ └──────┬───┘ │
│ │ │ │ │
│ ┌────▼──────────────▼──────────────▼────┐ │
│ │ Domain API Modules │ ← :payments-api │
│ │ (DTOs, Mappers, DataSources, Repos) │ :loyalty-api │
│ └────┬──────────────┬──────────────┬────┘ :users-api │
│ │ │ │ │
├────────┼──────────────┼──────────────┼───────────────────────┤
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌────────────┐ ┌──────────────┐ │
│ │ network │ │ network │ │ security │ ← SDK │
│ │ -core │ │ -ktor │ │ -core │ │
│ └──────────┘ └────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────────┘
Los módulos del SDK se sitúan en la parte inferior del grafo de dependencias. Las funcionalidades de la aplicación nunca importan Ktor, nunca ven RawResponse, y nunca manejan lógica de reintentos directamente.
| Módulo | Responsabilidad | Contratos clave | Dependencias |
|---|---|---|---|
:network-core |
Abstracciones puras de red: ejecución HTTP, errores, validación, reintentos, observabilidad |
HttpEngine, SafeRequestExecutor, NetworkResult<T>, NetworkError, NetworkEventObserver, LoggingObserver, NetworkLogger, RetryPolicy
|
Solo kotlinx-coroutines-core
|
:network-ktor |
Adaptador de transporte HTTP. Encapsula Ktor completamente |
KtorHttpEngine, KtorErrorClassifier
|
:network-core, ktor-client-core, ktor-client-okhttp (Android), ktor-client-darwin (iOS) |
:network-ws-core |
Abstracciones puras de WebSocket: conexión, reconexión, errores, observabilidad |
WebSocketEngine, SafeWebSocketExecutor, WebSocketConnection, WebSocketError, ReconnectPolicy, WebSocketEventObserver
|
Solo kotlinx-coroutines-core
|
:network-ws-ktor |
Adaptador de transporte WebSocket. Encapsula ktor-client-websockets completamente |
KtorWebSocketEngine, KtorWebSocketErrorClassifier
|
:network-ws-core, :security-core, ktor-client-core, ktor-client-websockets, ktor-client-okhttp (Android), ktor-client-darwin (iOS) |
:security-core |
Credenciales, sesiones, almacenamiento seguro, confianza TLS, sanitización de logs |
Credential, CredentialProvider, SessionController, SecretStore, TrustPolicy, LogSanitizer
|
Solo kotlinx-coroutines-core
|
:sample-api |
Módulo piloto de referencia: demuestra el patrón DTO → Mapper → DataSource → Repository → Factory |
UserDto, User, UserMapper, UserRemoteDataSource, UserRepository, SampleApiFactory
|
:network-core, :network-ktor, :security-core, kotlinx-serialization-json
|
Implementaciones de plataforma en :security-core:
AndroidSecretStore — DataStore + Cipher(AES/GCM/NoPadding) + Android KeystoreIosSecretStore — Keychain Services (kSecClassGenericPassword)DefaultSessionController — Gestión de sesión con StateFlow, persistencia en SecretStore, refresh configurableDefaultCredentialProvider — Lee credencial activa desde SessionController.state
Para el detalle completo de cada módulo (tablas Expone/NO expone, contratos internos, decisiones de diseño), consulta los READMEs de Módulos.
:sample-api ──▶ :network-core
:sample-api ──▶ :network-ktor ──▶ :network-core
:sample-api ──▶ :security-core
:network-ktor ──▶ :network-core
:network-ktor ──▶ :security-core
:network-ws-ktor ──▶ :network-ws-core
:network-ws-ktor ──▶ :security-core
:network-core ──▶ (ninguno)
:network-ws-core ──▶ (ninguno)
:security-core ──▶ (ninguno)
Invariante crítica: :network-core, :network-ws-core y :security-core tienen cero dependencia mutua. Esto es por diseño y debe preservarse.
El 95%+ del código vive en commonMain. Solo SecretStore (Android Keystore / iOS Keychain) y los engines de transporte HTTP (OkHttp / Darwin) requieren source sets de plataforma. Para más detalle, consulta la Estrategia KMP.
| Herramienta | Versión | Notas |
|---|---|---|
| Kotlin | 2.3.10 | Plugin Kotlin Multiplatform |
| Gradle | 9.3.1+ | Con catálogo de versiones (libs.versions.toml) |
| AGP | 9.1.0 | Usa plugin com.android.kotlin.multiplatform.library
|
| Android Studio | Ladybug o posterior | Requiere soporte KMP |
| Xcode | 15+ | Para compilación de target iOS |
Android compileSdk |
36 | |
Android minSdk |
29 | Android 10+ |
| Targets iOS |
iosX64, iosArm64, iosSimulatorArm64
|
| Librería | Versión | Módulo |
|---|---|---|
kotlinx-coroutines-core |
1.10.2 |
network-core, security-core
|
ktor-client-core |
3.4.2 | network-ktor |
ktor-client-okhttp |
3.4.2 |
network-ktor (Android) |
ktor-client-darwin |
3.4.2 |
network-ktor, network-ws-ktor (iOS) |
ktor-client-websockets |
3.4.2 | network-ws-ktor |
kotlinx-serialization-json |
1.10.0 |
sample-api (módulos de dominio) |
Para guías detalladas de integración, configuración y uso:
Para detalles técnicos de cada módulo (contratos, decisiones de diseño, extensibilidad, manejo de errores, seguridad):
Para diagramas de arquitectura, consulta el índice de diagramas.
| Tarea | Módulo | Estado |
|---|---|---|
Implementar AndroidSecretStore con DataStore + Cipher + KeyStore |
security-core |
✅ Completado |
Implementar IosSecretStore con Keychain Services |
security-core |
✅ Completado |
Implementar DefaultSessionController con StateFlow + almacenamiento de tokens |
security-core |
✅ Completado |
Implementar DefaultCredentialProvider respaldado por SessionController |
security-core |
✅ Completado |
RefreshOutcome sealed — migrar refreshSession() de Boolean a resultado tipado |
security-core |
✅ Completado |
SessionController.invalidate() + isAuthenticated — force-logout y conveniencia |
security-core |
✅ Completado |
CredentialProvider.refresh() + invalidate() — refresh proactivo e invalidación en 401 |
security-core |
✅ Completado |
| Tarea | Módulo | Estado |
|---|---|---|
LoggingObserver + NetworkLogger — logging del ciclo de vida de requests con sanitización |
network-core |
✅ Completado |
MetricsObserver + MetricsCollector — latencia, errores, retries con backend inyectable (NOOP default) |
network-core |
✅ Completado |
Tests de integración con Ktor MockEngine
|
network-ktor |
🔴 No iniciado |
Tests unitarios para DefaultSafeRequestExecutor
|
network-core |
🔴 No iniciado |
| Tarea | Módulo | Estado |
|---|---|---|
Certificate pinning vía TrustPolicy → OkHttp / Darwin TLS |
network-ktor |
✅ Completado |
| Interceptor de auth refresh (401 → refresh → retry) | Módulo puente | ✅ Habilitado por CredentialProvider.invalidate()
|
Logging de respuestas sanitizado con LogSanitizer
|
network-core (vía headerSanitizer lambda) |
✅ Completado |
| Tarea | Módulo | Estado |
|---|---|---|
Unificar Diagnostic en módulo :platform-common
|
Nuevo módulo | 🔴 No iniciado |
TracingObserver + TracingBackend — span/trace IDs con backend inyectable (NOOP default) |
network-core |
✅ Completado |
HttpEngine.healthCheck() — liveness probing (default true, implementado en KtorHttpEngine) |
network-core / network-ktor
|
✅ Completado |
SecretStore.keys() + putStringIfAbsent() — migración/diagnóstico y escritura atómica |
security-core |
✅ Completado |
| Cleanup de TODOs redundantes — reclasificación de logging/caching/circuit-breaker | Todos | ✅ Completado |
| Publicación en Maven Central | Todos | ✅ Completado (v0.4.0) |
| Política de reintento circuit breaker | network-core |
🔴 No iniciado |
| Soporte WebSocket con reconexión automática |
network-ws-core, network-ws-ktor
|
✅ Completado (v0.4.0) |
| Primer módulo de dominio en producción | Nuevo módulo | 🔴 No iniciado |
El SDK implementa guardrails de seguridad alineados al OWASP Mobile Application Security Verification Standard (MASVS).
Consulta docs/security-checklist.md para el checklist completo.
| Categoría MASVS | Guardrail | Módulo |
|---|---|---|
| NETWORK-1 — Solo HTTPS/WSS |
NetworkConfig rechaza http:// por defecto; WebSocketConfig rechaza ws:// por defecto |
network-core, network-ws-core
|
| NETWORK-2 — Certificate Pinning |
TrustPolicy → OkHttp / Darwin TLS |
network-ktor |
| STORAGE-1 — Almacenamiento seguro |
SecretStore → DataStore + Cipher + Keystore / Keychain |
security-core |
| STORAGE-2 — No secretos en logs |
toString() redactado en Credential, HttpRequest, RawResponse, SessionCredentials
|
security-core, network-core
|
| PRIVACY-1 — Header sanitization |
LoggingObserver redacta ALL headers por defecto |
network-core |
| PRIVACY-2 — Query params en observabilidad |
MetricsObserver / TracingObserver strip query params |
network-core |
| AUTH-1 — Credential lifecycle |
SessionController con invalidación, refresh, limpieza en logout |
security-core |
El camino seguro es el camino por defecto. Los guardrails están activos sin configuración. Desactivarlos requiere acción explícita (
allowInsecureConnections, sanitizer custom).
Estas son las invariantes arquitectónicas del proyecto. Todas las contribuciones deben respetarlas.
El API público nunca expone detalles de transporte.
Los consumidores ven HttpRequest, NetworkResult, NetworkError. Nunca io.ktor.*, okhttp3.*, ni NSURLSession.
network-core y security-core nunca deben depender el uno del otro.
Solo se integran a nivel del consumidor vía composición.
Excepción: network-ktor depende de security-core para configurar certificate pinning via TrustPolicy.
Los errores son valores, no excepciones.
NetworkResult.Failure envuelve NetworkError. Las excepciones se capturan en el límite del executor y se clasifican en tipos semánticos.
Diagnostic es interno. message es público.
error.message es seguro para usuarios finales. error.diagnostic es solo para logging y debugging.
Las decisiones de reintento pertenecen al modelo de error.
NetworkError.isRetryable determina la reintentabilidad. El executor no hardcodea qué errores reintentar.
Los interceptors son para infraestructura, no lógica de negocio. Headers de auth, contexto de tracing, logging — sí. Validación de órdenes, cálculo de precios — no.
DTOs y modelos de dominio siempre están separados.
Los DTOs tienen @Serializable y coinciden con el contrato del API. Los modelos de dominio son limpios y agnósticos del API.
El código específico de plataforma vive en los bordes.
Interfaces en commonMain. Implementaciones en androidMain/iosMain. Nunca al revés.
Cada componente principal es inyectable.
HttpEngine, ErrorClassifier, ResponseValidator, CredentialProvider, SecretStore — todas interfaces, todas inyectadas vía constructor.
Las nuevas funcionalidades son aditivas. Nuevos módulos, nuevos interceptors, nuevos observers, nuevos subtipos de error. Los contratos existentes son estables.
Core Data Platform — Construido para equipos que envían múltiples apps desde una base compartida.
| Módulo | Maven Central |
|---|---|
network-core |
|
network-ktor |
|
network-ws-core |
|
network-ws-ktor |
|
security-core |
|
sample-api |
SDK Kotlin Multiplatform para Acceso Remoto Seguro de Datos
Una librería Kotlin Multiplatform (KMP) reutilizable y modular diseñada para proveer una base segura, escalable y agnóstica de transporte para operaciones de datos remotos en aplicaciones Android e iOS.
data: estructura de carpetas, DTOs vs modelos de dominio, DataSource, Repository, DI, y referencias a escenarios avanzados// 1. Crea el repository (configuración por defecto incluida)
val repository = SampleApiFactory.create()
// 2. Llama un endpoint
val result: NetworkResult<List<User>> = repository.getUsers()
// 3. Maneja el resultado
result.fold(
onSuccess = { users ->
users.forEach { println("${it.displayName} (@${it.handle})") }
},
onFailure = { error ->
println("Error: ${error.message}")
}
)
SampleApiFactory.create()ensambla internamente todo el pipeline: configuración → engine HTTP → executor con reintentos → data source → repository. Tú solo interactúas conUserRepositoryyNetworkResult<User>.
Para configuración avanzada (auth, timeouts personalizados, interceptors), consulta la Guía de Integración o las guías rápidas para Android / iOS.
El SDK está publicado en Maven Central. Agrega los módulos que necesites en tu build.gradle.kts:
repositories {
mavenCentral()
}
dependencies {
// Contratos core (siempre requeridos)
implementation("io.github.dancrrdz93:network-core:0.4.0")
// Implementación de transporte HTTP (elige uno)
implementation("io.github.dancrrdz93:network-ktor:0.4.0")
// WebSocket (si necesitas conexiones persistentes bidireccionales)
implementation("io.github.dancrrdz93:network-ws-core:0.4.0")
implementation("io.github.dancrrdz93:network-ws-ktor:0.4.0")
// Seguridad (auth, almacenamiento seguro, gestión de sesiones)
implementation("io.github.dancrrdz93:security-core:0.4.0")
// Módulo de referencia (opcional — para ver el patrón de integración)
implementation("io.github.dancrrdz93:sample-api:0.4.0")
}Si el SDK se consume como módulo local (composite build), usa implementation(project(":network-core")) en su lugar.
Core Data Platform es un SDK interno construido con Kotlin Multiplatform que provee una base unificada, segura y extensible para hacer llamadas a APIs remotas desde aplicaciones móviles. Está diseñado para ser consumido por múltiples apps a gran escala sin acoplarlas a ningún cliente HTTP, librería de serialización o contrato de backend específico.
En organizaciones que mantienen múltiples aplicaciones móviles, cada equipo tiende a construir su propio stack de networking y seguridad. Esto lleva a:
Core Data Platform resuelve esto proveyendo una única base bien testeada y dirigida por contratos que todas las apps comparten, manteniendo cada app libre de definir su propia lógica de dominio, serialización y UI.
| Objetivo | Cómo se logra |
|---|---|
| Reutilizable | Contratos puros en network-core y security-core — sin lógica específica de app, sin suposiciones de backend |
| Desacoplado |
network-core tiene cero conocimiento de Ktor, OkHttp o cualquier librería HTTP. El transporte es pluggable vía HttpEngine
|
| Seguro | Abstracción de credenciales, almacenamiento seguro de plataforma, sanitización de logs, políticas de confianza TLS — todo como contratos de primera clase |
| Escalable | Nuevos módulos de dominio (pagos, fidelidad, etc.) se agregan sin modificar módulos core |
| Portable | Kotlin Multiplatform con contratos en commonMain e implementaciones de plataforma en androidMain/iosMain
|
| Mantenible | Interfaces pequeñas y enfocadas. Clases open para extensión. Tipos sealed para manejo exhaustivo. Sin God objects |
La arquitectura sigue tres principios fundamentales:
Contratos sobre implementaciones — Cada componente principal se define como una interfaz o clase abstracta en commonMain. Las implementaciones concretas se inyectan, nunca se hardcodean.
Separación por capas — El proyecto separa qué hace el SDK (contratos) de cómo lo hace (implementaciones) y quién lo usa (módulos de dominio).
Cero acoplamiento lateral — network-core y security-core son módulos completamente independientes. Ninguno sabe que el otro existe. Solo se componen en el punto de consumo (módulos de dominio o la app).
Estos módulos abordan preocupaciones fundamentalmente diferentes:
network-core responde: "¿Cómo ejecuto, valido, reintento y clasifico operaciones HTTP de forma segura?"
security-core responde: "¿Cómo almaceno secretos, gestiono sesiones, evalúo confianza y protejo datos sensibles?"
Mantenerlos independientes significa:
CredentialHeaderMapper) que vive en security-core y retorna un simple Map<String, String> — sin tipos de red requeridos.┌──────────────────────────────────────────────────────────────┐
│ YOUR APPLICATION │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Feature A│ │ Feature B│ │ Feature C│ ← App layers │
│ └────┬─────┘ └─────┬────┘ └──────┬───┘ │
│ │ │ │ │
│ ┌────▼──────────────▼──────────────▼────┐ │
│ │ Domain API Modules │ ← :payments-api │
│ │ (DTOs, Mappers, DataSources, Repos) │ :loyalty-api │
│ └────┬──────────────┬──────────────┬────┘ :users-api │
│ │ │ │ │
├────────┼──────────────┼──────────────┼───────────────────────┤
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌────────────┐ ┌──────────────┐ │
│ │ network │ │ network │ │ security │ ← SDK │
│ │ -core │ │ -ktor │ │ -core │ │
│ └──────────┘ └────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────────┘
Los módulos del SDK se sitúan en la parte inferior del grafo de dependencias. Las funcionalidades de la aplicación nunca importan Ktor, nunca ven RawResponse, y nunca manejan lógica de reintentos directamente.
| Módulo | Responsabilidad | Contratos clave | Dependencias |
|---|---|---|---|
:network-core |
Abstracciones puras de red: ejecución HTTP, errores, validación, reintentos, observabilidad |
HttpEngine, SafeRequestExecutor, NetworkResult<T>, NetworkError, NetworkEventObserver, LoggingObserver, NetworkLogger, RetryPolicy
|
Solo kotlinx-coroutines-core
|
:network-ktor |
Adaptador de transporte HTTP. Encapsula Ktor completamente |
KtorHttpEngine, KtorErrorClassifier
|
:network-core, ktor-client-core, ktor-client-okhttp (Android), ktor-client-darwin (iOS) |
:network-ws-core |
Abstracciones puras de WebSocket: conexión, reconexión, errores, observabilidad |
WebSocketEngine, SafeWebSocketExecutor, WebSocketConnection, WebSocketError, ReconnectPolicy, WebSocketEventObserver
|
Solo kotlinx-coroutines-core
|
:network-ws-ktor |
Adaptador de transporte WebSocket. Encapsula ktor-client-websockets completamente |
KtorWebSocketEngine, KtorWebSocketErrorClassifier
|
:network-ws-core, :security-core, ktor-client-core, ktor-client-websockets, ktor-client-okhttp (Android), ktor-client-darwin (iOS) |
:security-core |
Credenciales, sesiones, almacenamiento seguro, confianza TLS, sanitización de logs |
Credential, CredentialProvider, SessionController, SecretStore, TrustPolicy, LogSanitizer
|
Solo kotlinx-coroutines-core
|
:sample-api |
Módulo piloto de referencia: demuestra el patrón DTO → Mapper → DataSource → Repository → Factory |
UserDto, User, UserMapper, UserRemoteDataSource, UserRepository, SampleApiFactory
|
:network-core, :network-ktor, :security-core, kotlinx-serialization-json
|
Implementaciones de plataforma en :security-core:
AndroidSecretStore — DataStore + Cipher(AES/GCM/NoPadding) + Android KeystoreIosSecretStore — Keychain Services (kSecClassGenericPassword)DefaultSessionController — Gestión de sesión con StateFlow, persistencia en SecretStore, refresh configurableDefaultCredentialProvider — Lee credencial activa desde SessionController.state
Para el detalle completo de cada módulo (tablas Expone/NO expone, contratos internos, decisiones de diseño), consulta los READMEs de Módulos.
:sample-api ──▶ :network-core
:sample-api ──▶ :network-ktor ──▶ :network-core
:sample-api ──▶ :security-core
:network-ktor ──▶ :network-core
:network-ktor ──▶ :security-core
:network-ws-ktor ──▶ :network-ws-core
:network-ws-ktor ──▶ :security-core
:network-core ──▶ (ninguno)
:network-ws-core ──▶ (ninguno)
:security-core ──▶ (ninguno)
Invariante crítica: :network-core, :network-ws-core y :security-core tienen cero dependencia mutua. Esto es por diseño y debe preservarse.
El 95%+ del código vive en commonMain. Solo SecretStore (Android Keystore / iOS Keychain) y los engines de transporte HTTP (OkHttp / Darwin) requieren source sets de plataforma. Para más detalle, consulta la Estrategia KMP.
| Herramienta | Versión | Notas |
|---|---|---|
| Kotlin | 2.3.10 | Plugin Kotlin Multiplatform |
| Gradle | 9.3.1+ | Con catálogo de versiones (libs.versions.toml) |
| AGP | 9.1.0 | Usa plugin com.android.kotlin.multiplatform.library
|
| Android Studio | Ladybug o posterior | Requiere soporte KMP |
| Xcode | 15+ | Para compilación de target iOS |
Android compileSdk |
36 | |
Android minSdk |
29 | Android 10+ |
| Targets iOS |
iosX64, iosArm64, iosSimulatorArm64
|
| Librería | Versión | Módulo |
|---|---|---|
kotlinx-coroutines-core |
1.10.2 |
network-core, security-core
|
ktor-client-core |
3.4.2 | network-ktor |
ktor-client-okhttp |
3.4.2 |
network-ktor (Android) |
ktor-client-darwin |
3.4.2 |
network-ktor, network-ws-ktor (iOS) |
ktor-client-websockets |
3.4.2 | network-ws-ktor |
kotlinx-serialization-json |
1.10.0 |
sample-api (módulos de dominio) |
Para guías detalladas de integración, configuración y uso:
Para detalles técnicos de cada módulo (contratos, decisiones de diseño, extensibilidad, manejo de errores, seguridad):
Para diagramas de arquitectura, consulta el índice de diagramas.
| Tarea | Módulo | Estado |
|---|---|---|
Implementar AndroidSecretStore con DataStore + Cipher + KeyStore |
security-core |
✅ Completado |
Implementar IosSecretStore con Keychain Services |
security-core |
✅ Completado |
Implementar DefaultSessionController con StateFlow + almacenamiento de tokens |
security-core |
✅ Completado |
Implementar DefaultCredentialProvider respaldado por SessionController |
security-core |
✅ Completado |
RefreshOutcome sealed — migrar refreshSession() de Boolean a resultado tipado |
security-core |
✅ Completado |
SessionController.invalidate() + isAuthenticated — force-logout y conveniencia |
security-core |
✅ Completado |
CredentialProvider.refresh() + invalidate() — refresh proactivo e invalidación en 401 |
security-core |
✅ Completado |
| Tarea | Módulo | Estado |
|---|---|---|
LoggingObserver + NetworkLogger — logging del ciclo de vida de requests con sanitización |
network-core |
✅ Completado |
MetricsObserver + MetricsCollector — latencia, errores, retries con backend inyectable (NOOP default) |
network-core |
✅ Completado |
Tests de integración con Ktor MockEngine
|
network-ktor |
🔴 No iniciado |
Tests unitarios para DefaultSafeRequestExecutor
|
network-core |
🔴 No iniciado |
| Tarea | Módulo | Estado |
|---|---|---|
Certificate pinning vía TrustPolicy → OkHttp / Darwin TLS |
network-ktor |
✅ Completado |
| Interceptor de auth refresh (401 → refresh → retry) | Módulo puente | ✅ Habilitado por CredentialProvider.invalidate()
|
Logging de respuestas sanitizado con LogSanitizer
|
network-core (vía headerSanitizer lambda) |
✅ Completado |
| Tarea | Módulo | Estado |
|---|---|---|
Unificar Diagnostic en módulo :platform-common
|
Nuevo módulo | 🔴 No iniciado |
TracingObserver + TracingBackend — span/trace IDs con backend inyectable (NOOP default) |
network-core |
✅ Completado |
HttpEngine.healthCheck() — liveness probing (default true, implementado en KtorHttpEngine) |
network-core / network-ktor
|
✅ Completado |
SecretStore.keys() + putStringIfAbsent() — migración/diagnóstico y escritura atómica |
security-core |
✅ Completado |
| Cleanup de TODOs redundantes — reclasificación de logging/caching/circuit-breaker | Todos | ✅ Completado |
| Publicación en Maven Central | Todos | ✅ Completado (v0.4.0) |
| Política de reintento circuit breaker | network-core |
🔴 No iniciado |
| Soporte WebSocket con reconexión automática |
network-ws-core, network-ws-ktor
|
✅ Completado (v0.4.0) |
| Primer módulo de dominio en producción | Nuevo módulo | 🔴 No iniciado |
El SDK implementa guardrails de seguridad alineados al OWASP Mobile Application Security Verification Standard (MASVS).
Consulta docs/security-checklist.md para el checklist completo.
| Categoría MASVS | Guardrail | Módulo |
|---|---|---|
| NETWORK-1 — Solo HTTPS/WSS |
NetworkConfig rechaza http:// por defecto; WebSocketConfig rechaza ws:// por defecto |
network-core, network-ws-core
|
| NETWORK-2 — Certificate Pinning |
TrustPolicy → OkHttp / Darwin TLS |
network-ktor |
| STORAGE-1 — Almacenamiento seguro |
SecretStore → DataStore + Cipher + Keystore / Keychain |
security-core |
| STORAGE-2 — No secretos en logs |
toString() redactado en Credential, HttpRequest, RawResponse, SessionCredentials
|
security-core, network-core
|
| PRIVACY-1 — Header sanitization |
LoggingObserver redacta ALL headers por defecto |
network-core |
| PRIVACY-2 — Query params en observabilidad |
MetricsObserver / TracingObserver strip query params |
network-core |
| AUTH-1 — Credential lifecycle |
SessionController con invalidación, refresh, limpieza en logout |
security-core |
El camino seguro es el camino por defecto. Los guardrails están activos sin configuración. Desactivarlos requiere acción explícita (
allowInsecureConnections, sanitizer custom).
Estas son las invariantes arquitectónicas del proyecto. Todas las contribuciones deben respetarlas.
El API público nunca expone detalles de transporte.
Los consumidores ven HttpRequest, NetworkResult, NetworkError. Nunca io.ktor.*, okhttp3.*, ni NSURLSession.
network-core y security-core nunca deben depender el uno del otro.
Solo se integran a nivel del consumidor vía composición.
Excepción: network-ktor depende de security-core para configurar certificate pinning via TrustPolicy.
Los errores son valores, no excepciones.
NetworkResult.Failure envuelve NetworkError. Las excepciones se capturan en el límite del executor y se clasifican en tipos semánticos.
Diagnostic es interno. message es público.
error.message es seguro para usuarios finales. error.diagnostic es solo para logging y debugging.
Las decisiones de reintento pertenecen al modelo de error.
NetworkError.isRetryable determina la reintentabilidad. El executor no hardcodea qué errores reintentar.
Los interceptors son para infraestructura, no lógica de negocio. Headers de auth, contexto de tracing, logging — sí. Validación de órdenes, cálculo de precios — no.
DTOs y modelos de dominio siempre están separados.
Los DTOs tienen @Serializable y coinciden con el contrato del API. Los modelos de dominio son limpios y agnósticos del API.
El código específico de plataforma vive en los bordes.
Interfaces en commonMain. Implementaciones en androidMain/iosMain. Nunca al revés.
Cada componente principal es inyectable.
HttpEngine, ErrorClassifier, ResponseValidator, CredentialProvider, SecretStore — todas interfaces, todas inyectadas vía constructor.
Las nuevas funcionalidades son aditivas. Nuevos módulos, nuevos interceptors, nuevos observers, nuevos subtipos de error. Los contratos existentes son estables.
Core Data Platform — Construido para equipos que envían múltiples apps desde una base compartida.