Files
New-planet-app/CLAUDE.md
2025-12-13 15:05:17 +03:00

412 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md — Новая Планета (Android)
> Справочная информация для AI-ассистента о проекте **Новая Планета**
---
## 🎯 О проекте
**Новая Планета** — Android-приложение для помощи детям с расстройством аутистического спектра (РАС) через:
- 📅 Визуальные расписания (день/неделя)
- ⏱️ Визуальный таймер (круговой с цветовой индикацией)
- 🎁 Систему наград за выполненные задания
- 🌍 ИИ-агента "Земля" для ответов и генерации расписаний
- 📚 Библиотеку изображений
- 👨‍👩‍👧 Роли: ребёнок, родитель, педагог
**Важно:** Приложение должно следовать принципам доступности (accessibility) для людей с РАС — высокая контрастность, крупные элементы, простые иконки.
---
## 🏗️ Архитектура
### Clean Architecture + MVVM
Проект использует **Clean Architecture** с разделением на 3 слоя:
```
com.novayaplaneta/
├── domain/ # Бизнес-логика (не зависит от Android)
│ ├── model/ # Доменные модели
│ ├── repository/ # Интерфейсы репозиториев
│ └── usecase/ # Use cases (бизнес-правила)
├── data/ # Реализация источников данных
│ ├── local/ # Room (Entity, DAO, Database)
│ ├── remote/ # Retrofit (DTO, API)
│ └── repository/ # Реализации репозиториев
└── ui/ # Presentation Layer (Jetpack Compose)
├── screens/ # Экраны (Screen + ViewModel)
├── components/ # Переиспользуемые UI-компоненты
├── navigation/ # Навигация
└── theme/ # Тема и стили
```
### Принципы:
1. **Dependency Rule**: Внутренние слои не зависят от внешних
- `domain` не знает о `data` и `ui`
- `data` зависит от `domain` (реализует интерфейсы)
- `ui` зависит от `domain` (использует модели и use cases)
2. **MVVM**: ViewModel связывает UI и бизнес-логику
- ViewModel получает данные через Use Cases
- UI наблюдает за StateFlow/LiveData в ViewModel
- ViewModel не знает о Compose напрямую
3. **Offline-first**: Room — основной источник данных, Retrofit — для синхронизации
---
## 📦 Технологический стек
### Язык и платформа
- **Kotlin** 2.0.21
- **Android SDK**: compileSdk 36, targetSdk 36, minSdk 26
- **JDK** 17
### UI
- **Jetpack Compose** (BOM 2024.09.00)
- **Material Design 3**
- **Navigation Component** (Compose)
### Архитектурные компоненты
- **Hilt** 2.53 — Dependency Injection
- **KSP** 2.0.21-1.0.25 — для кодогенерации (Room, Hilt)
- **Lifecycle ViewModel Compose** — интеграция ViewModel с Compose
- **Coroutines + Flow** — асинхронность
### Data
- **Room** 2.6.1 — локальная БД (offline-first)
- **Retrofit** 2.11.0 — REST API
- **OkHttp** 4.12.0 — HTTP клиент
- **Kotlinx Serialization** — JSON сериализация
### Другие библиотеки
- **Coil** 2.7.0 — загрузка изображений
- **Lottie** 6.1.0 — анимации
---
## 📂 Структура пакетов
### Domain Layer (`domain/`)
#### `domain/model/`
Доменные модели (data classes), не зависят от Android/фреймворков:
- `User.kt` — пользователь с ролями (CHILD, PARENT, TEACHER)
- `Schedule.kt` — расписание с задачами
- `Task.kt` — задача/задание
- `Reward.kt` — награда
- `ChatMessage.kt` — сообщение от ИИ
#### `domain/repository/`
Интерфейсы репозиториев (без реализации):
- `AuthRepository` — аутентификация
- `ScheduleRepository` — работа с расписаниями
- `TaskRepository` — работа с задачами
- `RewardRepository` — работа с наградами
- `AIRepository` — взаимодействие с ИИ
#### `domain/usecase/`
Use Cases — инкапсулируют бизнес-логику:
- `GetSchedulesUseCase` — получение расписаний
- `CreateScheduleUseCase` — создание расписания
- `CompleteTaskUseCase` — завершение задачи
- `SendAIMessageUseCase` — отправка сообщения ИИ
**Правило:** Use Case принимает интерфейсы репозиториев через конструктор (DI).
---
### Data Layer (`data/`)
#### `data/local/`
**Room Database:**
- `entity/` — Room entities (таблицы БД)
- Используют Long для timestamps (вместо LocalDateTime)
- Префикс `Entity` (например, `UserEntity`)
- `dao/` — Data Access Objects (запросы к БД)
- Используют Flow для реактивных данных
- Префикс `Dao` (например, `UserDao`)
- `mapper/` — мапперы между Entity ↔ Domain
- Extension functions: `toDomain()`, `toEntity()`
- Пример: `UserMapper.kt`, `ScheduleMapper.kt`
- `NewPlanetDatabase.kt` — главный класс Room Database
#### `data/remote/`
**Retrofit API:**
- `BackendApi.kt` — интерфейс Retrofit с эндпоинтами
- Base URL: `https://api.novayaplaneta.ru/`
- Использует Kotlinx Serialization
- `dto/` — Data Transfer Objects (DTO) для API
- Префикс `Request`/`Response` (например, `LoginRequest`, `LoginResponse`)
- Используют `@Serializable` из kotlinx.serialization
#### `data/repository/`
Реализации репозиториев:
- `AuthRepositoryImpl` — реализует `AuthRepository`
- `ScheduleRepositoryImpl` — реализует `ScheduleRepository`
- `TaskRepositoryImpl` — реализует `TaskRepository`
- `RewardRepositoryImpl` — реализует `RewardRepository`
- `AIRepositoryImpl` — реализует `AIRepository`
**Правило:**
- Репозиторий объединяет данные из Room (local) и Retrofit (remote)
- Использует мапперы для конвертации Entity → Domain
- Отдает Flow из Room для реактивности
---
### UI Layer (`ui/`)
#### `ui/screens/`
Экраны организованы по функциональности:
- `schedule/``ScheduleScreen.kt` + `ScheduleViewModel.kt`
- `task/``TaskScreen.kt` + `TaskViewModel.kt`
- `timer/``TimerScreen.kt` + `TimerViewModel.kt`
- `rewards/``RewardsScreen.kt` + `RewardsViewModel.kt`
- `ai/``AIScreen.kt` + `AIViewModel.kt`
- `settings/``SettingsScreen.kt` + `SettingsViewModel.kt`
**Правило:**
- Каждый экран — это `@Composable` функция с `Scaffold`
- ViewModel инжектируется через `hiltViewModel()`
- UI State хранится в `StateFlow` в ViewModel
- Экран наблюдает за UI State через `collectAsState()`
#### `ui/components/`
Переиспользуемые UI-компоненты:
- `BottomNavigation.kt` — нижняя навигационная панель с 6 пунктами
#### `ui/navigation/`
- `NewPlanetNavigation.kt` — NavHost с маршрутами
#### `ui/theme/`
- `Color.kt` — цвета темы (высокая контрастность для РАС)
- `Theme.kt` — Material3 тема (Light/Dark)
- `Type.kt` — типографика
---
### DI (`di/`)
Hilt модули:
- `DatabaseModule.kt` — предоставляет Room Database и DAOs
- `NetworkModule.kt` — предоставляет Retrofit и OkHttp
- `RepositoryModule.kt` — привязывает интерфейсы к реализациям (`@Binds`)
**Правило:**
- Все модули используют `@InstallIn(SingletonComponent::class)`
- Используется KSP для кодогенерации (не KAPT)
---
## 🎨 Дизайн и доступность
### Принципы доступности (РАС)
1. **Крупные элементы** — минимум 48dp для кликабельных областей
2. **Высокая контрастность** — WCAG AAA стандарт
3. **Простые иконки** — понятные, без лишних деталей
4. **Цветовое кодирование** — состояния имеют разные цвета
5. **Плавные анимации** — без мигания и резких переходов
### Цветовая схема
**Светлая тема:**
- Фон: `#FFFFFF`, `#F5F5F5`
- Текст: `#0A0A0A`
- Акценты: `#4CAF50` (зеленый), `#FF6B35` (оранжевый)
**Тёмная тема:**
- Фон: `#0A0A0A`
- Текст: `#FFFFFF`
- Акценты: `#4CAF50` (зеленый), `#FFD700` (золотой)
### Типографика
Используется Material3 Typography с настройками для читаемости (крупные размеры, хороший межстрочный интервал).
---
## 💻 Соглашения о коде
### Именование
- **Классы/Interfaces**: PascalCase (`ScheduleRepository`, `UserEntity`)
- **Функции/Переменные**: camelCase (`getSchedules`, `uiState`)
- **Константы**: UPPER_SNAKE_CASE (если нужны)
- **Пакеты**: lowercase (без подчеркиваний)
### Файлы
- Один класс/интерфейс = один файл
- Имя файла = имя класса
- Для Extension functions: имя файла описывает назначение (например, `UserMapper.kt`)
### ViewModel
```kotlin
@HiltViewModel
class ScheduleViewModel @Inject constructor(
private val getSchedulesUseCase: GetSchedulesUseCase
) : ViewModel() {
private val _uiState = MutableStateFlow(ScheduleUiState())
val uiState: StateFlow<ScheduleUiState> = _uiState.asStateFlow()
fun loadSchedules(userId: String) { /* ... */ }
}
data class ScheduleUiState(
val schedules: List<Schedule> = emptyList(),
val isLoading: Boolean = false
)
```
### Composable Screen
```kotlin
@Composable
fun ScheduleScreen(
viewModel: ScheduleViewModel = hiltViewModel(),
modifier: Modifier = Modifier
) {
val uiState by viewModel.uiState.collectAsState()
Scaffold(topBar = { /* ... */ }) { paddingValues ->
// UI content
}
}
```
### Repository
```kotlin
class ScheduleRepositoryImpl @Inject constructor(
private val scheduleDao: ScheduleDao,
private val taskDao: TaskDao
) : ScheduleRepository {
override fun getSchedules(userId: String): Flow<List<Schedule>> {
return scheduleDao.getSchedulesByUserId(userId).map { /* ... */ }
}
}
```
---
## 🔌 API и сеть
### Backend API
- **Base URL**: `https://api.novayaplaneta.ru/`
- **Аутентификация**: Bearer Token в заголовке `Authorization`
- **Формат**: JSON (Kotlinx Serialization)
### Эндпоинты (примеры)
```kotlin
@POST("api/v1/auth/login")
suspend fun login(@Body request: LoginRequest): Response<LoginResponse>
@POST("api/v1/ai/chat")
suspend fun chatWithAI(
@Header("Authorization") token: String,
@Body request: ChatRequest
): Response<ChatResponse>
```
### Обработка ошибок
- Используется `Result<T>` для обработки успешных/ошибочных результатов
- Локальные ошибки логируются, сетевые ошибки показываются пользователю
---
## 💾 База данных (Room)
### Стратегия
- **Offline-first**: данные сначала сохраняются в Room
- **Синхронизация**: периодическая синхронизация с сервером
- **Flow**: все запросы возвращают `Flow` для реактивности
### Entity → Domain Mapping
Используются extension functions:
```kotlin
fun UserEntity.toDomain(): User { /* ... */ }
fun User.toEntity(): UserEntity { /* ... */ }
```
### Миграции
При изменении схемы БД необходимо добавить миграцию в `NewPlanetDatabase`.
---
## 🧩 Dependency Injection (Hilt)
### Структура
- `@HiltAndroidApp` на `NewPlanetApplication`
- `@AndroidEntryPoint` на `MainActivity`
- `@HiltViewModel` на ViewModels
- `@Inject constructor()` для зависимостей
### Модули
- **DatabaseModule** — Room (Singleton)
- **NetworkModule** — Retrofit + OkHttp (Singleton)
- **RepositoryModule** — привязки интерфейсов (Singleton)
**Важно:** Используется KSP (не KAPT) для Room и Hilt.
---
## 🧪 Тестирование
- Unit тесты: `test/` (JUnit)
- Instrumented тесты: `androidTest/` (Espresso, Compose Testing)
Команды:
```bash
./gradlew test # Unit тесты
./gradlew connectedAndroidTest # Instrumented тесты
```
---
## 📝 Важные заметки
1. **Offline-first**: Приложение работает без интернета, данные берутся из Room
2. **Accessibility**: Все UI компоненты должны следовать принципам доступности для РАС
3. **Роли пользователей**: CHILD, PARENT, TEACHER — разные права доступа (будущая реализация)
4. **ИИ-агент "Земля"**: чат-бот для помощи пользователям
5. **Визуальный таймер**: круговой индикатор с цветовым кодированием (важно для детей с РАС)
---
## 🚀 Быстрый старт
1. Установить JDK 17+
2. Открыть проект в Android Studio Hedgehog+
3. Синхронизировать Gradle
4. Запустить на эмуляторе/устройстве (minSdk 26)
---
## 📚 Полезные ссылки
- [Material Design 3](https://m3.material.io/)
- [Jetpack Compose](https://developer.android.com/jetpack/compose)
- [Hilt](https://dagger.dev/hilt/)
- [Room](https://developer.android.com/training/data-storage/room)
- [Retrofit](https://square.github.io/retrofit/)
---
*Последнее обновление: на основе текущей структуры проекта*