WCAG 2.2 AA compliance, ARIA patterns, keyboard navigation, screen reader optimization
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Coroutine patterns, Flow operators, Jetpack Compose state management, Ktor routing, and Kotlin Multiplatform shared code.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
Modern Kotlin patterns for Android, server-side, and multiplatform development.
import kotlinx.coroutines.*
// Structured concurrency: child failures cancel siblings
suspend fun loadDashboard(): Dashboard = coroutineScope {
val profile = async { api.fetchProfile() }
val orders = async { api.fetchRecentOrders() }
val stats = async { api.fetchStats() }
// All run concurrently; if one fails, others are cancelled
Dashboard(
profile = profile.await(),
orders = orders.await(),
stats = stats.await()
)
}
// SupervisorScope: child failures don't cancel siblings
suspend fun loadOptionalData(): HomeScreen = supervisorScope {
val required = async { api.fetchRequiredData() }
val optional = async {
try { api.fetchRecommendations() }
catch (e: Exception) { emptyList() } // Graceful fallback
}
HomeScreen(
data = required.await(),
recommendations = optional.await()
)
}
// Retry with exponential backoff
suspend fun <T> retryWithBackoff(
maxRetries: Int = 3,
initialDelayMs: Long = 1000,
factor: Double = 2.0,
block: suspend () -> T
): T {
var currentDelay = initialDelayMs
repeat(maxRetries - 1) { attempt ->
try {
return block()
} catch (e: Exception) {
if (e is CancellationException) throw e // Never swallow cancellation
delay(currentDelay)
currentDelay = (currentDelay * factor).toLong()
}
}
return block() // Last attempt, let exception propagate
}
import kotlinx.coroutines.flow.*
// Repository pattern with Flow
class OrderRepository(private val api: OrderApi, private val db: OrderDao) {
// Offline-first: emit cached, then fetch fresh
fun getOrders(): Flow<List<Order>> = flow {
// Emit cached data first
emit(db.getAllOrders())
// Fetch fresh data
val fresh = api.fetchOrders()
db.insertAll(fresh)
emit(fresh)
}.catch { e ->
// On network error, emit cached data
emit(db.getAllOrders())
}
// Debounce search input
fun search(queryFlow: Flow<String>): Flow<List<Order>> =
queryFlow
.debounce(300)
.distinctUntilChanged()
.filter { it.length >= 2 }
.flatMapLatest { query ->
flow { emit(api.search(query)) }
.catch { emit(emptyList()) }
}
// Combine multiple flows
fun getDashboard(): Flow<DashboardState> =
combine(
getOrders(),
getStats(),
getNotifications()
) { orders, stats, notifications ->
DashboardState(orders, stats, notifications)
}
}
// StateFlow for UI state (hot flow, always has value)
class OrderViewModel(private val repo: OrderRepository) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
init {
viewModelScope.launch {
repo.getOrders()
.map { orders -> UiState.Success(orders) as UiState }
.catch { emit(UiState.Error(it.message ?: "Unknown error")) }
.collect { _uiState.value = it }
}
}
sealed interface UiState {
data object Loading : UiState
data class Success(val orders: List<Order>) : UiState
data class Error(val message: String) : UiState
}
}
@Composable
fun OrderListScreen(viewModel: OrderViewModel = viewModel()) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
when (val state = uiState) {
is UiState.Loading -> LoadingIndicator()
is UiState.Error -> ErrorMessage(state.message) { viewModel.retry() }
is UiState.Success -> OrderList(
orders = state.orders,
onOrderClick = { viewModel.selectOrder(it) },
onDelete = { viewModel.deleteOrder(it) }
)
}
}
// Stateless composable with hoisted state
@Composable
fun OrderList(
orders: List<Order>,
onOrderClick: (Order) -> Unit,
onDelete: (Order) -> Unit,
modifier: Modifier = Modifier
) {
LazyColumn(modifier = modifier) {
items(orders, key = { it.id }) { order ->
OrderItem(
order = order,
onClick = { onOrderClick(order) },
onDelete = { onDelete(order) },
modifier = Modifier.animateItem()
)
}
}
}
// Remember expensive computation
@Composable
fun FilteredOrders(orders: List<Order>, filter: String) {
val filtered = remember(orders, filter) {
orders.filter { it.status.name.contains(filter, ignoreCase = true) }
}
OrderList(orders = filtered, onOrderClick = {}, onDelete = {})
}
import io.ktor.server.application.*
import io.ktor.server.routing.*
import io.ktor.server.response.*
import io.ktor.server.request.*
import io.ktor.http.*
fun Application.configureRouting() {
routing {
route("/api/v1") {
// Middleware: auth check for all routes under /api/v1
install(AuthPlugin)
route("/orders") {
get {
val page = call.parameters["page"]?.toIntOrNull() ?: 1
val limit = call.parameters["limit"]?.toIntOrNull()?.coerceIn(1, 100) ?: 20
val orders = orderService.findAll(page, limit)
call.respond(ApiResponse.success(orders))
}
get("/{id}") {
val id = call.parameters["id"]
?: return@get call.respond(HttpStatusCode.BadRequest, "Missing ID")
val order = orderService.findById(id)
?: return@get call.respond(HttpStatusCode.NotFound)
call.respond(ApiResponse.success(order))
}
post {
val input = call.receive<CreateOrderInput>()
val validated = input.validate()
?: return@post call.respond(HttpStatusCode.BadRequest, "Invalid input")
val order = orderService.create(validated)
call.respond(HttpStatusCode.Created, ApiResponse.success(order))
}
}
}
}
}
// Typed API response wrapper
@Serializable
data class ApiResponse<T>(
val success: Boolean,
val data: T? = null,
val error: String? = null
) {
companion object {
fun <T> success(data: T) = ApiResponse(success = true, data = data)
fun error(message: String) = ApiResponse<Nothing>(success = false, error = message)
}
}
// shared/src/commonMain/kotlin
expect class PlatformContext
// Repository shared between Android/iOS
class SharedOrderRepository(
private val httpClient: HttpClient,
private val database: SharedDatabase
) {
suspend fun getOrders(): List<Order> {
return try {
val remote = httpClient.get("https://api.example.com/orders").body<List<Order>>()
database.orderDao().insertAll(remote)
remote
} catch (e: Exception) {
database.orderDao().getAll() // Offline fallback
}
}
}
// shared/src/androidMain/kotlin
actual class PlatformContext(val context: android.content.Context)
// shared/src/iosMain/kotlin
actual class PlatformContext
key parameter in LazyColumn items for stable identity아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
WCAG 2.2 AA compliance, ARIA patterns, keyboard navigation, screen reader optimization
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
axe-core integration, WCAG 2.2 AA checklist, keyboard navigation testing, screen reader testing, and ARIA pattern validation.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Steam-style achievement system with XP, levels, streaks, and skill trees. Gamifies the development workflow. 25 achievements across 5 categories.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Framework for measuring and tracking agent response quality over time. Detects regressions before they reach production. Use when evaluating agent changes, auditing quality, or establishing performance baselines.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Agent Context Isolation
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Agent ve skill dosyalarinin yapisal dogrulamasi. Frontmatter kontrol, naming convention, zorunlu bolum kontrolu, tutarlilik denetimi. Yeni agent/skill eklendiginde veya mevcut dosyalar duzenlediginde otomatik calistirilir.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.