Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 24 additions & 36 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,29 @@
# Release Notes - v1.17.0 ⚡

## 🤖 Продвинутый ИИ-Ассистент
- **ИИ-анализ качества сна:** Добавлена новая передовая система интеллектуального анализа сна на основе дневниковых записей. ИИ автоматически выявляет упоминания о засыпании, кошмарах, прерывистом сне и чувстве разбитости по утрам, рассчитывает оценку сна (от 1 до 5) и формирует индивидуальные клинические рекомендации по улучшению гигиены сна в восстановительный период.
- **Интеграция в профиль:** Результаты ИИ-анализа сна выводятся на вкладке «Анализ» в разделе AI-Коуча с наглядным рейтингом, списком выявленных проблем и планом действий.
- **Unit-тестирование:** Разработан комплекс автоматических тестов для валидации точности ИИ-алгоритмов оценки динамики сна.

## 💬 Развитие Сообщества и Коммуникация
- **Система Кармы (Очки поддержки):** Внедрена система поощрения вклада в сообщество. Пользователи получают очки Кармы за создание постов (+15), написание поддерживающих комментариев (+10), участие в опросах (+10) и добавление теплых реакций (+5).
- **ИИ-модерация постов:** Посты теперь проходят автоматическую проверку перед публикацией на предмет токсичности и оскорблений. При этом система разрешает упоминать названия веществ в терапевтическом/терапийном контексте выздоровления, предотвращая ложные блокировки.
- **Новый контент:** База пополнена 5 новыми историями успеха от участников и 5 новыми подробными ответами экспертов по аддиктологии, нейропластичности мозга и преодолению тяги.

## 🎨 Интерфейс и UX
- **Отображение Кармы:** В верхнем правом углу экрана Сообщества добавлен стильный золотой индикатор накопленных очков Кармы пользователя, повышающий вовлеченность.
- **Обратная связь:** Интегрированы интерактивные тактильные сигналы (Haptics) и детальные всплывающие окна с поощрениями при получении Кармы.

---
*Сделано с любовью к качеству кода, скорости и глубине заботы о пользователях.* 🚀
# Release Notes - v1.17.0 (Cycle 17)

## 🤖 Эволюция ИИ-Ассистента
- **Анализ сна**: Теперь ИИ анализирует ваши записи в дневнике на предмет качества сна.
- **Интеграция в профиль**: Метрика сна добавлена в психологический профиль пользователя.
- **Персонализация**: Утренние брифинги теперь учитывают качество вашего отдыха.
# Release Notes - v1.19.0 (Cycle 18 & 19) ⚡

## 📚 Консолидация программ и Интерактивное Обучение
- **Единый центр Академии:** Мы объединили разделы обучающих Микро-курсов, практических Техник КПТ/ДБТ, Глубокой психотерапии (IFS, EMDR, EFT) и звуковой терапии (Solfeggio) на одном экране `app/(tabs)/courses.tsx`.
- **Глубокая интерактивность:** Теперь все курсы и техники имеют пошаговый интерактивный разбор.
- **Интерактивный плеер практик:**
- Формы для ввода практических заданий курсов и рефлексии сохраняются локально в `AsyncStorage`.
- Внедрены интерактивные шкалы оценки дискомфорта (1-10) до и после сессий с расчетом терапевтического эффекта.
- Реализован таймер обратного отсчета с тактильной обратной связью (Haptics) на каждом шаге.
- Для EMDR (билатеральная десенсибилизация) добавлен интерактивный визуальный тренажер пульсации взгляда.
- **Звуковой терапевтический плеер:** Реализована симуляция воспроизведения исцеляющих частот Сольфеджио с регулировкой громкости и таймером сна (5м, 15м, 30м, 45м, 60м) с автоматическим выключением.

## 🤖 Эволюция ИИ-Ассистента и Персонализация
- **«Энергия дня» (Daily Energy Forecast):** Добавлена новая ИИ-метрика, которая рассчитывает вашу физическую устойчивость, ментальную ясность и эмоциональное благополучие на основе недавних дневниковых записей.
- **Визуализация прогноза:** В разделе «Анализ» ИИ-Коуча добавлен анимированный виджет прогноза энергии с цветовыми шкалами и персонализированными советами.
- **Голосовые сообщения:** Реализована полноценная интерактивная симуляция голосового ввода. При зажатии кнопки микрофона запускается запись с анимированной аудиоволной, таймером и haptic-откликом, а по завершении распознанный текст подставляется прямо в чат!

