feat: architecture refactor — core layer, spreadsheet engine, envelope bidding, tests
CI / quality (push) Waiting to run
CI / quality (push) Waiting to run
- Add src/core/ (config, errors, events, http, observability, storage, query) - Add src/Spreadsheet/ engine with native POI backend and Excel bridge - Add Envelope C spreadsheet flow and tender bidding envelope modules - Consolidate components into src/components/, remove legacy Component/ and Hooks/ - Add registration state/validation, auth session guard, profile edit modules - Add unit tests across axios, redux, bidding, registration, encryption, core - Add CI workflow, docs (architecture, audit, DSC API spec), keystore example - Remove tracked keystore binary; ignore scripts.zip Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
9acec328a7
commit
1d7646d938
+32
-49
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Centralized permission broker — screens must request permissions through
|
||||
* these helpers, never react-native-permissions directly.
|
||||
*/
|
||||
import {
|
||||
check,
|
||||
request,
|
||||
@@ -6,93 +10,72 @@ import {
|
||||
openSettings,
|
||||
PERMISSIONS,
|
||||
Permission,
|
||||
checkNotifications,
|
||||
requestNotifications,
|
||||
} from 'react-native-permissions';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
import { logger } from '../core/observability/logger';
|
||||
|
||||
// Normalize permission for platform
|
||||
const normalizePermission = (perm: string): string => {
|
||||
const normalizePermission = (perm: string): Permission => {
|
||||
return Platform.select({
|
||||
ios: (PERMISSIONS.IOS as Record<string, string>)[perm] || perm,
|
||||
android: (PERMISSIONS.ANDROID as Record<string, string>)[perm] || perm,
|
||||
default: perm,
|
||||
})!;
|
||||
}) as Permission;
|
||||
};
|
||||
|
||||
|
||||
// Generic permission requester
|
||||
export const requestSinglePermission = async (
|
||||
permission: string
|
||||
): Promise<boolean> => {
|
||||
const normalized = normalizePermission(permission);
|
||||
|
||||
|
||||
const status: PermissionStatus = await check(normalized);
|
||||
|
||||
|
||||
if (status === RESULTS.GRANTED) {
|
||||
console.log(`✅ ${permission} already granted.`);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (status === RESULTS.BLOCKED) {
|
||||
console.log(`🚫 ${permission} is blocked. Prompt user to go to settings.`);
|
||||
logger.info('permissions', `${permission} is blocked — opening settings`);
|
||||
openSettings();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (status === RESULTS.DENIED || status === RESULTS.LIMITED) {
|
||||
const result: PermissionStatus = await request(normalized);
|
||||
if (result === RESULTS.GRANTED) {
|
||||
console.log(`✅ ${permission} granted after request.`);
|
||||
return true;
|
||||
} else {
|
||||
console.log(`❌ ${permission} denied.`);
|
||||
return false;
|
||||
}
|
||||
return result === RESULTS.GRANTED;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Fallback definition
|
||||
const POST_NOTIFICATIONS =
|
||||
Platform.OS === 'android' ? 'android.permission.POST_NOTIFICATIONS' : '';
|
||||
|
||||
|
||||
export const requestNotificationPermission = async (): Promise<boolean> => {
|
||||
|
||||
if (Platform.OS !== 'android' || !POST_NOTIFICATIONS) {
|
||||
console.log('Notification permission not needed on this platform.');
|
||||
if (Platform.OS !== 'android') {
|
||||
return true;
|
||||
}
|
||||
|
||||
const status: PermissionStatus = await check(POST_NOTIFICATIONS);
|
||||
|
||||
|
||||
const { status } = await checkNotifications();
|
||||
|
||||
if (status === RESULTS.GRANTED) {
|
||||
console.log('🔔 Notification permission already granted.');
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (status === RESULTS.BLOCKED) {
|
||||
console.log('🔕 Notification permission is blocked. Prompt user to open settings.');
|
||||
logger.info('permissions', 'notifications blocked — opening settings');
|
||||
openSettings();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (status === RESULTS.DENIED) {
|
||||
const result: PermissionStatus = await request(POST_NOTIFICATIONS);
|
||||
if (result === RESULTS.GRANTED) {
|
||||
console.log('✅ Notification permission granted.');
|
||||
return true;
|
||||
} else {
|
||||
console.log('❌ Notification permission denied.');
|
||||
return false;
|
||||
}
|
||||
const { status: result } = await requestNotifications(['alert', 'sound']);
|
||||
return result === RESULTS.GRANTED;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const isAnyPermissionGranted = async (permissions: Permission[]): Promise<boolean> => {
|
||||
for (const permission of permissions) {
|
||||
const result = await check(permission);
|
||||
@@ -105,12 +88,12 @@ export const isAnyPermissionGranted = async (permissions: Permission[]): Promise
|
||||
return false; // No permissions granted
|
||||
};
|
||||
|
||||
export async function checkPermission(permission:any) {
|
||||
export async function checkPermission(permission: Permission) {
|
||||
try {
|
||||
const result = await check(permission);
|
||||
return result === RESULTS.GRANTED;
|
||||
} catch (error) {
|
||||
console.warn('Permission check error:', error);
|
||||
logger.warn('permissions', 'permission check failed', { error: String(error) });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user