write-feature

star 1.6k

Use when adding a new feature to Alkaa end-to-end — from domain models through data layer, Koin DI, and up to presentation. Triggers on tasks like "add a new feature", "create [feature] feature", "implement [feature] functionality", or "add [feature] to the app".

igorescodro By igorescodro schedule Updated 3/28/2026

name: write-feature description: Use when adding a new feature to Alkaa end-to-end — from domain models through data layer, Koin DI, and up to presentation. Triggers on tasks like "add a new feature", "create [feature] feature", "implement [feature] functionality", or "add [feature] to the app".

Write Feature

Overview

A complete Alkaa feature spans five layers: domain models → repository interface → data implementation → Koin DI → presentation. Each layer has strict conventions. This skill guides you through all five in order.

Before starting: Use superpowers:brainstorming to align on scope and API design. Use superpowers:writing-plans if the feature is large.

Phases

  1. Domain Layer — Domain model, repository interface, use case interface + impl → see references/DOMAIN_LAYER.md
  2. Data Layer — Repository mapper + RepositoryImpl → see references/DATA_LAYER.md
    • If the feature needs a new database table, invoke the write-local-datasource skill first
  3. Koin DI — Feature module, RepositoryModule, KoinHelper registration → see references/KOIN_DI.md
  4. Presentation — ViewModel, Composables, Navigation, strings → see delegation below
  5. Tests — Unit, UI, E2E → see delegation below

Rules

Rule Details
Use cases are internal internal visibility — never public
One use case = one action Never inject another ViewModel or feature module directly
Flow vs. suspend Flow<T> for streams; suspend fun for one-shot mutations. No Result<T> wrapping
Mappers required Never return the entity directly — local ↔ repo ↔ domain separation is required
ViewModels inject use cases Never inject repositories into ViewModels
Register in KoinHelper immediately Missing registration causes silent runtime crashes
API module only when shared Only create <name>-api when another feature depends on this one → see references/FEATURE_API_MODULE.md
Interactors for cross-feature side effects When a use case must trigger an action in another feature, define an Interactor interface in domain/interactor/ — never import the feature directly → see references/INTERACTOR.md

Phase 4: Presentation

  • ViewModel → use write-viewmodel skill
  • Composables + Screens → use write-composable skill
  • Navigation → use navigation skill
  • Strings → use localization skill
  • New Kuvio component needed → use write-design-system-component skill before implementing the composable

Phase 5: Tests

  • Use case / ViewModel unit tests → use write-unit-tests skill
  • UI / composable tests → use write-ui-tests skill
  • End-to-end flow tests → use write-e2e-tests skill

Common Mistakes

Mistake Fix
suspend fun for a stream Use Flow<T> for streams; suspend only for one-shot mutations
Wrapping return values in Result<T> Don't — exceptions propagate through Flow
One use case doing two things Create separate use cases
Skipping the mapper Local ↔ repo ↔ domain separation is required
Injecting a repository into the ViewModel ViewModels inject use cases only
Feature depending directly on another feature Create a <name>-api module
Registering in KoinHelper after the feature works Register immediately — silent runtime crashes
Reusing the domain model as the view model Keep them separate — UI concerns must not bleed into domain
Importing a feature module directly into a use case Define an Interactor interface in domain/interactor/ instead → see references/INTERACTOR.md
Install via CLI
npx skills add https://github.com/igorescodro/alkaa --skill write-feature
Repository Details
star Stars 1,633
call_split Forks 162
navigation Branch main
article Path SKILL.md
More from Creator