diff --git a/devtools_options.yaml b/devtools_options.yaml
new file mode 100644
index 0000000..fa0b357
--- /dev/null
+++ b/devtools_options.yaml
@@ -0,0 +1,3 @@
+description: This file stores settings for Dart & Flutter DevTools.
+documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
+extensions:
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
index b5586f2..391a902 100644
--- a/ios/Flutter/AppFrameworkInfo.plist
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -1,26 +1,24 @@
-
-
-
-
- CFBundleDevelopmentRegion
- en
- CFBundleExecutable
- App
- CFBundleIdentifier
- io.flutter.flutter.app
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- App
- CFBundlePackageType
- FMWK
- CFBundleShortVersionString
- 1.0
- CFBundleSignature
- ????
- CFBundleVersion
- 1.0
- MinimumOSVersion
- 13.0
-
-
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+
+
diff --git a/lib/app/router/app_router.dart b/lib/app/router/app_router.dart
index 4b7fc9b..b00eb42 100644
--- a/lib/app/router/app_router.dart
+++ b/lib/app/router/app_router.dart
@@ -145,7 +145,10 @@ GoRouter goRouter(Ref ref) {
GoRoute(
path: 'chat',
parentNavigatorKey: _rootNavigatorKey,
- builder: (context, state) => const ChatScreen(),
+ builder: (context, state) {
+ final initialPrompt = state.extra as String?;
+ return ChatScreen(initialPrompt: initialPrompt);
+ },
),
],
),
diff --git a/lib/features/chat/presentation/chat_screen.dart b/lib/features/chat/presentation/chat_screen.dart
index 41982c8..5a1dda7 100644
--- a/lib/features/chat/presentation/chat_screen.dart
+++ b/lib/features/chat/presentation/chat_screen.dart
@@ -6,7 +6,9 @@ import 'package:learning_coach/shared/data/providers.dart';
import 'package:learning_coach/shared/models/models.dart';
class ChatScreen extends ConsumerStatefulWidget {
- const ChatScreen({super.key});
+ final String? initialPrompt;
+
+ const ChatScreen({super.key, this.initialPrompt});
@override
ConsumerState createState() => _ChatScreenState();
@@ -17,6 +19,31 @@ class _ChatScreenState extends ConsumerState {
final ScrollController _scrollController = ScrollController();
bool _isSending = false;
+ @override
+ void initState() {
+ super.initState();
+ if (widget.initialPrompt != null) {
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ _sendInitialMessage(widget.initialPrompt!);
+ });
+ }
+ }
+
+ Future _sendInitialMessage(String text) async {
+ setState(() => _isSending = true);
+ try {
+ // Add user message first (optional, maybe we don't want to show the long prompt?)
+ // For now let's show it so user knows context is sent.
+ // Alternatively, we could send it as a "system" message or just directly call provider.
+ await ref.read(chatMessagesProvider.notifier).sendMessage(text);
+ Future.delayed(const Duration(milliseconds: 100), _scrollToBottom);
+ } finally {
+ if (mounted) {
+ setState(() => _isSending = false);
+ }
+ }
+ }
+
@override
void dispose() {
_controller.dispose();
diff --git a/lib/features/home/presentation/widgets/home_widgets.dart b/lib/features/home/presentation/widgets/home_widgets.dart
index debb9eb..8f3ebcc 100644
--- a/lib/features/home/presentation/widgets/home_widgets.dart
+++ b/lib/features/home/presentation/widgets/home_widgets.dart
@@ -5,7 +5,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:learning_coach/core/constants/app_strings.dart';
import 'package:learning_coach/core/providers/locale_provider.dart';
+import 'package:learning_coach/shared/data/api_stats_repository.dart';
import 'package:learning_coach/shared/data/providers.dart';
+import 'package:learning_coach/shared/models/models.dart';
// --- Today Plan Card ---
class TodayPlanCard extends ConsumerStatefulWidget {
@@ -545,6 +547,7 @@ class _CoachTipCardState extends ConsumerState
with SingleTickerProviderStateMixin {
late AnimationController _floatController;
late Animation _floatAnimation;
+ bool _isLoading = false;
@override
void initState() {
@@ -564,6 +567,110 @@ class _CoachTipCardState extends ConsumerState
super.dispose();
}
+ Future _handleTap() async {
+ if (_isLoading) return;
+
+ setState(() => _isLoading = true);
+
+ try {
+ // 1. Fetch Data
+ final now = DateTime.now();
+ final today = DateTime(now.year, now.month, now.day);
+
+ final dailyStatsList = await ref.read(dailyStatsProvider.future);
+ final sessions = await ref
+ .read(apiStudySessionRepositoryProvider)
+ .getSessions();
+ final goals = await ref.read(goalsProvider.future);
+ final userStats = ref.read(userStatsProvider);
+
+ // 2. Filter & Aggregate
+ final todayStats = dailyStatsList.firstWhere(
+ (s) => s.date == today.toIso8601String().split('T')[0],
+ orElse: () => DailyStats(date: '', minutes: 0, sessions: 0),
+ );
+
+ final todaySessions = sessions.where((s) {
+ final date = DateTime(
+ s.startTime.year,
+ s.startTime.month,
+ s.startTime.day,
+ );
+ return date.isAtSameMomentAs(today);
+ }).toList();
+
+ // 3. Construct Detailed Prompt
+ final buffer = StringBuffer();
+ buffer.writeln(
+ 'Merhaba Koç, benim "Learning Coach" asistanımsın. İşte bugünkü durumum:',
+ );
+
+ buffer.writeln('\n👤 **Kullanıcı Profili:**');
+ buffer.writeln(
+ '- Seviye: ${userStats.level} (${userStats.stage.name.toUpperCase()})',
+ );
+ buffer.writeln(
+ '- XP: ${userStats.xp} / ${userStats.xpRequiredForNextLevel}',
+ );
+ buffer.writeln('- Toplam Altın: ${userStats.gold}');
+
+ buffer.writeln('\n📅 **Bugünkü Özet:**');
+ buffer.writeln('- Toplam Çalışma: ${todayStats.minutes} dakika');
+ buffer.writeln('- Oturum Sayısı: ${todayStats.sessions}');
+
+ if (todaySessions.isNotEmpty) {
+ buffer.writeln('\n📝 **Oturum Detayları:**');
+ for (final session in todaySessions) {
+ final goal = goals.firstWhere(
+ (g) => g.id == session.goalId,
+ orElse: () => Goal(title: 'Bilinmeyen Hedef', description: ''),
+ );
+
+ final timeStr =
+ "${session.startTime.hour.toString().padLeft(2, '0')}:${session.startTime.minute.toString().padLeft(2, '0')}";
+
+ buffer.write('- **$timeStr** | ${goal.title}');
+ buffer.write(' (${session.durationMinutes} dk)');
+
+ if (session.quizScore != null) {
+ buffer.write(' | Quiz Başarısı: %${session.quizScore}');
+ }
+
+ // Efficiency Check (if actual duration is tracked)
+ if (session.actualDurationSeconds != null) {
+ final actualMins = (session.actualDurationSeconds! / 60).round();
+ if (actualMins < session.durationMinutes) {
+ buffer.write(' | ⚡ Verimli (Erken bitti)');
+ } else if (actualMins > session.durationMinutes + 5) {
+ buffer.write(' | 🐢 Biraz uzadı');
+ }
+ }
+ buffer.writeln();
+ }
+ } else {
+ buffer.writeln('\nHenüz detaylı bir çalışma kaydım yok.');
+ }
+
+ buffer.writeln(
+ '\nLütfen bu verilere dayanarak bana özel, motive edici ve gelişim odaklı bir tavsiye ver. Eğer verimsiz geçtiyse nazikçe uyar, iyiyse kutla.',
+ );
+
+ if (!mounted) return;
+
+ // 4. Navigate
+ context.push('/home/chat', extra: buffer.toString());
+ } catch (e) {
+ debugPrint('Error preparing coach tip: $e');
+ if (mounted) {
+ context.push('/home/chat'); // Fallback to empty chat
+ }
+ } finally {
+ if (mounted) {
+ setState(() => _isLoading = false);
+ }
+ }
+ }
+
@override
Widget build(BuildContext context) {
final locale = ref.watch(localeProvider);
@@ -606,7 +713,7 @@ class _CoachTipCardState extends ConsumerState
child: Material(
color: Colors.transparent,
child: InkWell(
- onTap: () => context.push('/home/chat'),
+ onTap: _isLoading ? null : _handleTap,
borderRadius: BorderRadius.circular(28),
child: Padding(
padding: const EdgeInsets.all(24.0),
@@ -666,11 +773,20 @@ class _CoachTipCardState extends ConsumerState
color: Colors.white.withOpacity(0.2),
shape: BoxShape.circle,
),
- child: const Icon(
- Icons.auto_awesome_rounded,
- color: Colors.white,
- size: 16,
- ),
+ child: _isLoading
+ ? const SizedBox(
+ width: 16,
+ height: 16,
+ child: CircularProgressIndicator(
+ strokeWidth: 2,
+ color: Colors.white,
+ ),
+ )
+ : const Icon(
+ Icons.auto_awesome_rounded,
+ color: Colors.white,
+ size: 16,
+ ),
),
],
),
diff --git a/lib/shared/services/api_service.dart b/lib/shared/services/api_service.dart
index d5b329e..64eebf2 100644
--- a/lib/shared/services/api_service.dart
+++ b/lib/shared/services/api_service.dart
@@ -216,6 +216,11 @@ class ApiService {
static String get baseUrlLLM {
// 1. Önce .env dosyasında tanımlı mı diye bakıyoruz
final envUrl = dotenv.env['LLM_BASE_URL'];
+ final debugModeLLM = dotenv.env['DEBUG_MODE_LLM'];
+
+ if (debugModeLLM == 'true') {
+ return 'http://127.0.0.1:8000';
+ }
if (envUrl != null && envUrl.isNotEmpty) {
return envUrl;
diff --git a/llm_backend/app/__init__.py b/llm_backend/app/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/llm_backend/app/api/__init__.py b/llm_backend/app/api/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/llm_backend/app/api/chat.py b/llm_backend/app/api/chat.py
index bbaab72..f044d49 100644
--- a/llm_backend/app/api/chat.py
+++ b/llm_backend/app/api/chat.py
@@ -1,3 +1,4 @@
+import time
from fastapi import APIRouter, HTTPException
from app.models.chat_models import ChatRequest, ChatResponse
from app.services.llm_service import ask_llama
@@ -7,10 +8,25 @@
@router.post("", response_model=ChatResponse)
def chat(req: ChatRequest):
+ start_time = time.time()
try:
- logger.info(f"Kullanıcı mesajı: {req.message}")
+ # Determine chat type based on message content
+ chat_type = "COACH_TIP" if "Merhaba Koç, benim \"Learning Coach\" asistanımsın" in req.message else "GENERAL_CHAT"
+
+ logger.info(f"[{chat_type}] REQUEST: {req.message[:50]}...")
+
answer = ask_llama(req.message)
+
+ duration_ms = (time.time() - start_time) * 1000
+ logger.info(f"[{chat_type}] RESPONSE ({duration_ms:.2f}ms): {answer[:50]}...")
+
+ # Explicitly log specifically for the test requirement
+ logger.info(f"TEST_LOG | {chat_type} | {duration_ms:.2f}ms | Q: {req.message[:100]}... | A: {answer[:100]}...")
+
return ChatResponse(answer=answer)
+ except Exception as e:
+ logger.error(f"Chat error: {str(e)}")
+ raise HTTPException(status_code=500, detail="LLM error")
except Exception as e:
logger.error(str(e))
diff --git a/llm_backend/app/core/__init__.py b/llm_backend/app/core/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/llm_backend/app/core/logger.py b/llm_backend/app/core/logger.py
index 58f7234..124f131 100644
--- a/llm_backend/app/core/logger.py
+++ b/llm_backend/app/core/logger.py
@@ -1,8 +1,25 @@
import logging
+import os
+from datetime import datetime
+# Logs directory setup
+LOG_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "logs")
+os.makedirs(LOG_DIR, exist_ok=True)
+
+# Generate a unique filename for this session
+session_timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+log_filename = f"chat_log_{session_timestamp}.txt"
+log_filepath = os.path.join(LOG_DIR, log_filename)
+
+# Configure logging
logging.basicConfig(
level=logging.INFO,
- format="%(asctime)s | %(levelname)s | %(message)s"
+ format="%(asctime)s | %(levelname)s | %(message)s",
+ handlers=[
+ logging.StreamHandler(), # Console output
+ logging.FileHandler(log_filepath, encoding='utf-8') # File output
+ ]
)
logger = logging.getLogger("AI-COACH")
+logger.info(f"Logging started. Log file: {log_filepath}")
diff --git a/llm_backend/app/models/__init__.py b/llm_backend/app/models/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/llm_backend/app/services/__init__.py b/llm_backend/app/services/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/llm_backend/logs/chat_log_20260216_020724.txt b/llm_backend/logs/chat_log_20260216_020724.txt
new file mode 100644
index 0000000..718ae3d
--- /dev/null
+++ b/llm_backend/logs/chat_log_20260216_020724.txt
@@ -0,0 +1 @@
+2026-02-16 02:07:24,308 | INFO | Logging started. Log file: /Users/utar/Documents/GitHub/LearningCoachApp/llm_backend/logs/chat_log_20260216_020724.txt
diff --git a/llm_backend/logs/chat_log_20260216_020739.txt b/llm_backend/logs/chat_log_20260216_020739.txt
new file mode 100644
index 0000000..3a935af
--- /dev/null
+++ b/llm_backend/logs/chat_log_20260216_020739.txt
@@ -0,0 +1,7 @@
+2026-02-16 02:07:39,831 | INFO | Logging started. Log file: /Users/utar/Documents/GitHub/LearningCoachApp/llm_backend/logs/chat_log_20260216_020739.txt
+2026-02-16 02:11:00,246 | INFO | [GENERAL_CHAT] REQUEST: Merhaba, nasılsın?...
+2026-02-16 02:11:00,246 | INFO | LLAMA isteği gönderildi
+2026-02-16 02:11:00,251 | ERROR | Chat error: HTTPConnectionPool(host='localhost', port=11434): Max retries exceeded with url: /api/chat (Caused by NewConnectionError("HTTPConnection(host='localhost', port=11434): Failed to establish a new connection: [Errno 61] Connection refused"))
+2026-02-16 02:11:00,347 | INFO | [COACH_TIP] REQUEST: Merhaba Koç, benim "Learning Coach" asistanımsın. ...
+2026-02-16 02:11:00,347 | INFO | LLAMA isteği gönderildi
+2026-02-16 02:11:00,348 | ERROR | Chat error: HTTPConnectionPool(host='localhost', port=11434): Max retries exceeded with url: /api/chat (Caused by NewConnectionError("HTTPConnection(host='localhost', port=11434): Failed to establish a new connection: [Errno 61] Connection refused"))
diff --git a/llm_backend/logs/chat_log_20260216_021428.txt b/llm_backend/logs/chat_log_20260216_021428.txt
new file mode 100644
index 0000000..a244431
--- /dev/null
+++ b/llm_backend/logs/chat_log_20260216_021428.txt
@@ -0,0 +1,5 @@
+2026-02-16 02:14:28,764 | INFO | Logging started. Log file: /Users/utar/Documents/GitHub/LearningCoachApp/llm_backend/logs/chat_log_20260216_021428.txt
+2026-02-16 02:14:44,040 | INFO | [GENERAL_CHAT] REQUEST: Merhaba, nasılsın?...
+2026-02-16 02:14:44,040 | INFO | LLAMA isteği gönderildi
+2026-02-16 02:14:45,292 | INFO | [GENERAL_CHAT] RESPONSE (1251.70ms): Nasım iyi. Ne soruyor musun?...
+2026-02-16 02:14:45,292 | INFO | TEST_LOG | GENERAL_CHAT | 1251.70ms | Q: Merhaba, nasılsın?... | A: Nasım iyi. Ne soruyor musun?...
diff --git a/llm_backend/logs/chat_log_20260216_021720.txt b/llm_backend/logs/chat_log_20260216_021720.txt
new file mode 100644
index 0000000..f6ea3fd
--- /dev/null
+++ b/llm_backend/logs/chat_log_20260216_021720.txt
@@ -0,0 +1 @@
+2026-02-16 02:17:20,330 | INFO | Logging started. Log file: /Users/utar/Documents/GitHub/LearningCoachApp/llm_backend/logs/chat_log_20260216_021720.txt
diff --git a/pubspec.lock b/pubspec.lock
index 1707247..10164c5 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -5,34 +5,34 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
- sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f
+ sha256: c209688d9f5a5f26b2fb47a188131a6fb9e876ae9e47af3737c0b4f58a93470d
url: "https://pub.dev"
source: hosted
- version: "85.0.0"
+ version: "91.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
- sha256: f4ad0fea5f102201015c9aae9d93bc02f75dd9491529a8c21f88d17a8523d44c
+ sha256: a40a0cee526a7e1f387c6847bd8a5ccbf510a75952ef8a28338e989558072cb0
url: "https://pub.dev"
source: hosted
- version: "7.6.0"
+ version: "8.4.0"
analyzer_buffer:
dependency: transitive
description:
name: analyzer_buffer
- sha256: f7833bee67c03c37241c67f8741b17cc501b69d9758df7a5a4a13ed6c947be43
+ sha256: aba2f75e63b3135fd1efaa8b6abefe1aa6e41b6bd9806221620fa48f98156033
url: "https://pub.dev"
source: hosted
- version: "0.1.10"
+ version: "0.1.11"
analyzer_plugin:
dependency: transitive
description:
name: analyzer_plugin
- sha256: a5ab7590c27b779f3d4de67f31c4109dbe13dd7339f86461a6f2a8ab2594d8ce
+ sha256: "08cfefa90b4f4dd3b447bda831cecf644029f9f8e22820f6ee310213ebe2dd53"
url: "https://pub.dev"
source: hosted
- version: "0.13.4"
+ version: "0.13.10"
args:
dependency: transitive
description:
@@ -125,10 +125,10 @@ packages:
dependency: transitive
description:
name: characters
- sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
+ sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
url: "https://pub.dev"
source: hosted
- version: "1.4.0"
+ version: "1.4.1"
checked_yaml:
dependency: transitive
description:
@@ -221,26 +221,26 @@ packages:
dependency: transitive
description:
name: custom_lint_core
- sha256: cc4684d22ca05bf0a4a51127e19a8aea576b42079ed2bc9e956f11aaebe35dd1
+ sha256: "85b339346154d5646952d44d682965dfe9e12cae5febd706f0db3aa5010d6423"
url: "https://pub.dev"
source: hosted
- version: "0.8.0"
+ version: "0.8.1"
custom_lint_visitor:
dependency: transitive
description:
name: custom_lint_visitor
- sha256: "4a86a0d8415a91fbb8298d6ef03e9034dc8e323a599ddc4120a0e36c433983a2"
+ sha256: "91f2a81e9f0abb4b9f3bb529f78b6227ce6050300d1ae5b1e2c69c66c7a566d8"
url: "https://pub.dev"
source: hosted
- version: "1.0.0+7.7.0"
+ version: "1.0.0+8.4.0"
dart_style:
dependency: transitive
description:
name: dart_style
- sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb"
+ sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b
url: "https://pub.dev"
source: hosted
- version: "3.1.1"
+ version: "3.1.3"
dbus:
dependency: transitive
description:
@@ -544,14 +544,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.5"
- js:
- dependency: transitive
- description:
- name: js
- sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
- url: "https://pub.dev"
- source: hosted
- version: "0.7.2"
json_annotation:
dependency: "direct main"
description:
@@ -612,18 +604,18 @@ packages:
dependency: transitive
description:
name: matcher
- sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
+ sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
url: "https://pub.dev"
source: hosted
- version: "0.12.17"
+ version: "0.12.18"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
- sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
+ sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
url: "https://pub.dev"
source: hosted
- version: "0.11.1"
+ version: "0.13.0"
meta:
dependency: transitive
description:
@@ -644,10 +636,10 @@ packages:
dependency: transitive
description:
name: mockito
- sha256: "2314cbe9165bcd16106513df9cf3c3224713087f09723b128928dc11a4379f99"
+ sha256: a45d1aa065b796922db7b9e7e7e45f921aed17adf3a8318a1f47097e7e695566
url: "https://pub.dev"
source: hosted
- version: "5.5.0"
+ version: "5.6.3"
node_preamble:
dependency: transitive
description:
@@ -897,10 +889,10 @@ packages:
dependency: transitive
description:
name: source_gen
- sha256: "7b19d6ba131c6eb98bfcbf8d56c1a7002eba438af2e7ae6f8398b2b0f4f381e3"
+ sha256: "1d562a3c1f713904ebbed50d2760217fd8a51ca170ac4b05b0db490699dbac17"
url: "https://pub.dev"
source: hosted
- version: "3.1.0"
+ version: "4.2.0"
source_helper:
dependency: transitive
description:
@@ -985,26 +977,26 @@ packages:
dependency: transitive
description:
name: test
- sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7"
+ sha256: "77cc98ea27006c84e71a7356cf3daf9ddbde2d91d84f77dbfe64cf0e4d9611ae"
url: "https://pub.dev"
source: hosted
- version: "1.26.3"
+ version: "1.28.0"
test_api:
dependency: transitive
description:
name: test_api
- sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
+ sha256: "19a78f63e83d3a61f00826d09bc2f60e191bf3504183c001262be6ac75589fb8"
url: "https://pub.dev"
source: hosted
- version: "0.7.7"
+ version: "0.7.8"
test_core:
dependency: transitive
description:
name: test_core
- sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0"
+ sha256: f1072617a6657e5fc09662e721307f7fb009b4ed89b19f47175d11d5254a62d4
url: "https://pub.dev"
source: hosted
- version: "0.6.12"
+ version: "0.6.14"
timing:
dependency: transitive
description:
diff --git a/test_data/test_questions.md b/test_data/test_questions.md
new file mode 100644
index 0000000..a16866f
--- /dev/null
+++ b/test_data/test_questions.md
@@ -0,0 +1,79 @@
+# Test Soruları ve Senaryoları
+
+## Genel Chat Soruları
+Bu soruların amacı genel bilgi ve sohbet yeteneğini test etmektir.
+1. İstanbul'un fethi ne zaman gerçekleşti ve hangi padişah tarafından yapıldı?
+2. Kuantum dolanıklığı nedir? Basitçe açıklar mısın?
+3. Bana Python ile bir Fibonacci dizisi hesaplayan fonksiyon yazar mısın?
+4. Motivasyonumu kaybettim, bana çalışmak için 3 neden söyler misin?
+5. Dünyanın en derin çukuru neresidir ve derinliği ne kadardır?
+6. Yapay zeka gelecekte meslekleri nasıl etkileyecek?
+7. Sağlıklı beslenmek için günde kaç öğün yemeliyim?
+8. Bana kısa ve komik bir fıkra anlatır mısın?
+9. "Sefiller" kitabının yazarı kimdir?
+10. Mars'a insanlı yolculuk ne zaman mümkün olabilir?
+
+---
+
+## Koç Tavsiyesi (Coach Tip) Senaryoları
+Aşağıdaki metinler, uygulamanın arka planda `CoachTipCard` üzerinden gönderdiği prompt yapılarını simüle eder. Test ederken bu metinleri Chat ekranına yapıştırarak veya API request body olarak kullanarak test edebilirsiniz.
+
+### Senaryo 1: Yeni Başlayan (Hiç Veri Yok)
+```text
+Merhaba Koç, benim "Learning Coach" asistanımsın. İşte bugünkü durumum:
+
+👤 **Kullanıcı Profili:**
+- Seviye: 1 (TOHUM)
+- XP: 0 / 100
+- Toplam Altın: 0
+
+📅 **Bugünkü Özet:**
+- Toplam Çalışma: 0 dakika
+- Oturum Sayısı: 0
+
+Henüz detaylı bir çalışma kaydım yok.
+
+Lütfen bu verilere dayanarak bana özel, motive edici ve gelişim odaklı bir tavsiye ver. Eğer verimsiz geçtiyse nazikçe uyar, iyiyse kutla.
+```
+
+### Senaryo 2: Verimli Bir Gün (Çok Çalışmış)
+```text
+Merhaba Koç, benim "Learning Coach" asistanımsın. İşte bugünkü durumum:
+
+👤 **Kullanıcı Profili:**
+- Seviye: 5 (FİDAN)
+- XP: 450 / 500
+- Toplam Altın: 320
+
+📅 **Bugünkü Özet:**
+- Toplam Çalışma: 180 dakika
+- Oturum Sayısı: 4
+
+📝 **Oturum Detayları:**
+- **09:00** | Matematik Çalışması (50 dk) | Quiz Başarısı: %85 | ⚡ Verimli (Erken bitti)
+- **11:00** | Tarih Okuması (40 dk)
+- **14:00** | Fizik Problemleri (60 dk) | 🐢 Biraz uzadı
+- **16:00** | İngilizce Kelime (30 dk) | Quiz Başarısı: %95
+
+Lütfen bu verilere dayanarak bana özel, motive edici ve gelişim odaklı bir tavsiye ver. Eğer verimsiz geçtiyse nazikçe uyar, iyiyse kutla.
+```
+
+### Senaryo 3: Zorlanan Kullanıcı (Düşük Başarı)
+```text
+Merhaba Koç, benim "Learning Coach" asistanımsın. İşte bugünkü durumum:
+
+👤 **Kullanıcı Profili:**
+- Seviye: 3 (FİLİZ)
+- XP: 210 / 300
+- Toplam Altın: 150
+
+📅 **Bugünkü Özet:**
+- Toplam Çalışma: 45 dakika
+- Oturum Sayısı: 2
+
+📝 **Oturum Detayları:**
+- **10:00** | Kimya Konu Anlatımı (30 dk) | Quiz Başarısı: %40
+- **13:30** | Biyoloji Testi (15 dk) | Quiz Başarısı: %30
+
+Lütfen bu verilere dayanarak bana özel, motive edici ve gelişim odaklı bir tavsiye ver. Eğer verimsiz geçtiyse nazikçe uyar, iyiyse kutla.
+```