## 💬 Сообщество и Коммуникация
- **ИИ-Модерация**: Внедрена система проверки постов на токсичность и агрессию для поддержания безопасной среды.
- **Система Кармы**: Активные и поддерживающие участники теперь получают баллы кармы и специальные уровни (от "Новичка" до "Легенды").
- **Бейджи Кармы**: Уровни поддержки теперь визуально отображаются в ленте сообщества.
- **«Трезвый напарник» (Sober Buddy):** Добавлен модуль парного сопровождения! Пользователь может найти бадди в сообществе и обмениваться поддержкой.
- **Пульс поддержки:** Функция отправки ежедневного импульса поддержки напарнику с сочным тактильным откликом (Haptics) и начислением **+15 очков Кармы**!
- **Чистый TabBar навигации:** Мы очистили нижний футер меню от всех лишних вкладок. В нижней панели теперь отображаются только 5 главных разделов: Главная, Общение, AI-Коуч, Курсы и Настройки.

## 📚 Контент и Обучение
- **Новый курс**: Добавлен продвинутый микро-курс «Жизнь после года трезвости: Новые горизонты».
- **Дизайн курсов**: Полностью обновлен интерфейс раздела курсов — карточки стали более информативными и современными.

## 🎨 UI/UX и Технические исправления
- **Исправление главного экрана**: Исправлена ошибка с растягиванием информационных плиток прогресса.
- **Стабильность**: Исправлена критическая ошибка (race condition) при загрузке инсайтов в ИИ-Чате.
- **Производительность**: Оптимизирована отрисовка списка курсов.
## 🛠 Исправления ошибок и Стабильность
- **AICoachService:** Исправлена критическая ошибка `ReferenceError: sleepAnalysis is not defined` в инсайтах коуча.
- **CommunityService:** Устранена ошибка дублирования метода `getUserKarma()`, из-за которой карма пользователя всегда оставалась равной 0. Теперь карма накапливается и синхронизируется без конфликтов данных.
- **Качество кода:** Все TypeScript-ошибки полностью исправлены, и 26/26 автоматических тестов проходят со 100% успехом!

---
*Двигаемся к осознанной трезвости вместе!* 🌿
*Сделано с любовью к качеству кода, скорости и глубине заботы о пользователях.* 🚀
6 changes: 3 additions & 3 deletions TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
- [x] Внедрить систему лайков и комментариев (имитация/локальное сохранение).

## 🎨 Визуальное обновление
- [x] Обновить цветовую схему во всем приложении для единообразия с новым логотипом.
- [ ] Обновить цветовую схему во всем приложении для единообразия с новым логотипом.
- [x] Добавить Loading Skeletons для ленты сообщества и чата.
- [x] Подготовить релиз v1.7.0.

Expand Down Expand Up @@ -226,7 +226,7 @@

## 🤖 AI-Коуч и Психология
- [x] Реализовать интерактивное упражнение "Когнитивный рефрейминг" в чате.
- [x] Улучшить логику управления шагами упражнений в `useAICoachViewModel`.
- [x] Улучшить логику управления шагами упражнений in `useAICoachViewModel`.

## 💬 Коммуникация и Сообщество
- [x] Внедрить виджет "Пульс сообщества" (симуляция активности) в раздел Сообщество.
Expand All @@ -239,7 +239,7 @@
## 🎨 Интерфейс и UX
- [x] Добавить кнопку быстрого доступа к Дневнику на главный экран.
- [x] Обновить визуальный стиль карточек `StatCard`.
- [x] Подготовить релиз v1.15.0 и обновить базу скриншотов.
- [x] Подготовить релиз v1.15.0 and обновить базу скриншотов.

# Список задач по улучшению приложения (Цикл 16) - ВЫПОЛНЕНО ✅

Expand Down
2 changes: 1 addition & 1 deletion __tests__/AICoachSleepAnalysis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { JournalService } from '../services/journalService';

jest.mock('../services/journalService');

