결재 API 계약 보완 및 테스트 정리

This commit is contained in:
JiWoong Sul
2025-10-16 18:53:22 +09:00
parent 9e2244f260
commit efed3c1a6f
44 changed files with 1969 additions and 293 deletions

View File

@@ -11,6 +11,9 @@ import '../../../../core/network/api_error.dart';
import '../../../../core/network/failure.dart';
import '../../../../core/permissions/permission_manager.dart';
import '../../../../core/permissions/permission_resources.dart';
import '../../../auth/application/auth_service.dart';
import '../../../auth/domain/entities/auth_session.dart';
import '../../../auth/domain/entities/login_request.dart';
import '../../../masters/group/domain/entities/group.dart';
import '../../../masters/group/domain/repositories/group_repository.dart';
import '../../../masters/group_permission/application/permission_synchronizer.dart';
@@ -49,8 +52,6 @@ class _LoginPageState extends State<LoginPage> {
final id = idController.text.trim();
final password = passwordController.text.trim();
await Future<void>.delayed(const Duration(milliseconds: 600));
if (id.isEmpty || password.isEmpty) {
setState(() {
errorMessage = '아이디와 비밀번호를 모두 입력하세요.';
@@ -67,9 +68,19 @@ class _LoginPageState extends State<LoginPage> {
return;
}
final authService = GetIt.I<AuthService>();
AuthSession? session;
if (!mounted) return;
try {
await _synchronizePermissions();
session = await authService.login(
LoginRequest(
identifier: id,
password: password,
rememberMe: rememberMe,
),
);
await _applyPermissions(session);
} catch (error) {
if (!mounted) return;
final failure = Failure.from(error);
@@ -317,24 +328,50 @@ class _LoginPageState extends State<LoginPage> {
context.go(dashboardRoutePath);
}
Future<void> _synchronizePermissions() async {
Future<void> _applyPermissions(AuthSession session) async {
final manager = PermissionScope.of(context);
manager.clearServerPermissions();
final aggregated = <String, Set<PermissionAction>>{};
for (final permission in session.permissions) {
final map = permission.toPermissionMap();
for (final entry in map.entries) {
aggregated
.putIfAbsent(entry.key, () => <PermissionAction>{})
.addAll(entry.value);
}
}
if (aggregated.isNotEmpty) {
manager.applyServerPermissions(aggregated);
return;
}
await _synchronizePermissions(groupId: session.user.primaryGroupId);
}
Future<void> _synchronizePermissions({int? groupId}) async {
final manager = PermissionScope.of(context);
manager.clearServerPermissions();
final groupRepository = GetIt.I<GroupRepository>();
final defaultGroups = await groupRepository.list(
page: 1,
pageSize: 1,
isDefault: true,
);
Group? targetGroup = _firstGroupWithId(defaultGroups.items);
int? targetGroupId = groupId;
if (targetGroup == null) {
final fallbackGroups = await groupRepository.list(page: 1, pageSize: 1);
targetGroup = _firstGroupWithId(fallbackGroups.items);
if (targetGroupId == null) {
final defaultGroups = await groupRepository.list(
page: 1,
pageSize: 1,
isDefault: true,
);
var targetGroup = _firstGroupWithId(defaultGroups.items);
if (targetGroup == null) {
final fallbackGroups = await groupRepository.list(page: 1, pageSize: 1);
targetGroup = _firstGroupWithId(fallbackGroups.items);
}
targetGroupId = targetGroup?.id;
}
if (targetGroup?.id == null) {
if (targetGroupId == null) {
return;
}
@@ -343,8 +380,7 @@ class _LoginPageState extends State<LoginPage> {
repository: permissionRepository,
manager: manager,
);
final groupId = targetGroup!.id!;
await synchronizer.syncForGroup(groupId);
await synchronizer.syncForGroup(targetGroupId);
}
Group? _firstGroupWithId(List<Group> groups) {