288 lines
8.7 KiB
Markdown
288 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-коды для внешних заданий
|