Harden published curriculum and student flows

This commit is contained in:
Hamza-Ayed
2026-09-30 08:22:17 +03:00
parent e8163fe265
commit ce7b0fcf14
53 changed files with 4723 additions and 3317 deletions
+65 -14
View File
@@ -6,13 +6,57 @@ import 'package:flutter/foundation.dart';
class AppLogger {
AppLogger._();
static const _sensitiveKeyParts = [
'authorization',
'token',
'secret',
'password',
'phone',
'national',
'identity',
'otp',
'ticket',
'email',
'fingerprint',
'pin',
'address',
];
static bool _isSensitiveKey(String key) {
final normalized = key.toLowerCase().replaceAll(RegExp(r'[^a-z0-9]'), '');
return _sensitiveKeyParts.any(normalized.contains);
}
static dynamic _safeLogValue(dynamic value, {String key = ''}) {
if (_isSensitiveKey(key)) return '[REDACTED]';
if (value is Map) {
return value.map((k, v) => MapEntry(
k.toString(),
_safeLogValue(v, key: k.toString()),
));
}
if (value is List) {
return value.map((v) => _safeLogValue(v)).toList();
}
if (value is String && key.isEmpty) return '[TEXT OMITTED]';
return value;
}
static Uri _safeUri(Uri uri) {
final safeQuery = Map<String, String>.fromEntries(
uri.queryParameters.entries.where((entry) => !_isSensitiveKey(entry.key)),
);
return uri.replace(queryParameters: safeQuery.isEmpty ? null : safeQuery);
}
static void log(String message, {String tag = 'SAQEL'}) {
if (kDebugMode) {
debugPrint('[$tag] $message');
}
}
static void event(String name, {Map<String, dynamic>? details, String tag = 'EVENT'}) {
static void event(String name,
{Map<String, dynamic>? details, String tag = 'EVENT'}) {
if (!kDebugMode) return;
final buffer = StringBuffer();
buffer.write('⚡ [$tag] $name');
@@ -35,21 +79,23 @@ class AppLogger {
if (!kDebugMode) return;
final buffer = StringBuffer();
buffer.writeln('\n🌐 ─── [HTTP REQUEST] ──────────────────────────────────────────');
buffer.writeln(
'\n🌐 ─── [HTTP REQUEST] ──────────────────────────────────────────');
buffer.writeln('➡️ Method: $method');
buffer.writeln('🔗 URL: $uri');
buffer.writeln('🔗 URL: ${_safeUri(uri)}');
if (headers != null && headers.isNotEmpty) {
final safeHeaders = Map<String, String>.from(headers);
if (safeHeaders.containsKey('Authorization')) {
final auth = safeHeaders['Authorization']!;
safeHeaders['Authorization'] = auth.length > 20 ? '${auth.substring(0, 15)}...' : 'Bearer [REDACTED]';
safeHeaders['Authorization'] = '[REDACTED]';
}
safeHeaders.removeWhere((key, _) => _isSensitiveKey(key));
buffer.writeln('📋 Headers: ${jsonEncode(safeHeaders)}');
}
if (body != null) {
buffer.writeln('📦 Body: ${body is String ? body : jsonEncode(body)}');
buffer.writeln('📦 Body: ${jsonEncode(_safeLogValue(body))}');
}
buffer.writeln('───────────────────────────────────────────────────────────────');
buffer.writeln(
'───────────────────────────────────────────────────────────────');
debugPrint(buffer.toString());
}
@@ -66,24 +112,28 @@ class AppLogger {
final emoji = isSuccess ? '✅' : '⚠️';
final buffer = StringBuffer();
buffer.writeln('\n$emoji ─── [HTTP RESPONSE $statusCode] ────────────────────────────────');
buffer.writeln(
'\n$emoji ─── [HTTP RESPONSE $statusCode] ────────────────────────────────');
buffer.writeln('⬅️ Method: $method');
buffer.writeln('🔗 URL: $uri');
buffer.writeln('🔗 URL: ${_safeUri(uri)}');
if (duration != null) {
buffer.writeln('⏱️ Time: ${duration.inMilliseconds}ms');
}
if (responseBody != null) {
buffer.writeln('📦 Data: ${responseBody is String ? responseBody : jsonEncode(responseBody)}');
buffer.writeln('📦 Data: ${jsonEncode(_safeLogValue(responseBody))}');
}
buffer.writeln('───────────────────────────────────────────────────────────────');
buffer.writeln(
'───────────────────────────────────────────────────────────────');
debugPrint(buffer.toString());
}
static void error(String message, {dynamic error, StackTrace? stackTrace, String tag = 'ERROR'}) {
static void error(String message,
{dynamic error, StackTrace? stackTrace, String tag = 'ERROR'}) {
if (!kDebugMode) return;
final buffer = StringBuffer();
buffer.writeln('\n🚨 ─── [ERROR: $tag] ──────────────────────────────────────────');
buffer.writeln(
'\n🚨 ─── [ERROR: $tag] ──────────────────────────────────────────');
buffer.writeln('❌ Message: $message');
if (error != null) {
buffer.writeln('⚠️ Error: $error');
@@ -91,7 +141,8 @@ class AppLogger {
if (stackTrace != null) {
buffer.writeln('📍 Trace: \n$stackTrace');
}
buffer.writeln('───────────────────────────────────────────────────────────────');
buffer.writeln(
'───────────────────────────────────────────────────────────────');
debugPrint(buffer.toString());
}
}