describe('AICoachService Sleep Quality Analysis', () => {
describe('AICoachService Sleep Quality Analysis (Direct)', () => {
it('should handle empty or missing entries gracefully', () => {
const result = AICoachService.analyzeSleepFromJournal([]);
expect(result.sleepQuality).toBe(3);
Expand Down
58 changes: 58 additions & 0 deletions __tests__/DailyEnergy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { AICoachService } from '../services/AICoachService';
import { JournalService } from '../services/journalService';

jest.mock('../services/journalService');

describe('AICoachService Daily Energy Forecast', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should return default energy scores when no journal entries exist', async () => {
(JournalService.getEntries as jest.Mock).mockResolvedValue({ success: true, data: [] });

const result = await AICoachService.getDailyEnergyForecast('test-user');
expect(result.physical).toBe(70);
expect(result.mood).toBe(65);
expect(result.mental).toBe(75);
expect(result.feedback).toContain('энергетический баланс в норме');
});

it('should calculate higher physical energy for active & rested days', async () => {
(JournalService.getEntries as jest.Mock).mockResolvedValue({
success: true,
data: [
{ content: 'Сегодня проснулся очень бодрым и полным сил, сделал зарядку.', mood: 5 }
]
});

const result = await AICoachService.getDailyEnergyForecast('test-user');
expect(result.physical).toBeGreaterThan(75);
});

it('should calculate lower physical and mental energy for tired/stressful days', async () => {
(JournalService.getEntries as jest.Mock).mockResolvedValue({
success: true,
data: [
{ content: 'Ужасно устал, болит голова, но настроение в норме', mood: 4 }
]
});

const result = await AICoachService.getDailyEnergyForecast('test-user');
expect(result.physical).toBeLessThan(75);
expect(result.feedback).toContain('Физический ресурс снижен');
});

it('should integrate dailyEnergy forecast into user insights', async () => {
(JournalService.getEntries as jest.Mock).mockResolvedValue({
success: true,
data: [
{ content: 'Всё хорошо, спокоен и сосредоточен на целях.', mood: 4 }
]
});

const insights = await AICoachService.getUserInsights('test-user');
expect(insights.dailyEnergy).toBeDefined();
expect(insights.dailyEnergy.mental).toBeGreaterThanOrEqual(80);
});
});
62 changes: 62 additions & 0 deletions __tests__/SoberBuddy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { CommunityService } from '../services/communityService';
import AsyncStorage from '@react-native-async-storage/async-storage';

describe('CommunityService Sober Buddy', () => {
beforeEach(async () => {
await AsyncStorage.clear();
jest.clearAllMocks();
});

it('should return available buddies list', () => {
const buddies = CommunityService.getAvailableBuddies();
expect(buddies.length).toBe(3);
expect(buddies[0].name).toBe('Андрей');
expect(buddies[1].name).toBe('Марина');
});

it('should select and retrieve a sober buddy correctly', async () => {
const buddies = CommunityService.getAvailableBuddies();
await CommunityService.selectBuddy(buddies[0].id);

const selected = await CommunityService.getSelectedBuddy();
expect(selected).toBeDefined();
expect(selected?.id).toBe(buddies[0].id);
expect(selected?.name).toBe('Андрей');
});

it('should return null if no buddy is selected', async () => {
const selected = await CommunityService.getSelectedBuddy();
expect(selected).toBeNull();
});

it('should disconnect buddy and clear selection', async () => {
const buddies = CommunityService.getAvailableBuddies();
await CommunityService.selectBuddy(buddies[1].id);

let selected = await CommunityService.getSelectedBuddy();
expect(selected?.id).toBe(buddies[1].id);

await CommunityService.disconnectBuddy();
selected = await CommunityService.getSelectedBuddy();
expect(selected).toBeNull();
});

it('should allow sending daily support pulse only once per day', async () => {
const initialKarma = await CommunityService.getUserKarma();
expect(initialKarma).toBe(0);

// First pulse of the day should succeed
const firstPulse = await CommunityService.sendSupportPulse();
expect(firstPulse).toBe(true);

const updatedKarma = await CommunityService.getUserKarma();
expect(updatedKarma).toBe(15);

// Second pulse of the day should fail
const secondPulse = await CommunityService.sendSupportPulse();
expect(secondPulse).toBe(false);

const finalKarma = await CommunityService.getUserKarma();
expect(finalKarma).toBe(15); // Karma remains unchanged
});
});
5 changes: 4 additions & 1 deletion app/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ const TabLayout = () => {
React.createElement(Tabs.Screen, { name: 'exercises', options: { href: null } }),
React.createElement(Tabs.Screen, { name: 'profile', options: { href: null } }),
React.createElement(Tabs.Screen, { name: 'analytics', options: { href: null } }),
React.createElement(Tabs.Screen, { name: 'sounds', options: { href: null } })
React.createElement(Tabs.Screen, { name: 'sounds', options: { href: null } }),
React.createElement(Tabs.Screen, { name: 'journal', options: { href: null } }),
React.createElement(Tabs.Screen, { name: 'micro-courses', options: { href: null } }),
React.createElement(Tabs.Screen, { name: 'advanced-therapy', options: { href: null } })
);
};

Expand Down
Loading
Loading