---
name: "source-command-align"
description: "Dallyrun 멀티모듈 MVI 아키텍처 정렬 점검"
---

# source-command-align

Use this skill when the user asks to run the migrated source command `align`.

## Command Template

# Architecture Alignment

새 파일을 만들거나 기존 파일을 리팩터링하기 전에 아래 체크리스트로 **모듈 경계·계층 책임·의존 방향**을 검증한다. 어긋나면 작업을 멈추고 사용자에게 어디에 두는 게 맞는지 먼저 합의한다.

## 1. 모듈 경계 (Domain Isolation)

이 로직이 어떤 모듈에 속하는지 먼저 결정한다.

### Feature 모듈 (`feature:<name>`)

화면 단위 기능. UI · ViewModel · Navigation 만 들어간다.

- 기존 feature 의 확장인가? → `feature/<name>/` 안에 둔다.
- 새 화면인가? → `/new-feature <name>` 으로 스캐폴딩 후 시작.
- **두 feature 가 서로 직접 import 하면 안 된다.** 공유가 필요하면 `core:*` 로 끌어올린다.

### Core 모듈 (`core:<name>`)

여러 feature 에서 공유되는 기반.

| 모듈 | 들어가는 것 | 들어가면 안 되는 것 |
|---|---|---|
| `core:model` | 순수 도메인 모델 (data class, sealed, value class) | Android 의존, 어노테이션 (`@Serializable` 등 네트워크 전용도 금지) |
| `core:domain` | UseCase, Repository **인터페이스** | Repository 구현, Retrofit/Room |
| `core:data` | Repository **구현**, DataStore, 토큰 저장소 | Compose UI, ViewModel |
| `core:network` | Retrofit API, DTO, `toDomain()` 매퍼, Auth 인터셉터/인증기 | UseCase, Repository 구현 |
| `core:database` | Room DAO/Entity, PagingSource DAO, 로컬 캐시, schema 관리 | 네트워크, UI |
| `core:designsystem` | Material3 theme, 색상/타이포 토큰 | 비즈니스 도메인 모델 |
| `core:ui` | feature 간 재사용되는 Compose 컴포넌트 | feature 특화 화면, ViewModel |
| `core:common` | `DallyrunViewModel`, `UiState`, `UiEvent`, `SideEffect` MVI base | 도메인 로직, Repository |
| `core:testing` | `MainDispatcherRule`, `TestData`, MockK/Turbine re-export | 프로덕션 코드 |

> 새 core 모듈이 필요한지부터 의심하라 — 대부분은 기존 모듈 안에 자리가 있다. 새 모듈 추가는 별도 PR 로 분리.

## 2. 계층 책임 (Layered Responsibility)

MVI · Clean Architecture 기준 계층별 책임.

| 파일 | 책임 | 금지 |
|---|---|---|
| `*Screen.kt` | stateless Composable. state 를 파라미터로 받고 이벤트는 `(Event) -> Unit` 으로 위임 | ViewModel 직접 호출, 비즈니스 로직, suspend 호출 |
| `*Route.kt` | `viewModel()` 주입, `collectAsStateWithLifecycle()`, SideEffect 수집 | UI 그리기 (Screen 에 위임) |
| `*ViewModel.kt` | UI state 관리, `onEvent()` 핸들링, UseCase 호출 | Retrofit/Room 직접 호출, Compose 의존, `Dispatchers.IO` 직접 사용 (UseCase 가 main-safe) |
| `*Contract.kt` | `UiState`, `UiEvent`, `SideEffect` 정의 | 로직 |
| `*Navigation.kt` | type-safe Navigation route + `navGraphBuilder.<feature>()` 확장 | 라우트 외 로직 |
| `*UseCase.kt` (`core:domain`) | 단일 비즈니스 동작, Repository 조합 | UI/Compose, DTO |
| `*Repository.kt` 인터페이스 (`core:domain`) | 도메인 모델만 노출 | DTO, Retrofit 타입 |
| `*RepositoryImpl.kt` (`core:data`) | DTO ↔ Domain 매핑, 네트워크/DB 조합, suspend main-safe | UI |
| `*Api.kt` (`core:network`) | Retrofit suspend 함수 | 매핑, 비즈니스 로직 |
| `Network*.kt` DTO (`core:network`) | `@Serializable` DTO + `toDomain()` | 비즈니스 동작 |

## 3. 의존 방향 (Dependency Rule)

```
feature:* ──► core:domain ──► core:model
    │            ▲
    ├──► core:common, core:designsystem, core:ui
    └──► (테스트) core:testing

core:data ──► core:domain, core:model, core:network, core:database
core:database ──► core:model
core:network ──► core:model
core:ui ──► core:designsystem, core:model
```

**금지:**
- `core:model` 이 다른 무언가에 의존 (Android, 어노테이션 라이브러리 포함)
- `core:domain` 이 `core:data` / `core:network` 에 의존 (인터페이스만 정의, 구현은 data 가 책임)
- `feature:*` 간 직접 의존
- `core:*` 모듈 간 순환 의존
- `core:designsystem` 이 도메인 모듈에 의존

새 모듈 의존이 추가되면 `core/AGENTS.md` 의 의존성 다이어그램과 `core` 모듈 표도 같이 업데이트.

## 4. MVI 컨벤션

- ViewModel 은 `DallyrunViewModel<UiState, UiEvent, SideEffect>` 를 상속.
- 상태 변경은 `MutableStateFlow.update { it.copy(...) }`. `value = ` 직접 대입 금지.
- Side effect (네비게이션, 토스트, 토큰 만료 알림 등) 는 `Channel` / `SharedFlow` 로 emit, Route 에서 수집.
- `_uiState` (private MutableStateFlow) ↔ `uiState` (public StateFlow) backing property 패턴.
- `viewModelScope` 외 스코프 사용 금지. UseCase 가 `withContext(Dispatchers.IO)` 로 main-safe 보장.

## 5. 참고 문서

| 문서 | 무엇이 있나 |
|---|---|
| `AGENTS.md` (루트) | Module Structure, Convention Plugins, Coding Conventions |
| `core/AGENTS.md` | core 모듈 의존 규칙, Auth/Network 패턴, testing 사용법 |
| `feature/AGENTS.md` | feature 모듈 작성 규칙 (있다면) |
| `.codex/docs/VALIDATION.md` | 변경 유형별 Validation gate |
| `.codex/docs/TROUBLESHOOTING.md` | 과거 트러블슈팅·트레이드오프·성능 결정 |

## 실행 절차

1. 변경하려는 코드가 위 체크리스트 중 어느 항목과 맞닿는지 먼저 식별.
2. 어긋남이 있으면 **사용자에게 옮겨야 할 위치를 제안**하고 합의 후 진행.
3. 새 모듈/계층/의존이 생기면 관련 `AGENTS.md` 동기 업데이트를 같은 PR 에 포함.
4. 작업 종료 시 `scripts/verify-change.sh` 또는 `/check` 로 Validation gate 통과 확인.
