feat: Gemini AI (doc OCR + face match) + role-assignment endpoints
- GeminiService (integrations/gemini, @Global): extractDocument (OCR fields) + faceMatch; graceful if no GEMINI_API_KEY - documents: face-match now real via Gemini; POST /admin/documents/:id/ocr extracts fields for CS auto-fill - roles: PATCH /admin/users/:id/role (admin) + POST /platform/users/role (bootstrap via x-platform-secret) - config: gemini + platform.secret; .env.example entries Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
import 'background_service.dart';
|
||||
|
||||
Future<void> requestNotificationPermission() async {
|
||||
if (Platform.isAndroid) {
|
||||
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||
if (androidInfo.version.sdkInt >= 33) {
|
||||
// Android 13+
|
||||
final status = await Permission.notification.request();
|
||||
if (!status.isGranted) {
|
||||
print('⚠️ إذن الإشعارات مرفوض');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// بعد الحصول على الإذن، ابدأ الخدمة
|
||||
await BackgroundServiceHelper.startService();
|
||||
}
|
||||
|
||||
class PermissionsHelper {
|
||||
/// طلب إذن الإشعارات على Android 13+
|
||||
static Future<bool> requestNotificationPermission() async {
|
||||
if (Platform.isAndroid) {
|
||||
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||
|
||||
// Android 13+ (API 33+) يحتاج إذن POST_NOTIFICATIONS
|
||||
if (androidInfo.version.sdkInt >= 33) {
|
||||
final status = await Permission.notification.request();
|
||||
|
||||
if (status.isDenied) {
|
||||
print('⚠️ إذن الإشعارات مرفوض');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (status.isPermanentlyDenied) {
|
||||
print('⚠️ إذن الإشعارات مرفوض بشكل دائم - افتح الإعدادات');
|
||||
await openAppSettings();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// طلب جميع الإذونات المطلوبة
|
||||
static Future<bool> requestAllPermissions() async {
|
||||
// إذن الإشعارات أولاً
|
||||
bool notificationGranted = await requestNotificationPermission();
|
||||
if (!notificationGranted) return false;
|
||||
|
||||
// إذن الموقع
|
||||
final locationStatus = await Permission.location.request();
|
||||
if (!locationStatus.isGranted) {
|
||||
print('⚠️ إذن الموقع مرفوض');
|
||||
return false;
|
||||
}
|
||||
|
||||
// إذن الموقع في الخلفية
|
||||
if (Platform.isAndroid) {
|
||||
final bgLocationStatus = await Permission.locationAlways.request();
|
||||
if (!bgLocationStatus.isGranted) {
|
||||
print('⚠️ إذن الموقع في الخلفية مرفوض');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user