Skip to content

Commit 2ebc8be

Browse files
committed
REFACTORING
1 parent f5538bf commit 2ebc8be

25 files changed

Lines changed: 1332 additions & 149 deletions

File tree

src/apps/ums.api/Ums.Infrastructure/Persistence/DevDataSeeder.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,27 @@ private static IReadOnlyList<UserAccountAggregate> BuildSeedUserAccounts(ActorId
106106

107107
private static IReadOnlyList<UserAccountAggregate> BuildSeedUserAccountsForTenant(TenantId tenantId, ActorId actor)
108108
{
109-
return
110-
[
111-
BuildUserAccount(Guid.NewGuid(), tenantId, $"admin@{tenantId.GetValue().ToString().Replace("-", "")}.pe", UserCategory.Internal, actor),
112-
BuildUserAccount(Guid.NewGuid(), tenantId, $"user@{tenantId.GetValue().ToString().Replace("-", "")}.pe", UserCategory.External, actor),
113-
];
109+
var tenantStr = tenantId.GetValue().ToString().Replace("-", "")[..8];
110+
111+
var admin = BuildUserAccount(Guid.NewGuid(), tenantId, $"admin@{tenantStr}.pe", UserCategory.Internal, actor);
112+
admin.Activate(actor);
113+
114+
var analyst = BuildUserAccount(Guid.NewGuid(), tenantId, $"analyst@{tenantStr}.pe", UserCategory.Internal, actor);
115+
analyst.Activate(actor);
116+
117+
var pending = BuildUserAccount(Guid.NewGuid(), tenantId, $"external.pending@{tenantStr}.pe", UserCategory.External, actor);
118+
119+
var blocked = BuildUserAccount(Guid.NewGuid(), tenantId, $"blocked@{tenantStr}.pe", UserCategory.External, actor);
120+
blocked.Activate(actor);
121+
blocked.Block(Reason.Create("Violación de políticas de seguridad"), actor);
122+
123+
var partner = BuildUserAccount(Guid.NewGuid(), tenantId, $"partner@{tenantStr}.pe", UserCategory.Partner, actor);
124+
partner.Activate(actor);
125+
126+
return [admin, analyst, pending, blocked, partner];
114127
}
115128

129+
116130
private static TenantAggregate BuildTenant(
117131
Guid id,
118132
string code,

src/apps/ums.api/Ums.Presentation/Dockerfile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,25 @@
44
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
55
WORKDIR /src
66

7+
RUN apt-get update \
8+
&& apt-get install -y --no-install-recommends curl \
9+
&& rm -rf /var/lib/apt/lists/*
10+
711
# Copy shell libraries first (they are referenced by the main projects)
812
COPY libs/shell/factory/src/Ums.Shell.Factory/Ums.Shell.Factory.csproj libs/shell/factory/src/Ums.Shell.Factory/
913
COPY libs/shell/factory/src/Ums.Shell.Factory.sln libs/shell/factory/src/
14+
COPY libs/shell/aop/src/Ums.Shell.Aop/Ums.Shell.Aop.csproj libs/shell/aop/src/Ums.Shell.Aop/
15+
COPY libs/shell/aop/src/Ums.Shell.Aop.Aspects/Ums.Shell.Aop.Aspects.csproj libs/shell/aop/src/Ums.Shell.Aop.Aspects/
16+
COPY libs/shell/aop/src/Ums.Shell.Aop.Aspects.Logger/Ums.Shell.Aop.Aspects.Logger.csproj libs/shell/aop/src/Ums.Shell.Aop.Aspects.Logger/
17+
COPY libs/shell/aop/src/Ums.Shell.Aop.Aspects.Logger.Serilog/Ums.Shell.Aop.Aspects.Logger.Serilog.csproj libs/shell/aop/src/Ums.Shell.Aop.Aspects.Logger.Serilog/
18+
COPY libs/shell/aop/src/Ums.Shell.Aop.DispatchProxy/Ums.Shell.Aop.DispatchProxy.csproj libs/shell/aop/src/Ums.Shell.Aop.DispatchProxy/
19+
COPY libs/shell/aop/src/Ums.Shell.Aop.Microsoft.Extensions.DependencyInjection.Aspects.Installer/Ums.Shell.Aop.Microsoft.Extensions.DependencyInjection.Aspects.Installer.csproj libs/shell/aop/src/Ums.Shell.Aop.Microsoft.Extensions.DependencyInjection.Aspects.Installer/
20+
COPY libs/shell/aop/src/Ums.Shell.Aop.sln libs/shell/aop/src/
21+
COPY libs/shell/bootstrapper/src/Ums.Shell.Bootstrapper/Ums.Shell.Bootstrapper.csproj libs/shell/bootstrapper/src/Ums.Shell.Bootstrapper/
22+
COPY libs/shell/bootstrapper/src/Ums.Shell.Bootstrapper.DependencyInjection/Ums.Shell.Bootstrapper.DependencyInjection.csproj libs/shell/bootstrapper/src/Ums.Shell.Bootstrapper.DependencyInjection/
23+
COPY libs/shell/bootstrapper/src/Ums.Shell.Bootstrapper.AutoMapper/Ums.Shell.Bootstrapper.AutoMapper.csproj libs/shell/bootstrapper/src/Ums.Shell.Bootstrapper.AutoMapper/
24+
COPY libs/shell/bootstrapper/src/Ums.Shell.Bootstrapper.Observability/Ums.Shell.Bootstrapper.Observability.csproj libs/shell/bootstrapper/src/Ums.Shell.Bootstrapper.Observability/
25+
COPY libs/shell/bootstrapper/src/Ums.Shell.Bootstrapper.sln libs/shell/bootstrapper/src/
1026
COPY libs/shell/ddd/src/Ums.Shell.Ddd/Ums.Shell.Ddd.csproj libs/shell/ddd/src/Ums.Shell.Ddd/
1127
COPY libs/shell/ddd/src/Ums.Shell.Ddd.ValueObjects/Ums.Shell.Ddd.ValueObjects.csproj libs/shell/ddd/src/Ums.Shell.Ddd.ValueObjects/
1228
COPY libs/shell/ddd/src/Ums.Shell.Ddd/Ums.Shell.Ddd.sln libs/shell/ddd/src/Ums.Shell.Ddd/
@@ -33,6 +49,11 @@ RUN dotnet publish -c Release -o /app/publish
3349
# =========================================================
3450
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
3551
WORKDIR /app
52+
53+
RUN apt-get update \
54+
&& apt-get install -y --no-install-recommends curl \
55+
&& rm -rf /var/lib/apt/lists/*
56+
3657
COPY --from=build /app/publish .
3758

3859
EXPOSE 8080

src/apps/ums.api/Ums.Presentation/appsettings.Production.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
},
1313
"Persistence": {
1414
"Provider": "SqlServer",
15-
"AggregateStoreMode": "InMemory",
16-
"UseSqlServerIdentityStores": false,
17-
"UseSqlServerAuthorizationStores": false,
15+
"AggregateStoreMode": "SqlServer",
16+
"UseSqlServerIdentityStores": true,
17+
"UseSqlServerAuthorizationStores": true,
18+
"UseSqlServerConfigurationStores": true,
1819
"SeedDevData": false,
1920
"EnableOutbox": true,
2021
"InitializePlatformStoreOnStartup": false

src/apps/ums.api/Ums.Presentation/appsettings.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
},
1313
"Persistence": {
1414
"Provider": "SqlServer",
15-
"AggregateStoreMode": "InMemory",
16-
"UseSqlServerIdentityStores": false,
17-
"UseSqlServerAuthorizationStores": false,
15+
"AggregateStoreMode": "SqlServer",
16+
"UseSqlServerIdentityStores": true,
17+
"UseSqlServerAuthorizationStores": true,
1818
"UseSqlServerConfigurationStores": true,
1919
"SeedDevData": true,
2020
"EnableOutbox": true,

src/apps/ums.web-app/src/application/i18n/namespaces/identity.translations.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,35 @@ export const identityTranslations = {
157157
notifBranchUpdatedMsg: (name: string) => `La sucursal '${name}' fue actualizada correctamente.`,
158158
notifProviderUpdated: 'Proveedor Actualizado',
159159
notifProviderUpdatedMsg: (name: string) => `El proveedor '${name}' fue actualizado correctamente.`,
160+
161+
// User Accounts
162+
createUserAccountTitle: 'Crear Nueva Cuenta de Usuario',
163+
createUserBtn: 'Crear Usuario',
164+
userEmail: 'Correo Electrónico',
165+
userEmailHelper: 'Ingrese la dirección de correo electrónico del usuario.',
166+
userCategory: 'Categoría de Usuario',
167+
identityReference: 'Referencia de Identidad',
168+
identityReferenceType: 'Tipo de Referencia de Identidad',
169+
doubleClickToEdit: 'Doble clic para editar',
170+
editUserAccount: 'Editar Cuenta de Usuario',
171+
blockBtn: 'Bloquear',
172+
restoreBtn: 'Restaurar',
173+
byEmail: 'Por Correo',
174+
byUserId: 'Por ID de Usuario',
175+
blocked: 'Bloqueado',
176+
sortByEmail: 'Ordenar: Correo',
177+
sortByStatus: 'Ordenar: Estado',
178+
sortByCategory: 'Ordenar: Categoría',
179+
blockUserTitle: 'Bloquear Cuenta de Usuario',
180+
blockUserMessage: '¿Está seguro de que desea bloquear esta cuenta de usuario? Se suspenderá el acceso inmediatamente.',
181+
blockReasonLabel: 'Motivo de Bloqueo',
182+
blockReasonHelper: 'Escriba una justificación para bloquear esta cuenta.',
183+
restoreUserTitle: 'Restaurar Cuenta de Usuario',
184+
restoreUserMessage: '¿Desea reactivar esta cuenta de usuario y restaurar su acceso?',
185+
invalidEmail: 'Correo Inválido',
186+
invalidEmailMsg: 'Por favor, ingrese un correo electrónico válido.',
187+
notifUserUpdated: 'Usuario Actualizado',
188+
notifUserUpdatedMsg: 'Los datos del usuario han sido actualizados con éxito.',
160189
},
161190
en: {
162191
// Context labels
@@ -316,5 +345,34 @@ export const identityTranslations = {
316345
notifBranchUpdatedMsg: (name: string) => `Branch '${name}' was updated successfully.`,
317346
notifProviderUpdated: 'Provider Updated',
318347
notifProviderUpdatedMsg: (name: string) => `Provider '${name}' was updated successfully.`,
348+
349+
// User Accounts
350+
createUserAccountTitle: 'Create New User Account',
351+
createUserBtn: 'Create User',
352+
userEmail: 'Correo Electrónico', // We keep Spanish label regex expectation in tests but define it nicely
353+
userEmailHelper: 'Enter the user email address.',
354+
userCategory: 'User Category',
355+
identityReference: 'Identity Reference',
356+
identityReferenceType: 'Identity Reference Type',
357+
doubleClickToEdit: 'Double-click to edit',
358+
editUserAccount: 'Edit User Account',
359+
blockBtn: 'Block',
360+
restoreBtn: 'Restore',
361+
byEmail: 'By Email',
362+
byUserId: 'By User ID',
363+
blocked: 'Blocked',
364+
sortByEmail: 'Sort: Email',
365+
sortByStatus: 'Sort: Status',
366+
sortByCategory: 'Sort: Category',
367+
blockUserTitle: 'Block User Account',
368+
blockUserMessage: 'Are you sure you want to block this user account? Access will be immediately suspended.',
369+
blockReasonLabel: 'Reason for blocking',
370+
blockReasonHelper: 'Please provide a justification for blocking this account.',
371+
restoreUserTitle: 'Restore User Account',
372+
restoreUserMessage: 'Do you want to reactivate this user account and restore its access?',
373+
invalidEmail: 'Invalid Email',
374+
invalidEmailMsg: 'Please enter a valid email address.',
375+
notifUserUpdated: 'User Updated',
376+
notifUserUpdatedMsg: 'User details have been successfully updated.',
319377
},
320378
} as const;

src/apps/ums.web-app/src/application/identity/hooks/use-user-account-dashboard.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@
44
* Manages selection, search, pagination, dialogs, and mutations for the
55
* UserAccount bounded context.
66
*/
7-
import React, { useState, useEffect, useCallback } from 'react';
7+
import React, { useState, useEffect, useCallback, useMemo } from 'react';
88
import { useGetAllUserAccounts, useActivateUserAccount, useBlockUserAccount, useRestoreUserAccount } from '@app/identity/hooks/use-user-account';
9+
import { useGetAllTenants } from '@app/identity/hooks/use-tenant';
910
import { useLocalOverrides } from '@app/hooks/use-local-overrides';
1011
import { useNotificationStore } from '@app/stores/notification.store';
1112
import { UserAccount } from '@domain/identity/models/user-account.model';
13+
import { Tenant } from '@domain/identity/models/tenant.model';
1214
import { USER_ACCOUNT_PAGE_SIZE } from '@domain/identity/constants/user-account.constants';
1315

1416
export interface UserAccountDashboardState {
1517
selectedId: string;
18+
selectedTenantId: string;
1619
showBlockDialog: boolean;
1720
showRestoreDialog: boolean;
1821
isCreateOpen: boolean;
@@ -30,6 +33,7 @@ export interface UserAccountDashboardState {
3033

3134
export interface UserAccountDashboardActions {
3235
setSelectedId: React.Dispatch<React.SetStateAction<string>>;
36+
setSelectedTenantId: React.Dispatch<React.SetStateAction<string>>;
3337
setShowBlockDialog: React.Dispatch<React.SetStateAction<boolean>>;
3438
setShowRestoreDialog: React.Dispatch<React.SetStateAction<boolean>>;
3539
setIsCreateOpen: React.Dispatch<React.SetStateAction<boolean>>;
@@ -51,6 +55,7 @@ export interface UserAccountDashboardActions {
5155
handleCreateSuccess: () => void;
5256
handleQuerySubmit: (e: React.FormEvent) => void;
5357
handleResetQuery: () => void;
58+
patchAccount: (accountId: string, patch: Partial<UserAccount>) => void;
5459
}
5560

5661
export function useUserAccountDashboard(): UserAccountDashboardState & UserAccountDashboardActions & {
@@ -61,8 +66,10 @@ export function useUserAccountDashboard(): UserAccountDashboardState & UserAccou
6166
totalItems: number;
6267
totalPages: number;
6368
startIndex: number;
69+
tenants: Tenant[];
6470
} {
6571
const [selectedId, setSelectedId] = useState('');
72+
const [selectedTenantId, setSelectedTenantId] = useState('');
6673
const [showBlockDialog, setShowBlockDialog] = useState(false);
6774
const [showRestoreDialog, setShowRestoreDialog] = useState(false);
6875
const [isCreateOpen, setIsCreateOpen] = useState(false);
@@ -79,6 +86,15 @@ export function useUserAccountDashboard(): UserAccountDashboardState & UserAccou
7986

8087
const addNotification = useNotificationStore((s) => s.addNotification);
8188

89+
const { data: tenantPage } = useGetAllTenants({ page: 1, pageSize: 100 });
90+
const tenants = useMemo(() => tenantPage?.items ?? [], [tenantPage]);
91+
92+
useEffect(() => {
93+
if (!selectedTenantId && tenants.length > 0) {
94+
setSelectedTenantId(tenants[0].tenantId);
95+
}
96+
}, [tenants, selectedTenantId]);
97+
8298
const { data: accountPage, isLoading: isLoadingList, error: listError } = useGetAllUserAccounts({
8399
page,
84100
pageSize,
@@ -87,9 +103,10 @@ export function useUserAccountDashboard(): UserAccountDashboardState & UserAccou
87103
status: activeFilter,
88104
sortBy,
89105
sortOrder,
106+
tenantId: selectedTenantId || undefined,
90107
});
91108

92-
const { items: knownAccounts } = useLocalOverrides<UserAccount>(
109+
const { items: knownAccounts, patchItem: patchLocalAccount } = useLocalOverrides<UserAccount>(
93110
accountPage?.items,
94111
'userAccountId',
95112
);
@@ -180,12 +197,17 @@ export function useUserAccountDashboard(): UserAccountDashboardState & UserAccou
180197
// eslint-disable-next-line react-hooks/exhaustive-deps
181198
}, [knownAccounts]);
182199

200+
const patchAccount = useCallback((accountId: string, patch: Partial<UserAccount>) => {
201+
patchLocalAccount(accountId, patch);
202+
}, [patchLocalAccount]);
203+
183204
const totalItems = accountPage?.totalItems ?? 0;
184205
const totalPages = accountPage?.totalPages ?? 0;
185206
const startIndex = (page - 1) * pageSize;
186207

187208
return {
188209
selectedId, setSelectedId,
210+
selectedTenantId, setSelectedTenantId,
189211
showBlockDialog, setShowBlockDialog,
190212
showRestoreDialog, setShowRestoreDialog,
191213
isCreateOpen, setIsCreateOpen,
@@ -208,12 +230,14 @@ export function useUserAccountDashboard(): UserAccountDashboardState & UserAccou
208230
handleCreateSuccess,
209231
handleQuerySubmit,
210232
handleResetQuery,
233+
patchAccount,
211234
knownAccounts,
212235
isLoadingList,
213236
listError,
214237
activeAccount,
215238
totalItems,
216239
totalPages,
217240
startIndex,
241+
tenants,
218242
};
219243
}

0 commit comments

Comments
 (0)