287 lines
8.7 KiB
Markdown
287 lines
8.7 KiB
Markdown
# План реализации механики заданий (Tasks)
|
||
|
||
## Обзор
|
||
|
||
Механика заданий позволяет пользователям выполнять различные задачи для изучения языков. Задания могут быть как внутри приложения (тесты, игры), так и внешними (подписки, реальные разговоры). Задания формируются и хранятся на бэкенде.
|
||
|
||
## Примеры заданий
|
||
- Пройди 3 теста сегодня
|
||
- Подпишись на канал в Telegram
|
||
- Сделай заказ в ресторане на испанском и запиши это на видео
|
||
|
||
## Архитектура
|
||
|
||
### Модели данных
|
||
|
||
#### Task (Задание)
|
||
```dart
|
||
@freezed
|
||
class Task with _$Task {
|
||
const factory Task({
|
||
required String id,
|
||
required String title,
|
||
required String description,
|
||
required TaskType type,
|
||
required TaskDifficulty difficulty,
|
||
required List<TaskReward> rewards,
|
||
required TaskStatus status,
|
||
required DateTime createdAt,
|
||
required DateTime expiresAt,
|
||
DateTime? completedAt,
|
||
String? proofUrl, // ссылка на доказательство (видео, фото)
|
||
}) = _Task;
|
||
}
|
||
```
|
||
|
||
#### TaskType (Тип задания)
|
||
```dart
|
||
enum TaskType {
|
||
appInternal, // внутри приложения (тесты, игры)
|
||
external, // внешние задания (реальные ситуации)
|
||
social, // социальные (подписки, репосты)
|
||
}
|
||
```
|
||
|
||
#### TaskDifficulty (Сложность)
|
||
```dart
|
||
enum TaskDifficulty {
|
||
easy,
|
||
medium,
|
||
hard,
|
||
}
|
||
```
|
||
|
||
#### TaskStatus (Статус)
|
||
```dart
|
||
enum TaskStatus {
|
||
available, // доступно для выполнения
|
||
inProgress, // в процессе выполнения
|
||
completed, // выполнено
|
||
expired, // истекло
|
||
failed, // провалено
|
||
}
|
||
```
|
||
|
||
#### TaskReward (Награда)
|
||
```dart
|
||
@freezed
|
||
class TaskReward with _$TaskReward {
|
||
const factory TaskReward({
|
||
required RewardType type,
|
||
required int amount,
|
||
}) = _TaskReward;
|
||
}
|
||
|
||
enum RewardType {
|
||
xp, // опыт
|
||
coins, // монеты
|
||
achievement, // достижение
|
||
}
|
||
```
|
||
|
||
#### TaskProgress (Прогресс пользователя)
|
||
```dart
|
||
@freezed
|
||
class TaskProgress with _$TaskProgress {
|
||
const factory TaskProgress({
|
||
required String userId,
|
||
required Map<String, TaskStatus> taskStatuses,
|
||
required Map<String, DateTime> completedTasks,
|
||
required int totalXp,
|
||
required int totalCoins,
|
||
required List<String> achievements,
|
||
}) = _TaskProgress;
|
||
}
|
||
```
|
||
|
||
### API Endpoints
|
||
|
||
#### Получение списка заданий
|
||
```
|
||
GET /api/tasks
|
||
Query params:
|
||
- user_id: String
|
||
- status: TaskStatus? (фильтр по статусу)
|
||
- type: TaskType? (фильтр по типу)
|
||
- limit: int? (ограничение количества)
|
||
```
|
||
|
||
#### Получение конкретного задания
|
||
```
|
||
GET /api/tasks/{taskId}
|
||
```
|
||
|
||
#### Обновление статуса задания
|
||
```
|
||
PUT /api/tasks/{taskId}/status
|
||
Body: {
|
||
"status": TaskStatus,
|
||
"proof_url": String?, // для внешних заданий
|
||
}
|
||
```
|
||
|
||
#### Получение прогресса пользователя
|
||
```
|
||
GET /api/users/{userId}/task-progress
|
||
```
|
||
|
||
#### Обновление прогресса
|
||
```
|
||
PUT /api/users/{userId}/task-progress
|
||
Body: {
|
||
"task_id": String,
|
||
"status": TaskStatus,
|
||
"proof_url": String?,
|
||
}
|
||
```
|
||
|
||
## State Management
|
||
|
||
### TasksStateManager
|
||
```dart
|
||
class TasksStateManager extends YxStateManager<TasksState> {
|
||
final TasksRepository _repository;
|
||
final UserStateManager _userManager;
|
||
|
||
// Методы:
|
||
Future<void> loadTasks();
|
||
Future<void> loadUserProgress();
|
||
Future<void> updateTaskStatus(String taskId, TaskStatus status);
|
||
Future<void> submitTaskProof(String taskId, String proofUrl);
|
||
Future<List<Task>> getAvailableTasks();
|
||
Future<List<Task>> getCompletedTasks();
|
||
Future<TaskProgress> getUserProgress();
|
||
}
|
||
```
|
||
|
||
### TasksState
|
||
```dart
|
||
@freezed
|
||
class TasksState with _$TasksState {
|
||
const factory TasksState({
|
||
required List<Task> tasks,
|
||
required TaskProgress? userProgress,
|
||
required bool isLoading,
|
||
required String? error,
|
||
}) = _TasksState;
|
||
}
|
||
```
|
||
|
||
## UI Компоненты
|
||
|
||
### Страница заданий (TasksPage)
|
||
- Список доступных заданий
|
||
- Фильтры по типу/статусу
|
||
- Прогресс бар
|
||
- Награды
|
||
|
||
### Карточка задания (TaskCard)
|
||
- Заголовок и описание
|
||
- Тип и сложность
|
||
- Статус
|
||
- Кнопка действия (начать/завершить)
|
||
- Награды
|
||
|
||
### Модальное окно подтверждения (TaskConfirmationDialog)
|
||
- Для внешних заданий
|
||
- Загрузка доказательства (фото/видео)
|
||
- Подтверждение выполнения
|
||
|
||
### Виджет прогресса (TasksProgressWidget)
|
||
- Общий прогресс
|
||
- Количество выполненных заданий
|
||
- XP и монеты
|
||
|
||
## Интеграция с существующими скоупами
|
||
|
||
### UserScope
|
||
Добавить TasksStateManager в UserScope:
|
||
```dart
|
||
class UserScope extends YxScope {
|
||
late final TasksStateManager tasksManager;
|
||
|
||
@override
|
||
Future<void> init() async {
|
||
tasksManager = TasksStateManager(
|
||
repository: ref.read(tasksRepositoryProvider),
|
||
userManager: ref.read(userStateManagerProvider),
|
||
);
|
||
await tasksManager.init();
|
||
}
|
||
}
|
||
```
|
||
|
||
### Навигация
|
||
Добавить маршрут `/tasks` в роутер.
|
||
|
||
## Этапы реализации
|
||
|
||
### Этап 1: Модели данных и API
|
||
1. Создать модели Task, TaskProgress и перечисления
|
||
2. Реализовать TasksRepository с моковыми данными
|
||
3. Настроить API клиент для работы с бэкендом
|
||
|
||
### Этап 2: State Management
|
||
1. Создать TasksStateManager
|
||
2. Интегрировать в UserScope
|
||
3. Реализовать бизнес-логику загрузки и обновления заданий
|
||
|
||
### Этап 3: UI Компоненты
|
||
1. Создать TaskCard виджет
|
||
2. Реализовать TasksPage
|
||
3. Добавить фильтры и сортировку
|
||
4. Создать TaskConfirmationDialog
|
||
|
||
### Этап 4: Интеграция
|
||
1. Добавить навигацию
|
||
2. Обновить главное меню (добавить вкладку Задания)
|
||
3. Интегрировать с системой наград
|
||
|
||
### Этап 5: Тестирование
|
||
1. Unit тесты для state manager
|
||
2. Widget тесты для UI компонентов
|
||
3. Integration тесты
|
||
|
||
### Этап 6: Бэкенд интеграция
|
||
1. Заменить моковые данные на реальные API вызовы
|
||
2. Обработать ошибки сети
|
||
3. Добавить кэширование
|
||
|
||
## Требования к дизайну
|
||
|
||
### Адаптивность
|
||
- Поддержка мобильных устройств (хотя проект web-only)
|
||
- Responsive дизайн для разных экранов
|
||
|
||
### UX/UI
|
||
- Ясные инструкции для каждого задания
|
||
- Визуальная обратная связь при выполнении
|
||
- Анимации для наград
|
||
- Push-уведомления о новых заданиях
|
||
|
||
### Доступность
|
||
- Поддержка клавиатуры
|
||
- Screen reader compatibility
|
||
- Высокий контраст
|
||
|
||
## Метрики и аналитика
|
||
|
||
- Количество выполненных заданий
|
||
- Время выполнения заданий
|
||
- Популярность типов заданий
|
||
- Конверсия в повторные использования
|
||
|
||
## Безопасность
|
||
|
||
- Валидация proof_url на клиенте
|
||
- Проверка на бэкенде
|
||
- Защита от спама (rate limiting)
|
||
- Модерация контента для пользовательских доказательств
|
||
|
||
## Будущие улучшения
|
||
|
||
1. **Персонализация**: Задания на основе прогресса пользователя
|
||
2. **Социальные фичи**: Совместные задания, лидерборды
|
||
3. **Геймификация**: Серии заданий, достижения
|
||
4. **AI генерация**: Автоматическое создание заданий
|
||
5. **Мобильная интеграция**: QR-коды для внешних заданий
|