1260 lines
39 KiB
Markdown
1260 lines
39 KiB
Markdown
|
|
# Statistics Upgrade Plan
|
|||
|
|
|
|||
|
|
## Дата создания: 8 ноября 2025
|
|||
|
|
|
|||
|
|
## Цель
|
|||
|
|
Расширить систему сбора и отображения статистики пользователя для создания детализированной страницы профиля с красивым UI и настройками приложения.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. Текущее состояние (Current State)
|
|||
|
|
|
|||
|
|
### Backend (mnemo_cards_backend)
|
|||
|
|
|
|||
|
|
**Модели данных:**
|
|||
|
|
- `UserModel` - основная модель пользователя (Isar)
|
|||
|
|
- `UserDataModel` - данные пользователя со статистикой
|
|||
|
|
- `words` - список `WordStatisticsModel`
|
|||
|
|
- `testsStatistics` - список `TestStatisticsModel`
|
|||
|
|
- `lastTimeOnline` - DateTime
|
|||
|
|
- `lastTestSessionToken` - String
|
|||
|
|
|
|||
|
|
**DTOs (mnemo_cards_common):**
|
|||
|
|
- `UserDto` - базовая информация пользователя
|
|||
|
|
- id, name, email, admin
|
|||
|
|
- packs (список ID паков)
|
|||
|
|
- purchases (список ID покупок)
|
|||
|
|
- subscription (bool)
|
|||
|
|
- subscriptionFeatures (Set)
|
|||
|
|
- userDataDto, userSettingsDto
|
|||
|
|
|
|||
|
|
- `UserDataDto` - статистика пользователя
|
|||
|
|
- allWordsStatistics (AllWordsStatisticsDto)
|
|||
|
|
- allTestsStatistics (AllTestsStatisticsDto)
|
|||
|
|
|
|||
|
|
- `WordStatisticsDto` - статистика по слову
|
|||
|
|
- word (String)
|
|||
|
|
- correct, incorrect, skipped (double)
|
|||
|
|
- questionTypes (Set)
|
|||
|
|
|
|||
|
|
- `TestStatisticsDto` - статистика по тесту
|
|||
|
|
- testId (int)
|
|||
|
|
- words (AllWordsStatisticsDto)
|
|||
|
|
- sessionToken (String)
|
|||
|
|
- attempts (int)
|
|||
|
|
|
|||
|
|
**API Endpoints (v2):**
|
|||
|
|
- GET `/api/v2/users/me` - получить текущего пользователя
|
|||
|
|
- POST `/api/v2/users/me/settings` - обновить настройки
|
|||
|
|
- POST `/api/v2/users/me/statistics` - добавить статистику теста
|
|||
|
|
- GET `/api/v2/users/me/purchases` - получить покупки
|
|||
|
|
|
|||
|
|
### Frontend (mnemo_cards_web_v2)
|
|||
|
|
|
|||
|
|
**Текущее отображение:**
|
|||
|
|
- `ProfilePage` - базовая страница профиля
|
|||
|
|
- User header (avatar, name, email)
|
|||
|
|
- Basic statistics (mocked)
|
|||
|
|
- Simple chart (daily progress)
|
|||
|
|
- Account info card
|
|||
|
|
- Settings section (dark mode, language)
|
|||
|
|
- Logout button
|
|||
|
|
|
|||
|
|
**Сервисы:**
|
|||
|
|
- `StatisticsService` - генерирует MOCK статистику
|
|||
|
|
- calculateLearnedWords (mock: packs * 10)
|
|||
|
|
- calculateTestsCompleted (mock)
|
|||
|
|
- calculateStudyTime (mock)
|
|||
|
|
- generateDailyProgress (mock)
|
|||
|
|
|
|||
|
|
**Проблемы:**
|
|||
|
|
- ❌ Вся статистика - это моки
|
|||
|
|
- ❌ Нет детализации по пакам
|
|||
|
|
- ❌ Нет детализации по словам
|
|||
|
|
- ❌ Нет реального отслеживания прогресса
|
|||
|
|
- ❌ Нет красивого UI для настроек
|
|||
|
|
- ❌ Нет расширенных метрик
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. Желаемое состояние (Desired State)
|
|||
|
|
|
|||
|
|
### Расширенная статистика
|
|||
|
|
|
|||
|
|
**Общая статистика:**
|
|||
|
|
1. Количество изученных слов (реальное)
|
|||
|
|
2. Общее время обучения
|
|||
|
|
3. Пройдено тестов
|
|||
|
|
4. Текущая серия дней (streak)
|
|||
|
|
5. Точность ответов (accuracy %)
|
|||
|
|
6. Любимые языки / категории
|
|||
|
|
7. Прогресс по уровням
|
|||
|
|
|
|||
|
|
**Статистика по пакам:**
|
|||
|
|
1. Прогресс по каждому паку (%)
|
|||
|
|
2. Количество изученных карточек в паке
|
|||
|
|
3. Время, потраченное на пак
|
|||
|
|
4. Дата последнего обучения
|
|||
|
|
5. Любимые паки (по времени/активности)
|
|||
|
|
6. Сложные слова в паке
|
|||
|
|
|
|||
|
|
**Статистика по словам:**
|
|||
|
|
1. Список всех изученных слов
|
|||
|
|
2. Уровень знания каждого слова
|
|||
|
|
3. История ответов на слово
|
|||
|
|
4. Типы вопросов, в которых встречалось слово
|
|||
|
|
5. Процент правильных ответов
|
|||
|
|
6. Дата последнего повторения
|
|||
|
|
7. Сложные слова (требуют повторения)
|
|||
|
|
|
|||
|
|
**Временная статистика:**
|
|||
|
|
1. Активность по дням недели
|
|||
|
|
2. Активность по времени суток
|
|||
|
|
3. Дневной прогресс (последние 30 дней)
|
|||
|
|
4. Недельный прогресс
|
|||
|
|
5. Месячный прогресс
|
|||
|
|
6. Общий прогресс за все время
|
|||
|
|
|
|||
|
|
**Достижения и цели:**
|
|||
|
|
1. Достигнутые цели
|
|||
|
|
2. Текущие цели
|
|||
|
|
3. Значки/достижения (badges)
|
|||
|
|
4. Рекорды
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. План реализации (Implementation Plan)
|
|||
|
|
|
|||
|
|
### Phase 1: Backend - Расширение моделей и сбора данных
|
|||
|
|
|
|||
|
|
#### 1.1. Расширить модели данных (Backend)
|
|||
|
|
|
|||
|
|
**Файлы для изменения:**
|
|||
|
|
- `mnemo_cards_common/lib/src/dtos/user/data/user_data_dto.dart`
|
|||
|
|
- `mnemo_cards_common_backend/lib/src/models/user_data_model.dart`
|
|||
|
|
|
|||
|
|
**Новые поля в UserDataDto:**
|
|||
|
|
```dart
|
|||
|
|
class UserDataDto {
|
|||
|
|
// Существующие
|
|||
|
|
final AllWordsStatisticsDto? allWordsStatistics;
|
|||
|
|
final AllTestsStatisticsDto? allTestsStatistics;
|
|||
|
|
|
|||
|
|
// Новые
|
|||
|
|
final DateTime? lastTimeOnline;
|
|||
|
|
final int totalStudyTimeMinutes; // общее время обучения
|
|||
|
|
final int currentStreak; // текущая серия дней
|
|||
|
|
final int longestStreak; // самая длинная серия
|
|||
|
|
final Map<String, PackProgressDto> packProgress; // прогресс по пакам
|
|||
|
|
final List<DateTime> studyDates; // даты обучения
|
|||
|
|
final Map<String, int> categoryMinutes; // время по категориям
|
|||
|
|
final List<AchievementDto> achievements; // достижения
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Новые DTO:**
|
|||
|
|
|
|||
|
|
1. **PackProgressDto** (`mnemo_cards_common/lib/src/dtos/user/data/pack_progress_dto.dart`)
|
|||
|
|
```dart
|
|||
|
|
class PackProgressDto {
|
|||
|
|
final String packId;
|
|||
|
|
final int totalCards;
|
|||
|
|
final int learnedCards;
|
|||
|
|
final int studyTimeMinutes;
|
|||
|
|
final DateTime? lastStudyDate;
|
|||
|
|
final DateTime? firstStudyDate;
|
|||
|
|
final Map<String, int> cardAttempts; // cardId -> attempts count
|
|||
|
|
final double averageAccuracy;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **AchievementDto** (`mnemo_cards_common/lib/src/dtos/user/achievement_dto.dart`)
|
|||
|
|
```dart
|
|||
|
|
class AchievementDto {
|
|||
|
|
final String id;
|
|||
|
|
final String title;
|
|||
|
|
final String description;
|
|||
|
|
final String iconUrl;
|
|||
|
|
final DateTime unlockedAt;
|
|||
|
|
final AchievementType type;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **DetailedWordStatisticsDto** (расширение существующего)
|
|||
|
|
```dart
|
|||
|
|
class DetailedWordStatisticsDto extends WordStatisticsDto {
|
|||
|
|
final DateTime? lastReviewed;
|
|||
|
|
final DateTime? firstLearned;
|
|||
|
|
final List<WordAttemptDto> recentAttempts; // последние 10 попыток
|
|||
|
|
final double difficultyScore; // оценка сложности (0-1)
|
|||
|
|
final bool needsReview; // требует повторения
|
|||
|
|
final String? packId; // из какого пака
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. **StudySessionDto** (новый - для отслеживания сессий)
|
|||
|
|
```dart
|
|||
|
|
class StudySessionDto {
|
|||
|
|
final String sessionId;
|
|||
|
|
final DateTime startTime;
|
|||
|
|
final DateTime endTime;
|
|||
|
|
final int wordsLearned;
|
|||
|
|
final int testsCompleted;
|
|||
|
|
final double accuracy;
|
|||
|
|
final String? packId;
|
|||
|
|
final String? testId;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Создать новые DTO классы
|
|||
|
|
- [ ] Добавить новые поля в UserDataDto
|
|||
|
|
- [ ] Создать соответствующие Isar модели
|
|||
|
|
- [ ] Добавить миграцию базы данных
|
|||
|
|
- [ ] Обновить метод toDto() в UserDataModel
|
|||
|
|
- [ ] Написать unit тесты для новых моделей
|
|||
|
|
|
|||
|
|
**Оценка времени:** 4-6 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 1.2. Расширить API для статистики (Backend)
|
|||
|
|
|
|||
|
|
**Новые endpoints в `/api/v2/users/`:**
|
|||
|
|
|
|||
|
|
1. **GET `/api/v2/users/me/statistics/detailed`** - детальная статистика
|
|||
|
|
- Возвращает полную UserDataDto с расширенными полями
|
|||
|
|
|
|||
|
|
2. **GET `/api/v2/users/me/statistics/packs`** - статистика по пакам
|
|||
|
|
- Query params: `packId` (optional)
|
|||
|
|
- Возвращает список PackProgressDto
|
|||
|
|
|
|||
|
|
3. **GET `/api/v2/users/me/statistics/words`** - статистика по словам
|
|||
|
|
- Query params: `packId`, `limit`, `offset`, `sortBy`, `needsReview`
|
|||
|
|
- Возвращает список DetailedWordStatisticsDto с пагинацией
|
|||
|
|
|
|||
|
|
4. **GET `/api/v2/users/me/statistics/timeline`** - временная статистика
|
|||
|
|
- Query params: `period` (day/week/month/year), `from`, `to`
|
|||
|
|
- Возвращает данные для графиков активности
|
|||
|
|
|
|||
|
|
5. **POST `/api/v2/users/me/sessions`** - начать/завершить сессию обучения
|
|||
|
|
- Body: StudySessionDto
|
|||
|
|
- Отслеживает время обучения
|
|||
|
|
|
|||
|
|
6. **GET `/api/v2/users/me/achievements`** - получить достижения
|
|||
|
|
- Возвращает список AchievementDto
|
|||
|
|
|
|||
|
|
**Файлы:**
|
|||
|
|
- `mnemo_cards_backend/lib/api/v2/users_api_v2.dart` - добавить новые endpoints
|
|||
|
|
- `mnemo_cards_backend/lib/user/user_manager.dart` - добавить методы расчета
|
|||
|
|
|
|||
|
|
**Логика расчета статистики:**
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
class StatisticsCalculator {
|
|||
|
|
// Расчет прогресса по паку
|
|||
|
|
PackProgressDto calculatePackProgress(UserModel user, String packId);
|
|||
|
|
|
|||
|
|
// Расчет серии дней
|
|||
|
|
int calculateStreak(List<DateTime> studyDates);
|
|||
|
|
|
|||
|
|
// Расчет сложных слов
|
|||
|
|
List<WordStatisticsDto> findDifficultWords(UserDataModel data, {int limit = 20});
|
|||
|
|
|
|||
|
|
// Расчет точности
|
|||
|
|
double calculateAccuracy(AllWordsStatisticsDto stats);
|
|||
|
|
|
|||
|
|
// Расчет времени обучения по датам
|
|||
|
|
Map<DateTime, int> calculateDailyStudyTime(List<StudySession> sessions);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Создать StatisticsCalculator сервис
|
|||
|
|
- [ ] Добавить новые endpoints в UsersApiV2
|
|||
|
|
- [ ] Реализовать методы расчета в UserManager
|
|||
|
|
- [ ] Добавить middleware для отслеживания времени
|
|||
|
|
- [ ] Написать integration тесты для новых endpoints
|
|||
|
|
- [ ] Обновить OpenAPI спецификацию
|
|||
|
|
|
|||
|
|
**Оценка времени:** 8-10 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 1.3. Автоматический сбор статистики (Backend)
|
|||
|
|
|
|||
|
|
**Tracking механизмы:**
|
|||
|
|
|
|||
|
|
1. **Session Tracking Middleware**
|
|||
|
|
- Отслеживает начало/конец сессий
|
|||
|
|
- Автоматически обновляет lastTimeOnline
|
|||
|
|
- Рассчитывает время онлайн
|
|||
|
|
|
|||
|
|
2. **Test Completion Hook**
|
|||
|
|
- При завершении теста обновляет:
|
|||
|
|
- Статистику по словам
|
|||
|
|
- Прогресс по паку
|
|||
|
|
- Общее количество тестов
|
|||
|
|
- Streak (если нужно)
|
|||
|
|
|
|||
|
|
3. **Card Learning Hook**
|
|||
|
|
- При изучении карточки обновляет:
|
|||
|
|
- Счетчик изученных карточек
|
|||
|
|
- Прогресс по паку
|
|||
|
|
- Статистику слова
|
|||
|
|
|
|||
|
|
4. **Achievement Checker**
|
|||
|
|
- Проверяет условия достижений после каждого действия
|
|||
|
|
- Выдает новые достижения
|
|||
|
|
|
|||
|
|
**Файлы:**
|
|||
|
|
- `mnemo_cards_backend/lib/statistics/session_tracker.dart` (новый)
|
|||
|
|
- `mnemo_cards_backend/lib/statistics/achievement_manager.dart` (новый)
|
|||
|
|
- `mnemo_cards_backend/lib/user/user_manager.dart` (расширить)
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Создать SessionTracker
|
|||
|
|
- [ ] Создать AchievementManager
|
|||
|
|
- [ ] Добавить hooks в существующие endpoints
|
|||
|
|
- [ ] Добавить фоновую задачу для расчета streak
|
|||
|
|
- [ ] Написать unit тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 6-8 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Phase 2: Frontend - Новые сервисы и state management
|
|||
|
|
|
|||
|
|
#### 2.1. Обновить HTTP Repository (Frontend)
|
|||
|
|
|
|||
|
|
**Файл:** `mnemo_cards_web_v2/lib/domain/services/http_repository_v2.dart`
|
|||
|
|
|
|||
|
|
**Новые методы:**
|
|||
|
|
```dart
|
|||
|
|
class HttpRepositoryV2 {
|
|||
|
|
// Существующие методы...
|
|||
|
|
|
|||
|
|
// Новые методы для статистики
|
|||
|
|
Future<UserDataDto> getDetailedStatistics();
|
|||
|
|
Future<List<PackProgressDto>> getPacksStatistics({String? packId});
|
|||
|
|
Future<PaginatedResponse<DetailedWordStatisticsDto>> getWordsStatistics({
|
|||
|
|
String? packId,
|
|||
|
|
int? limit,
|
|||
|
|
int? offset,
|
|||
|
|
String? sortBy,
|
|||
|
|
bool? needsReview,
|
|||
|
|
});
|
|||
|
|
Future<TimelineStatisticsDto> getTimelineStatistics({
|
|||
|
|
required String period,
|
|||
|
|
DateTime? from,
|
|||
|
|
DateTime? to,
|
|||
|
|
});
|
|||
|
|
Future<void> startStudySession(StudySessionDto session);
|
|||
|
|
Future<void> endStudySession(String sessionId, StudySessionDto session);
|
|||
|
|
Future<List<AchievementDto>> getAchievements();
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Добавить новые методы в HttpRepositoryV2
|
|||
|
|
- [ ] Создать классы для response моделей
|
|||
|
|
- [ ] Добавить error handling
|
|||
|
|
- [ ] Написать unit тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 2-3 часа
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 2.2. Создать расширенный StatisticsService (Frontend)
|
|||
|
|
|
|||
|
|
**Файл:** `mnemo_cards_web_v2/lib/domain/services/statistics_service.dart` (переписать)
|
|||
|
|
|
|||
|
|
**Новая структура:**
|
|||
|
|
```dart
|
|||
|
|
class StatisticsService {
|
|||
|
|
final HttpRepositoryV2 _repository;
|
|||
|
|
|
|||
|
|
// Получение полной статистики
|
|||
|
|
Future<DetailedUserStatistics> getDetailedStatistics();
|
|||
|
|
|
|||
|
|
// Получение статистики по пакам
|
|||
|
|
Future<List<PackStatistics>> getPacksStatistics({String? packId});
|
|||
|
|
|
|||
|
|
// Получение статистики по словам
|
|||
|
|
Future<WordsStatisticsData> getWordsStatistics({
|
|||
|
|
String? packId,
|
|||
|
|
int page = 0,
|
|||
|
|
int pageSize = 50,
|
|||
|
|
WordsSortOption sortBy = WordsSortOption.difficulty,
|
|||
|
|
bool needsReview = false,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Получение временной статистики
|
|||
|
|
Future<TimelineData> getTimelineStatistics({
|
|||
|
|
required TimelinePeriod period,
|
|||
|
|
DateTime? from,
|
|||
|
|
DateTime? to,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Управление сессиями
|
|||
|
|
String startSession({String? packId, String? testId});
|
|||
|
|
Future<void> endSession(String sessionId);
|
|||
|
|
|
|||
|
|
// Достижения
|
|||
|
|
Future<List<Achievement>> getAchievements();
|
|||
|
|
Future<List<Achievement>> getNewAchievements();
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Новые модели (Frontend):**
|
|||
|
|
```dart
|
|||
|
|
class DetailedUserStatistics {
|
|||
|
|
final int totalWords;
|
|||
|
|
final int totalStudyTime;
|
|||
|
|
final int testsCompleted;
|
|||
|
|
final int currentStreak;
|
|||
|
|
final int longestStreak;
|
|||
|
|
final double averageAccuracy;
|
|||
|
|
final List<Achievement> recentAchievements;
|
|||
|
|
final Map<String, PackStatistics> packStats;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class PackStatistics {
|
|||
|
|
final String packId;
|
|||
|
|
final String packName;
|
|||
|
|
final int totalCards;
|
|||
|
|
final int learnedCards;
|
|||
|
|
final double progress;
|
|||
|
|
final int studyTimeMinutes;
|
|||
|
|
final DateTime? lastStudyDate;
|
|||
|
|
final double accuracy;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class WordsStatisticsData {
|
|||
|
|
final List<WordStatistics> words;
|
|||
|
|
final int totalCount;
|
|||
|
|
final int page;
|
|||
|
|
final int pageSize;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class WordStatistics {
|
|||
|
|
final String word;
|
|||
|
|
final String translation;
|
|||
|
|
final double correctRate;
|
|||
|
|
final int totalAttempts;
|
|||
|
|
final DateTime? lastReviewed;
|
|||
|
|
final double difficultyScore;
|
|||
|
|
final bool needsReview;
|
|||
|
|
final String? packName;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class TimelineData {
|
|||
|
|
final List<DailyActivity> dailyActivity;
|
|||
|
|
final List<WeeklyActivity> weeklyActivity;
|
|||
|
|
final Map<int, int> hourlyActivity; // час -> минут
|
|||
|
|
final Map<int, int> weekdayActivity; // день недели -> минут
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class Achievement {
|
|||
|
|
final String id;
|
|||
|
|
final String title;
|
|||
|
|
final String description;
|
|||
|
|
final String iconUrl;
|
|||
|
|
final DateTime? unlockedAt;
|
|||
|
|
final bool isLocked;
|
|||
|
|
final double progress; // для незавершенных
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Переписать StatisticsService с реальной логикой
|
|||
|
|
- [ ] Создать новые модели данных
|
|||
|
|
- [ ] Добавить кэширование статистики
|
|||
|
|
- [ ] Написать unit тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 4-5 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 2.3. Создать State Manager для статистики (Frontend)
|
|||
|
|
|
|||
|
|
**Файл:** `mnemo_cards_web_v2/lib/domain/state/statistics_state_manager.dart` (новый)
|
|||
|
|
|
|||
|
|
**State:**
|
|||
|
|
```dart
|
|||
|
|
@freezed
|
|||
|
|
class StatisticsState with _$StatisticsState {
|
|||
|
|
const factory StatisticsState.loading() = _Loading;
|
|||
|
|
const factory StatisticsState.loaded(DetailedUserStatistics statistics) = _Loaded;
|
|||
|
|
const factory StatisticsState.error(String message) = _Error;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**State Manager:**
|
|||
|
|
```dart
|
|||
|
|
class StatisticsStateManager extends StateManager<StatisticsState> {
|
|||
|
|
final StatisticsService _service;
|
|||
|
|
|
|||
|
|
StatisticsStateManager(this._service) : super(const StatisticsState.loading());
|
|||
|
|
|
|||
|
|
Future<void> loadStatistics() async { /* ... */ }
|
|||
|
|
Future<void> refreshStatistics() async { /* ... */ }
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Дополнительные state managers:**
|
|||
|
|
|
|||
|
|
1. **PacksStatisticsStateManager** - статистика по пакам
|
|||
|
|
2. **WordsStatisticsStateManager** - статистика по словам
|
|||
|
|
3. **TimelineStatisticsStateManager** - временная статистика
|
|||
|
|
4. **AchievementsStateManager** - достижения
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Создать StatisticsStateManager
|
|||
|
|
- [ ] Создать дополнительные state managers
|
|||
|
|
- [ ] Добавить в UserScope module
|
|||
|
|
- [ ] Написать unit тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 3-4 часа
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Phase 3: Frontend - Красивый UI для профиля
|
|||
|
|
|
|||
|
|
#### 3.1. Редизайн ProfilePage
|
|||
|
|
|
|||
|
|
**Файл:** `mnemo_cards_web_v2/lib/presentation/pages/profile/profile_page.dart` (переписать)
|
|||
|
|
|
|||
|
|
**Новая структура:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
ProfilePage (Scaffold)
|
|||
|
|
├── AppBar
|
|||
|
|
│ ├── Title
|
|||
|
|
│ ├── Actions (settings icon)
|
|||
|
|
├── Body (ScrollView)
|
|||
|
|
│ ├── UserHeaderCard (расширенная)
|
|||
|
|
│ │ ├── Avatar (большой)
|
|||
|
|
│ │ ├── User info
|
|||
|
|
│ │ ├── Subscription badge
|
|||
|
|
│ │ ├── Streak indicator
|
|||
|
|
│ │ └── Level badge
|
|||
|
|
│ │
|
|||
|
|
│ ├── QuickStatsGrid (4 карточки в ряд)
|
|||
|
|
│ │ ├── Total Words
|
|||
|
|
│ │ ├── Study Time
|
|||
|
|
│ │ ├── Tests Completed
|
|||
|
|
│ │ └── Accuracy
|
|||
|
|
│ │
|
|||
|
|
│ ├── StreakCard (визуализация серии)
|
|||
|
|
│ │ ├── Calendar view (последние 30 дней)
|
|||
|
|
│ │ └── Current/Longest streak
|
|||
|
|
│ │
|
|||
|
|
│ ├── ActivityChartCard
|
|||
|
|
│ │ ├── Tabs (Day/Week/Month/Year)
|
|||
|
|
│ │ ├── Beautiful chart
|
|||
|
|
│ │ └── Activity heatmap
|
|||
|
|
│ │
|
|||
|
|
│ ├── PacksProgressSection
|
|||
|
|
│ │ ├── Title "Your Packs Progress"
|
|||
|
|
│ │ ├── List of PackProgressCard
|
|||
|
|
│ │ │ ├── Pack image
|
|||
|
|
│ │ │ ├── Pack name
|
|||
|
|
│ │ │ ├── Progress bar
|
|||
|
|
│ │ │ ├── Stats (learned/total)
|
|||
|
|
│ │ │ └── Last study date
|
|||
|
|
│ │ └── "View All" button
|
|||
|
|
│ │
|
|||
|
|
│ ├── AchievementsSection
|
|||
|
|
│ │ ├── Title "Achievements"
|
|||
|
|
│ │ ├── Horizontal scroll of achievement badges
|
|||
|
|
│ │ └── "View All" button
|
|||
|
|
│ │
|
|||
|
|
│ └── AccountActionsCard
|
|||
|
|
│ ├── Edit Profile
|
|||
|
|
│ ├── Settings
|
|||
|
|
│ ├── Subscription
|
|||
|
|
│ └── Logout
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Компоненты для создания:**
|
|||
|
|
|
|||
|
|
1. **UserHeaderCard** (`profile_user_header.dart`)
|
|||
|
|
- Большой avatar с gradient border
|
|||
|
|
- Имя, email
|
|||
|
|
- Badges (streak, level, subscription)
|
|||
|
|
- Красивая типографика
|
|||
|
|
|
|||
|
|
2. **QuickStatsGrid** (`profile_quick_stats.dart`)
|
|||
|
|
- Grid из 4 карточек
|
|||
|
|
- Иконки + число + label
|
|||
|
|
- Анимации при загрузке
|
|||
|
|
- Responsive (2x2 на мобильном)
|
|||
|
|
|
|||
|
|
3. **StreakCard** (`profile_streak_card.dart`)
|
|||
|
|
- Calendar heatmap (30 дней)
|
|||
|
|
- Текущая/максимальная серия
|
|||
|
|
- Fire icon для streak
|
|||
|
|
- Красивые градиенты
|
|||
|
|
|
|||
|
|
4. **ActivityChartCard** (`profile_activity_chart.dart`)
|
|||
|
|
- Tabs для периодов
|
|||
|
|
- fl_chart для графиков
|
|||
|
|
- Heatmap для времени суток
|
|||
|
|
- Weekday activity chart
|
|||
|
|
|
|||
|
|
5. **PackProgressCard** (`profile_pack_progress_card.dart`)
|
|||
|
|
- Pack image
|
|||
|
|
- Progress indicator (circular или linear)
|
|||
|
|
- Stats chips
|
|||
|
|
- Tap -> navigate to pack details
|
|||
|
|
|
|||
|
|
6. **AchievementBadge** (`profile_achievement_badge.dart`)
|
|||
|
|
- Иконка достижения
|
|||
|
|
- Tooltip с описанием
|
|||
|
|
- Locked/unlocked state
|
|||
|
|
- Shine animation для новых
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Создать новые компоненты
|
|||
|
|
- [ ] Переписать ProfilePage с новым layout
|
|||
|
|
- [ ] Добавить анимации и transitions
|
|||
|
|
- [ ] Сделать responsive design
|
|||
|
|
- [ ] Добавить skeleton loaders
|
|||
|
|
- [ ] Написать widget тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 12-15 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 3.2. Создать страницу детальной статистики по словам
|
|||
|
|
|
|||
|
|
**Файл:** `mnemo_cards_web_v2/lib/presentation/pages/statistics/words_statistics_page.dart` (новый)
|
|||
|
|
|
|||
|
|
**Структура:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
WordsStatisticsPage (Scaffold)
|
|||
|
|
├── AppBar
|
|||
|
|
│ ├── Title "Words Statistics"
|
|||
|
|
│ ├── Search field
|
|||
|
|
│ ├── Filter button
|
|||
|
|
├── Body
|
|||
|
|
│ ├── FilterBar
|
|||
|
|
│ │ ├── Pack selector
|
|||
|
|
│ │ ├── Sort options (difficulty, accuracy, recent)
|
|||
|
|
│ │ ├── "Needs Review" toggle
|
|||
|
|
│ │
|
|||
|
|
│ ├── WordsList (paginated)
|
|||
|
|
│ │ └── WordStatisticsCard (для каждого слова)
|
|||
|
|
│ │ ├── Word + translation
|
|||
|
|
│ │ ├── Pack badge
|
|||
|
|
│ │ ├── Accuracy indicator
|
|||
|
|
│ │ ├── Attempts count
|
|||
|
|
│ │ ├── Last reviewed date
|
|||
|
|
│ │ ├── Difficulty indicator
|
|||
|
|
│ │ └── "Needs Review" badge
|
|||
|
|
│ │
|
|||
|
|
│ └── LoadMore button / Infinite scroll
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Создать WordsStatisticsPage
|
|||
|
|
- [ ] Создать WordStatisticsCard компонент
|
|||
|
|
- [ ] Добавить фильтрацию и сортировку
|
|||
|
|
- [ ] Добавить пагинацию
|
|||
|
|
- [ ] Добавить поиск
|
|||
|
|
- [ ] Написать widget тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 6-8 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 3.3. Создать страницу детальной статистики по пакам
|
|||
|
|
|
|||
|
|
**Файл:** `mnemo_cards_web_v2/lib/presentation/pages/statistics/packs_statistics_page.dart` (новый)
|
|||
|
|
|
|||
|
|
**Структура:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
PacksStatisticsPage (Scaffold)
|
|||
|
|
├── AppBar
|
|||
|
|
│ ├── Title "Packs Statistics"
|
|||
|
|
│ ├── Sort menu
|
|||
|
|
├── Body
|
|||
|
|
│ ├── PacksGrid / PacksList
|
|||
|
|
│ │ └── PackStatisticsCard
|
|||
|
|
│ │ ├── Pack image
|
|||
|
|
│ │ ├── Pack name
|
|||
|
|
│ │ ├── Progress (circular chart)
|
|||
|
|
│ │ ├── Study time
|
|||
|
|
│ │ ├── Learned cards count
|
|||
|
|
│ │ ├── Accuracy
|
|||
|
|
│ │ ├── Last study date
|
|||
|
|
│ │ └── Tap -> PackStatisticsDetailsPage
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Детальная страница пака:**
|
|||
|
|
**Файл:** `pack_statistics_details_page.dart`
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
PackStatisticsDetailsPage (Scaffold)
|
|||
|
|
├── AppBar (pack name)
|
|||
|
|
├── Body
|
|||
|
|
│ ├── PackHeaderCard
|
|||
|
|
│ │ ├── Pack image
|
|||
|
|
│ │ ├── Overall progress
|
|||
|
|
│ │ ├── Total stats
|
|||
|
|
│ │
|
|||
|
|
│ ├── ProgressTimelineChart
|
|||
|
|
│ │ └── Chart of progress over time
|
|||
|
|
│ │
|
|||
|
|
│ ├── CardsListSection
|
|||
|
|
│ │ ├── Title "Cards Progress"
|
|||
|
|
│ │ └── List of cards with individual progress
|
|||
|
|
│ │ ├── Card preview
|
|||
|
|
│ │ ├── Word
|
|||
|
|
│ │ ├── Times reviewed
|
|||
|
|
│ │ ├── Accuracy
|
|||
|
|
│ │
|
|||
|
|
│ └── StudyHistorySection
|
|||
|
|
│ └── Timeline of study sessions
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Создать PacksStatisticsPage
|
|||
|
|
- [ ] Создать PackStatisticsCard
|
|||
|
|
- [ ] Создать PackStatisticsDetailsPage
|
|||
|
|
- [ ] Добавить графики прогресса
|
|||
|
|
- [ ] Написать widget тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 8-10 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 3.4. Создать страницу достижений
|
|||
|
|
|
|||
|
|
**Файл:** `mnemo_cards_web_v2/lib/presentation/pages/achievements/achievements_page.dart` (новый)
|
|||
|
|
|
|||
|
|
**Структура:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
AchievementsPage (Scaffold)
|
|||
|
|
├── AppBar
|
|||
|
|
│ ├── Title "Achievements"
|
|||
|
|
│ ├── Progress indicator (X/Y unlocked)
|
|||
|
|
├── Body
|
|||
|
|
│ ├── Tabs
|
|||
|
|
│ │ ├── All
|
|||
|
|
│ │ ├── Unlocked
|
|||
|
|
│ │ ├── Locked
|
|||
|
|
│ │
|
|||
|
|
│ └── AchievementsGrid
|
|||
|
|
│ └── AchievementCard
|
|||
|
|
│ ├── Icon/Badge
|
|||
|
|
│ ├── Title
|
|||
|
|
│ ├── Description
|
|||
|
|
│ ├── Progress bar (for locked)
|
|||
|
|
│ ├── Unlock date (for unlocked)
|
|||
|
|
│ └── Shimmer effect for locked
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Типы достижений:**
|
|||
|
|
- First Steps (first word, first test, first pack)
|
|||
|
|
- Streaks (3 days, 7 days, 30 days, 100 days)
|
|||
|
|
- Words Master (10, 50, 100, 500, 1000 words)
|
|||
|
|
- Perfect Score (100% on test)
|
|||
|
|
- Speed Learner (complete pack in 1 day)
|
|||
|
|
- Night Owl (study at night)
|
|||
|
|
- Early Bird (study in morning)
|
|||
|
|
- Dedicated (total study time milestones)
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Создать AchievementsPage
|
|||
|
|
- [ ] Создать AchievementCard компонент
|
|||
|
|
- [ ] Добавить фильтрацию по статусу
|
|||
|
|
- [ ] Добавить анимации unlock
|
|||
|
|
- [ ] Создать achievement icons/badges
|
|||
|
|
- [ ] Написать widget тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 6-8 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Phase 4: Frontend - Улучшенные настройки приложения
|
|||
|
|
|
|||
|
|
#### 4.1. Создать отдельную страницу Settings
|
|||
|
|
|
|||
|
|
**Файл:** `mnemo_cards_web_v2/lib/presentation/pages/settings/settings_page.dart` (новый)
|
|||
|
|
|
|||
|
|
**Структура:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
SettingsPage (Scaffold)
|
|||
|
|
├── AppBar
|
|||
|
|
│ ├── Title "Settings"
|
|||
|
|
│ ├── Back button
|
|||
|
|
├── Body (ListView)
|
|||
|
|
│ ├── Appearance Section
|
|||
|
|
│ │ ├── Theme (Light/Dark/System)
|
|||
|
|
│ │ ├── Primary Color picker
|
|||
|
|
│ │ ├── Font Size slider
|
|||
|
|
│ │ └── Language selector
|
|||
|
|
│ │
|
|||
|
|
│ ├── Learning Section
|
|||
|
|
│ │ ├── Daily Goal (words per day)
|
|||
|
|
│ │ ├── Reminder notifications toggle
|
|||
|
|
│ │ ├── Reminder time picker
|
|||
|
|
│ │ ├── Auto-play audio toggle
|
|||
|
|
│ │ ├── Show translations toggle
|
|||
|
|
│ │ └── Cards per session
|
|||
|
|
│ │
|
|||
|
|
│ ├── Privacy Section
|
|||
|
|
│ │ ├── Analytics toggle
|
|||
|
|
│ │ ├── Personalized ads toggle
|
|||
|
|
│ │ └── Data collection info
|
|||
|
|
│ │
|
|||
|
|
│ ├── Account Section
|
|||
|
|
│ │ ├── Email (readonly/editable)
|
|||
|
|
│ │ ├── Name (editable)
|
|||
|
|
│ │ ├── Change password
|
|||
|
|
│ │ └── Delete account
|
|||
|
|
│ │
|
|||
|
|
│ ├── Data Section
|
|||
|
|
│ │ ├── Export data
|
|||
|
|
│ │ ├── Import data
|
|||
|
|
│ │ ├── Clear cache
|
|||
|
|
│ │ └── Reset progress (dangerous)
|
|||
|
|
│ │
|
|||
|
|
│ └── About Section
|
|||
|
|
│ ├── Version
|
|||
|
|
│ ├── Terms of Service
|
|||
|
|
│ ├── Privacy Policy
|
|||
|
|
│ └── Contact Support
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Расширить UserSettingsDto:**
|
|||
|
|
|
|||
|
|
**Файл:** `mnemo_cards_common/lib/src/dtos/user/settings/user_settings_dto.dart`
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
class UserSettingsDto {
|
|||
|
|
// Appearance
|
|||
|
|
final String theme; // 'light', 'dark', 'system'
|
|||
|
|
final String? primaryColor;
|
|||
|
|
final double fontSize; // 0.8 - 1.2
|
|||
|
|
final String language;
|
|||
|
|
|
|||
|
|
// Learning
|
|||
|
|
final int dailyGoalWords;
|
|||
|
|
final bool reminderEnabled;
|
|||
|
|
final String? reminderTime; // "HH:mm"
|
|||
|
|
final bool autoPlayAudio;
|
|||
|
|
final bool showTranslations;
|
|||
|
|
final int cardsPerSession;
|
|||
|
|
|
|||
|
|
// Privacy
|
|||
|
|
final bool analyticsEnabled;
|
|||
|
|
final bool personalizedAdsEnabled;
|
|||
|
|
|
|||
|
|
// Notifications (web - не критично)
|
|||
|
|
final bool pushNotificationsEnabled;
|
|||
|
|
final bool emailNotificationsEnabled;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Компоненты:**
|
|||
|
|
|
|||
|
|
1. **SettingsSection** (`settings_section.dart`)
|
|||
|
|
- Section header
|
|||
|
|
- Divider
|
|||
|
|
- Settings items
|
|||
|
|
|
|||
|
|
2. **SettingsTile** (`settings_tile.dart`)
|
|||
|
|
- Leading icon
|
|||
|
|
- Title + subtitle
|
|||
|
|
- Trailing widget (switch/arrow/value)
|
|||
|
|
- Tap handler
|
|||
|
|
|
|||
|
|
3. **ThemeSelector** (`theme_selector.dart`)
|
|||
|
|
- Radio buttons для Light/Dark/System
|
|||
|
|
- Preview chips
|
|||
|
|
|
|||
|
|
4. **ColorPicker** (`color_picker.dart`)
|
|||
|
|
- Grid of colors
|
|||
|
|
- Custom color picker
|
|||
|
|
|
|||
|
|
5. **TimePickerSetting** (`time_picker_setting.dart`)
|
|||
|
|
- Time input
|
|||
|
|
- Native time picker
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Расширить UserSettingsDto
|
|||
|
|
- [ ] Создать SettingsPage с новым UI
|
|||
|
|
- [ ] Создать компоненты для settings
|
|||
|
|
- [ ] Добавить настройки в backend API
|
|||
|
|
- [ ] Создать SettingsStateManager
|
|||
|
|
- [ ] Сохранять настройки локально и на сервере
|
|||
|
|
- [ ] Написать unit и widget тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 10-12 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 4.2. Интегрировать настройки в приложение
|
|||
|
|
|
|||
|
|
**Применение настроек:**
|
|||
|
|
|
|||
|
|
1. **Theme Settings**
|
|||
|
|
- Обновить ThemeStateManager для поддержки custom colors
|
|||
|
|
- Добавить font size scaling
|
|||
|
|
|
|||
|
|
2. **Learning Settings**
|
|||
|
|
- Использовать в CardFlipper
|
|||
|
|
- Применять в тестах
|
|||
|
|
- Показывать daily goal на ProfilePage
|
|||
|
|
|
|||
|
|
3. **Reminder Notifications**
|
|||
|
|
- Локальные напоминания (web notifications API)
|
|||
|
|
- Backend cron job для email напоминаний
|
|||
|
|
|
|||
|
|
**Файлы для изменения:**
|
|||
|
|
- `lib/domain/state/theme_state_manager.dart`
|
|||
|
|
- `lib/presentation/widgets/card_flipper/card_flipper.dart`
|
|||
|
|
- `lib/di/user_scope/modules/settings_module.dart`
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Обновить ThemeStateManager
|
|||
|
|
- [ ] Применить настройки в UI
|
|||
|
|
- [ ] Добавить daily goal tracking
|
|||
|
|
- [ ] Реализовать напоминания
|
|||
|
|
- [ ] Написать тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 6-8 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Phase 5: Визуальные улучшения и анимации
|
|||
|
|
|
|||
|
|
#### 5.1. Создать красивые компоненты для статистики
|
|||
|
|
|
|||
|
|
**Новые виджеты:**
|
|||
|
|
|
|||
|
|
1. **StatsCard** (`widgets/stats/stats_card.dart`)
|
|||
|
|
- Универсальная карточка для stats
|
|||
|
|
- Gradient background
|
|||
|
|
- Icon + Value + Label
|
|||
|
|
- Shimmer loading state
|
|||
|
|
- Counter animation
|
|||
|
|
|
|||
|
|
2. **CircularProgressIndicator** (custom)
|
|||
|
|
- Красивый circular progress
|
|||
|
|
- Gradient stroke
|
|||
|
|
- Percentage в центре
|
|||
|
|
- Анимация заполнения
|
|||
|
|
|
|||
|
|
3. **LinearProgressBar** (custom)
|
|||
|
|
- Gradient background
|
|||
|
|
- Smooth animation
|
|||
|
|
- Labels (start/end)
|
|||
|
|
- Multiple segments support
|
|||
|
|
|
|||
|
|
4. **ActivityHeatmap** (`widgets/stats/activity_heatmap.dart`)
|
|||
|
|
- GitHub-style heatmap
|
|||
|
|
- Customizable colors
|
|||
|
|
- Tooltips на hover
|
|||
|
|
- Responsive
|
|||
|
|
|
|||
|
|
5. **StreakCalendar** (`widgets/stats/streak_calendar.dart`)
|
|||
|
|
- Calendar view с индикацией
|
|||
|
|
- Highlight current streak
|
|||
|
|
- Tooltips для каждого дня
|
|||
|
|
|
|||
|
|
6. **TimelineChart** (`widgets/stats/timeline_chart.dart`)
|
|||
|
|
- Использовать fl_chart
|
|||
|
|
- Line chart для прогресса
|
|||
|
|
- Bar chart для активности
|
|||
|
|
- Interactive tooltips
|
|||
|
|
|
|||
|
|
7. **RadarChart** (`widgets/stats/radar_chart.dart`)
|
|||
|
|
- Для отображения skills по категориям
|
|||
|
|
- fl_chart RadarChart
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Создать все новые виджеты
|
|||
|
|
- [ ] Добавить анимации
|
|||
|
|
- [ ] Сделать responsive
|
|||
|
|
- [ ] Добавить loading states
|
|||
|
|
- [ ] Написать widget тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 10-12 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 5.2. Добавить анимации и transitions
|
|||
|
|
|
|||
|
|
**Анимации:**
|
|||
|
|
|
|||
|
|
1. **Page Transitions**
|
|||
|
|
- Smooth navigation между Profile -> Statistics -> Settings
|
|||
|
|
- Hero animations для images/avatars
|
|||
|
|
|
|||
|
|
2. **Stats Counter Animation**
|
|||
|
|
- Animated counting для чисел
|
|||
|
|
- Использовать AnimatedCount widget
|
|||
|
|
|
|||
|
|
3. **Chart Animations**
|
|||
|
|
- fl_chart встроенные анимации
|
|||
|
|
- Staggered animation для bars
|
|||
|
|
|
|||
|
|
4. **Achievement Unlock Animation**
|
|||
|
|
- Confetti effect
|
|||
|
|
- Scale + Fade animation
|
|||
|
|
- Sound effect (optional)
|
|||
|
|
|
|||
|
|
5. **Shimmer Loading**
|
|||
|
|
- Skeleton screens для всех страниц
|
|||
|
|
- Shimmer effect
|
|||
|
|
|
|||
|
|
6. **Pull to Refresh**
|
|||
|
|
- Custom refresh indicator
|
|||
|
|
|
|||
|
|
**Пакеты:**
|
|||
|
|
- fl_chart (для графиков)
|
|||
|
|
- shimmer (для loading)
|
|||
|
|
- confetti (для celebrations)
|
|||
|
|
- lottie (для сложных анимаций)
|
|||
|
|
|
|||
|
|
**Задачи:**
|
|||
|
|
- [ ] Добавить Hero animations
|
|||
|
|
- [ ] Создать AnimatedCounter widget
|
|||
|
|
- [ ] Добавить shimmer loaders
|
|||
|
|
- [ ] Реализовать achievement unlock animation
|
|||
|
|
- [ ] Добавить pull-to-refresh
|
|||
|
|
- [ ] Написать тесты
|
|||
|
|
|
|||
|
|
**Оценка времени:** 6-8 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Phase 6: Testing & Documentation
|
|||
|
|
|
|||
|
|
#### 6.1. Unit Tests
|
|||
|
|
|
|||
|
|
**Backend тесты:**
|
|||
|
|
- [ ] StatisticsCalculator tests
|
|||
|
|
- [ ] PackProgressDto tests
|
|||
|
|
- [ ] Achievement logic tests
|
|||
|
|
- [ ] Session tracking tests
|
|||
|
|
- [ ] UserDataModel conversion tests
|
|||
|
|
|
|||
|
|
**Frontend тесты:**
|
|||
|
|
- [ ] StatisticsService tests
|
|||
|
|
- [ ] StatisticsStateManager tests
|
|||
|
|
- [ ] Settings logic tests
|
|||
|
|
- [ ] Calculations tests
|
|||
|
|
|
|||
|
|
**Оценка времени:** 6-8 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 6.2. Widget Tests
|
|||
|
|
|
|||
|
|
**Frontend widget тесты:**
|
|||
|
|
- [ ] ProfilePage tests
|
|||
|
|
- [ ] WordsStatisticsPage tests
|
|||
|
|
- [ ] PacksStatisticsPage tests
|
|||
|
|
- [ ] AchievementsPage tests
|
|||
|
|
- [ ] SettingsPage tests
|
|||
|
|
- [ ] All custom widgets tests
|
|||
|
|
|
|||
|
|
**Оценка времени:** 8-10 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 6.3. Integration Tests
|
|||
|
|
|
|||
|
|
**E2E тесты:**
|
|||
|
|
- [ ] Load statistics flow
|
|||
|
|
- [ ] Navigate through statistics pages
|
|||
|
|
- [ ] Update settings flow
|
|||
|
|
- [ ] Achievement unlock flow
|
|||
|
|
|
|||
|
|
**Оценка времени:** 4-6 часов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 6.4. Documentation
|
|||
|
|
|
|||
|
|
**Обновить документацию:**
|
|||
|
|
- [ ] Update TODO.md
|
|||
|
|
- [ ] Update PROGRESS.md
|
|||
|
|
- [ ] Create STATISTICS_API.md (API documentation)
|
|||
|
|
- [ ] Create STATISTICS_UI.md (UI guidelines)
|
|||
|
|
- [ ] Update README.md
|
|||
|
|
|
|||
|
|
**Оценка времени:** 2-3 часа
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. Общая оценка времени
|
|||
|
|
|
|||
|
|
### Backend
|
|||
|
|
- Phase 1.1: Расширение моделей - 4-6 часов
|
|||
|
|
- Phase 1.2: API endpoints - 8-10 часов
|
|||
|
|
- Phase 1.3: Автоматический сбор - 6-8 часов
|
|||
|
|
- **Backend Total:** 18-24 часа
|
|||
|
|
|
|||
|
|
### Frontend - Сервисы и State
|
|||
|
|
- Phase 2.1: HTTP Repository - 2-3 часа
|
|||
|
|
- Phase 2.2: StatisticsService - 4-5 часов
|
|||
|
|
- Phase 2.3: State Managers - 3-4 часа
|
|||
|
|
- **Services Total:** 9-12 часов
|
|||
|
|
|
|||
|
|
### Frontend - UI
|
|||
|
|
- Phase 3.1: ProfilePage редизайн - 12-15 часов
|
|||
|
|
- Phase 3.2: Words Statistics Page - 6-8 часов
|
|||
|
|
- Phase 3.3: Packs Statistics Page - 8-10 часов
|
|||
|
|
- Phase 3.4: Achievements Page - 6-8 часов
|
|||
|
|
- Phase 4.1: Settings Page - 10-12 часов
|
|||
|
|
- Phase 4.2: Settings Integration - 6-8 часов
|
|||
|
|
- Phase 5.1: Stats Widgets - 10-12 часов
|
|||
|
|
- Phase 5.2: Animations - 6-8 часов
|
|||
|
|
- **UI Total:** 64-81 час
|
|||
|
|
|
|||
|
|
### Testing & Documentation
|
|||
|
|
- Phase 6.1: Unit Tests - 6-8 часов
|
|||
|
|
- Phase 6.2: Widget Tests - 8-10 часов
|
|||
|
|
- Phase 6.3: Integration Tests - 4-6 часов
|
|||
|
|
- Phase 6.4: Documentation - 2-3 часа
|
|||
|
|
- **Testing Total:** 20-27 часов
|
|||
|
|
|
|||
|
|
### **ОБЩАЯ ОЦЕНКА: 111-144 часа**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. Приоритезация
|
|||
|
|
|
|||
|
|
### Высокий приоритет (MVP)
|
|||
|
|
1. ✅ Backend: Расширение моделей (Phase 1.1)
|
|||
|
|
2. ✅ Backend: Основные API endpoints (Phase 1.2)
|
|||
|
|
3. ✅ Frontend: StatisticsService (Phase 2.2)
|
|||
|
|
4. ✅ Frontend: ProfilePage редизайн (Phase 3.1)
|
|||
|
|
5. ✅ Frontend: Settings Page (Phase 4.1)
|
|||
|
|
|
|||
|
|
### Средний приоритет
|
|||
|
|
6. ⬜ Backend: Автоматический сбор (Phase 1.3)
|
|||
|
|
7. ⬜ Frontend: Words Statistics Page (Phase 3.2)
|
|||
|
|
8. ⬜ Frontend: Packs Statistics Page (Phase 3.3)
|
|||
|
|
9. ⬜ Frontend: Settings Integration (Phase 4.2)
|
|||
|
|
10. ⬜ Frontend: Stats Widgets (Phase 5.1)
|
|||
|
|
|
|||
|
|
### Низкий приоритет (Nice to have)
|
|||
|
|
11. ⬜ Frontend: Achievements Page (Phase 3.4)
|
|||
|
|
12. ⬜ Frontend: Animations (Phase 5.2)
|
|||
|
|
13. ⬜ Tests (Phase 6)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. Зависимости
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Phase 1.1 (Backend Models)
|
|||
|
|
↓
|
|||
|
|
Phase 1.2 (Backend API) + Phase 2.1 (Frontend HTTP)
|
|||
|
|
↓
|
|||
|
|
Phase 2.2 (Frontend Service) + Phase 2.3 (Frontend State)
|
|||
|
|
↓
|
|||
|
|
Phase 3.1 (Profile UI)
|
|||
|
|
↓
|
|||
|
|
Phase 3.2, 3.3, 3.4 (Statistics UI) + Phase 4.1 (Settings UI)
|
|||
|
|
↓
|
|||
|
|
Phase 1.3 (Auto tracking) + Phase 4.2 (Settings Integration)
|
|||
|
|
↓
|
|||
|
|
Phase 5.1, 5.2 (Visual improvements)
|
|||
|
|
↓
|
|||
|
|
Phase 6 (Testing)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. Технологии и библиотеки
|
|||
|
|
|
|||
|
|
### Backend
|
|||
|
|
- Dart 3.0+
|
|||
|
|
- Isar (database)
|
|||
|
|
- Shelf (HTTP)
|
|||
|
|
- GetIt + Injectable (DI)
|
|||
|
|
- Build Runner (codegen)
|
|||
|
|
|
|||
|
|
### Frontend
|
|||
|
|
- Flutter 3.x
|
|||
|
|
- yx_state + yx_scope (state management)
|
|||
|
|
- fl_chart (charts)
|
|||
|
|
- shimmer (loading)
|
|||
|
|
- confetti (celebrations)
|
|||
|
|
- lottie (animations)
|
|||
|
|
- shared_preferences (local storage)
|
|||
|
|
- go_router (navigation)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. Риски и митигация
|
|||
|
|
|
|||
|
|
### Риски:
|
|||
|
|
1. **Большой объем работы** - может занять много времени
|
|||
|
|
- Митигация: Разделить на фазы, начать с MVP
|
|||
|
|
|
|||
|
|
2. **Performance issues** - много данных статистики
|
|||
|
|
- Митигация: Пагинация, кэширование, оптимизация запросов
|
|||
|
|
|
|||
|
|
3. **Backend breaking changes** - изменения в API
|
|||
|
|
- Митигация: Версионирование API (v2), постепенная миграция
|
|||
|
|
|
|||
|
|
4. **UI complexity** - сложные графики и анимации
|
|||
|
|
- Митигация: Использовать проверенные библиотеки (fl_chart)
|
|||
|
|
|
|||
|
|
5. **Testing overhead** - много тестов для написания
|
|||
|
|
- Митигация: Писать тесты параллельно с разработкой
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 9. Acceptance Criteria
|
|||
|
|
|
|||
|
|
### Для MVP (Высокий приоритет):
|
|||
|
|
|
|||
|
|
✅ **Backend:**
|
|||
|
|
- [ ] Новые DTO созданы и работают
|
|||
|
|
- [ ] API endpoints для статистики работают
|
|||
|
|
- [ ] Данные корректно сохраняются в БД
|
|||
|
|
- [ ] Unit тесты покрывают новую логику
|
|||
|
|
|
|||
|
|
✅ **Frontend:**
|
|||
|
|
- [ ] ProfilePage показывает реальную статистику
|
|||
|
|
- [ ] Statistics виджеты красивые и responsive
|
|||
|
|
- [ ] Settings Page полностью функциональна
|
|||
|
|
- [ ] Настройки применяются в приложении
|
|||
|
|
- [ ] Данные загружаются без ошибок
|
|||
|
|
|
|||
|
|
✅ **Quality:**
|
|||
|
|
- [ ] Нет критических багов
|
|||
|
|
- [ ] Linter проходит
|
|||
|
|
- [ ] Основные тесты написаны
|
|||
|
|
- [ ] PROGRESS.md и TODO.md обновлены
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 10. Следующие шаги
|
|||
|
|
|
|||
|
|
1. **Создать задачи в TODO.md** - разбить план на конкретные задачи
|
|||
|
|
2. **Настроить workflow_state.md** - начать отслеживание прогресса
|
|||
|
|
3. **Начать с Phase 1.1** - расширение моделей данных
|
|||
|
|
4. **Итерировать** - работать фазами, тестировать каждую фазу
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Changelog
|
|||
|
|
|
|||
|
|
- **2025-11-08**: Initial plan created
|
|||
|
|
|