- 결재 상세 다이얼로그에 전표 요약·라인·고객 섹션을 추가하고 현재 사용자 단계 강조 및 비고 입력 검증을 개선함 - 대시보드·결재 목록에서 전표 리포지토리와 AuthService를 주입해 상세 진입과 결재 관리 이동 버튼을 제공함 - StockTransactionApprovalInput이 template/steps를 config 노드로 직렬화하도록 변경하고 통합 테스트를 갱신함 - scope 권한 문자열을 리소스권으로 변환하는 PermissionScopeMapper와 단위 테스트를 추가하고 AuthPermission을 연동함 - 재고 메뉴 정렬, 상세 컨트롤러 오류 리셋, 요청자 자동완성 상태 동기화 등 주변 UI 버그를 수정하고 테스트를 보강함
72 lines
2.5 KiB
Dart
72 lines
2.5 KiB
Dart
import '../../../../core/permissions/permission_manager.dart';
|
|
import '../../../../core/permissions/permission_resources.dart';
|
|
import '../../../../core/permissions/permission_scope_mapper.dart';
|
|
|
|
/// 로그인 응답에서 내려오는 단일 권한(리소스 + 액션 목록)을 표현한다.
|
|
class AuthPermission {
|
|
const AuthPermission({required this.resource, required this.actions});
|
|
|
|
/// 서버가 반환한 리소스 식별자 (예: `/stock-transactions`)
|
|
final String resource;
|
|
|
|
/// 허용된 액션 문자열 목록 (예: `view`, `create`)
|
|
final List<String> actions;
|
|
|
|
/// [PermissionManager]가 이해할 수 있는 포맷으로 변환한다.
|
|
Map<String, Set<PermissionAction>> toPermissionMap() {
|
|
final normalized = PermissionResources.normalize(resource);
|
|
final actionSet = <PermissionAction>{};
|
|
final isScope = normalized.startsWith('scope:');
|
|
for (final raw in actions) {
|
|
final parsed = _parseAction(raw);
|
|
if (parsed == null) {
|
|
continue;
|
|
}
|
|
actionSet.add(parsed);
|
|
}
|
|
|
|
final mappings = <String, Set<PermissionAction>>{};
|
|
if (isScope) {
|
|
final scopeMap = PermissionScopeMapper.map(normalized);
|
|
if (scopeMap != null && scopeMap.isNotEmpty) {
|
|
mappings.addAll(scopeMap);
|
|
}
|
|
}
|
|
|
|
if (actionSet.isEmpty) {
|
|
if (isScope) {
|
|
final fallback = {PermissionAction.view};
|
|
mappings.putIfAbsent(normalized, () => <PermissionAction>{})
|
|
.addAll(fallback);
|
|
return mappings;
|
|
}
|
|
return mappings;
|
|
}
|
|
|
|
mappings.putIfAbsent(normalized, () => <PermissionAction>{})
|
|
.addAll(actionSet);
|
|
return mappings;
|
|
}
|
|
|
|
/// 백엔드 권한 문자열을 [PermissionAction]으로 변환한다.
|
|
///
|
|
/// - 백엔드 스펙(`create`, `read`, `update`, `delete`, `restore`, `approve`)과
|
|
/// 프런트 내부 별칭(`view`, `edit`)을 모두 인식한다.
|
|
/// - 인식할 수 없는 문자열은 무시해 잘못된 권한이 섞여도 앱이 중단되지 않도록 한다.
|
|
PermissionAction? _parseAction(String raw) {
|
|
final key = raw.trim().toLowerCase();
|
|
return _actionMap[key];
|
|
}
|
|
|
|
static const Map<String, PermissionAction> _actionMap = {
|
|
'view': PermissionAction.view,
|
|
'read': PermissionAction.view,
|
|
'create': PermissionAction.create,
|
|
'edit': PermissionAction.edit,
|
|
'update': PermissionAction.edit,
|
|
'delete': PermissionAction.delete,
|
|
'restore': PermissionAction.restore,
|
|
'approve': PermissionAction.approve,
|
|
};
|
|
}
|