Some checks failed
ERP Core CI / Backend Lint (push) Has been cancelled
ERP Core CI / Backend Unit Tests (push) Has been cancelled
ERP Core CI / Backend Integration Tests (push) Has been cancelled
ERP Core CI / Frontend Lint (push) Has been cancelled
ERP Core CI / Frontend Unit Tests (push) Has been cancelled
ERP Core CI / Frontend E2E Tests (push) Has been cancelled
ERP Core CI / Database DDL Validation (push) Has been cancelled
ERP Core CI / Backend Build (push) Has been cancelled
ERP Core CI / Frontend Build (push) Has been cancelled
ERP Core CI / CI Success (push) Has been cancelled
Performance Tests / Lighthouse CI (push) Has been cancelled
Performance Tests / Bundle Size Analysis (push) Has been cancelled
Performance Tests / k6 Load Tests (push) Has been cancelled
Performance Tests / Performance Summary (push) Has been cancelled
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8 - Actualizaciones en modulos CRM y OpenAPI Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
626 lines
21 KiB
YAML
626 lines
21 KiB
YAML
# FRONTEND_INVENTORY.yml - ERP Core
|
|
# Inventario canonico de objetos frontend
|
|
# Ubicacion Canonica: orchestration/inventarios/
|
|
# Ultima actualizacion: 2025-12-05
|
|
|
|
version: "2.0"
|
|
project: erp-core
|
|
updated_at: "2026-01-06"
|
|
updated_by: ORQUESTADOR-Claude-Opus
|
|
|
|
# =============================================================================
|
|
# CONFIGURACION DEL STACK
|
|
# =============================================================================
|
|
|
|
stack:
|
|
framework: React 18.x
|
|
build_tool: Vite 5.x
|
|
language: TypeScript 5.3+
|
|
state_management: Zustand
|
|
styling: Tailwind CSS 4.x
|
|
forms: React Hook Form + Zod
|
|
routing: React Router 6.x
|
|
http_client: Axios
|
|
|
|
# =============================================================================
|
|
# RESUMEN
|
|
# =============================================================================
|
|
|
|
summary:
|
|
total_features: 24
|
|
total_pages: 58
|
|
total_components: 185
|
|
total_stores: 24
|
|
total_hooks: 35
|
|
total_api_clients: 24
|
|
implemented: 6 # auth, users, tenants, catalogs, settings (partial)
|
|
documented: 15 # MGN-001 a MGN-009
|
|
|
|
# Sprint 1-3 Implementation (2026-01-06)
|
|
implementation:
|
|
pages_created: 25
|
|
stores_created: 4
|
|
routes_added: 23
|
|
features_implemented: 2 # catalogs, settings
|
|
build_status: "Pass (4.07s)"
|
|
|
|
by_sprint:
|
|
sprint_1:
|
|
feature: catalogs
|
|
pages: 6 # Countries(3) + States(2) + index
|
|
files:
|
|
- features/catalogs/types/catalog.types.ts
|
|
- features/catalogs/api/catalogs.api.ts
|
|
- features/catalogs/hooks/useCountries.ts
|
|
- features/catalogs/hooks/useCurrencies.ts
|
|
- features/catalogs/hooks/useUom.ts
|
|
- features/catalogs/hooks/useCategories.ts
|
|
- features/catalogs/components/CountrySelect.tsx
|
|
- features/catalogs/components/CurrencySelect.tsx
|
|
- pages/catalogs/countries/CountriesPage.tsx
|
|
- pages/catalogs/countries/CountryFormPage.tsx
|
|
- pages/catalogs/countries/CountryDetailPage.tsx
|
|
- pages/catalogs/states/StatesPage.tsx
|
|
- pages/catalogs/states/StateFormPage.tsx
|
|
|
|
sprint_2:
|
|
feature: catalogs (complete)
|
|
pages: 17 # Currencies(4) + UoM(5) + Categories(5) + components(3)
|
|
files:
|
|
- pages/catalogs/currencies/CurrenciesPage.tsx
|
|
- pages/catalogs/currencies/CurrencyFormPage.tsx
|
|
- pages/catalogs/currencies/CurrencyDetailPage.tsx
|
|
- pages/catalogs/currencies/CurrencyRatesPage.tsx
|
|
- pages/catalogs/uom/UomPage.tsx
|
|
- pages/catalogs/uom/UomCategoriesPage.tsx
|
|
- pages/catalogs/uom/UomFormPage.tsx
|
|
- pages/catalogs/uom/UomConversionPage.tsx
|
|
- pages/catalogs/categories/CategoriesPage.tsx
|
|
- pages/catalogs/categories/CategoryFormPage.tsx
|
|
- pages/catalogs/categories/CategoryDetailPage.tsx
|
|
- features/catalogs/components/CategoryTree.tsx
|
|
- features/catalogs/components/CategoryTreeSelect.tsx
|
|
routes_added: 20
|
|
|
|
sprint_3:
|
|
features: [catalogs-stores, settings]
|
|
stores: 4
|
|
pages: 2 # SystemSettings, TenantSettings
|
|
files:
|
|
- features/catalogs/stores/countries.store.ts
|
|
- features/catalogs/stores/currencies.store.ts
|
|
- features/catalogs/stores/uom.store.ts
|
|
- features/catalogs/stores/categories.store.ts
|
|
- features/settings/types/settings.types.ts
|
|
- features/settings/api/settings.api.ts
|
|
- features/settings/hooks/useSystemSettings.ts
|
|
- features/settings/hooks/useTenantSettings.ts
|
|
- features/settings/hooks/useUserPreferences.ts
|
|
- pages/settings/SystemSettingsPage.tsx
|
|
- pages/settings/TenantSettingsPage.tsx
|
|
- pages/settings/components/GeneralSettingsForm.tsx
|
|
- pages/settings/components/FormatSettingsForm.tsx
|
|
- pages/settings/components/FeatureTogglesForm.tsx
|
|
- pages/settings/components/BrandingSettingsForm.tsx
|
|
- pages/settings/components/ModulesSettingsForm.tsx
|
|
- pages/settings/components/UsageStatsCard.tsx
|
|
routes_added: 3
|
|
|
|
# =============================================================================
|
|
# FEATURES (MODULOS FRONTEND)
|
|
# =============================================================================
|
|
|
|
features:
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# MGN-001: AUTH
|
|
# ---------------------------------------------------------------------------
|
|
- id: MGN-001
|
|
name: auth
|
|
path: apps/frontend/src/features/auth/
|
|
status: documented
|
|
rf: [RF-AUTH-001, RF-AUTH-002, RF-AUTH-003, RF-AUTH-005, RF-AUTH-006]
|
|
|
|
pages:
|
|
- name: LoginPage
|
|
file: pages/LoginPage.tsx
|
|
route: /login
|
|
rf: RF-AUTH-001
|
|
public: true
|
|
components: [LoginForm, SocialLoginButtons]
|
|
|
|
- name: ForgotPasswordPage
|
|
file: pages/ForgotPasswordPage.tsx
|
|
route: /forgot-password
|
|
rf: RF-AUTH-003
|
|
public: true
|
|
components: [ForgotPasswordForm]
|
|
|
|
- name: ResetPasswordPage
|
|
file: pages/ResetPasswordPage.tsx
|
|
route: /reset-password/:token
|
|
rf: RF-AUTH-003
|
|
public: true
|
|
components: [ResetPasswordForm]
|
|
|
|
components:
|
|
- name: LoginForm
|
|
file: components/LoginForm.tsx
|
|
rf: RF-AUTH-001
|
|
props: [onSuccess, onError]
|
|
description: Formulario de login con email/password
|
|
|
|
- name: SocialLoginButtons
|
|
file: components/SocialLoginButtons.tsx
|
|
rf: RF-AUTH-005
|
|
props: [providers]
|
|
description: Botones de login social
|
|
|
|
- name: ForgotPasswordForm
|
|
file: components/ForgotPasswordForm.tsx
|
|
rf: RF-AUTH-003
|
|
props: [onSuccess]
|
|
description: Formulario solicitud reset
|
|
|
|
- name: ResetPasswordForm
|
|
file: components/ResetPasswordForm.tsx
|
|
rf: RF-AUTH-003
|
|
props: [token, onSuccess]
|
|
description: Formulario cambio password
|
|
|
|
stores:
|
|
- name: authStore
|
|
file: stores/authStore.ts
|
|
rf: [RF-AUTH-001, RF-AUTH-002, RF-AUTH-006]
|
|
state:
|
|
- {name: user, type: "User | null"}
|
|
- {name: isAuthenticated, type: boolean}
|
|
- {name: isLoading, type: boolean}
|
|
- {name: error, type: "string | null"}
|
|
- {name: accessToken, type: "string | null"}
|
|
actions:
|
|
- {name: login, params: [credentials], rf: RF-AUTH-001}
|
|
- {name: logout, params: [], rf: RF-AUTH-006}
|
|
- {name: refreshToken, params: [], rf: RF-AUTH-002}
|
|
- {name: getProfile, params: [], rf: RF-AUTH-001}
|
|
- {name: clearError, params: []}
|
|
|
|
api:
|
|
- name: authApi
|
|
file: api/authApi.ts
|
|
methods:
|
|
- {name: login, endpoint: "POST /auth/login", rf: RF-AUTH-001}
|
|
- {name: logout, endpoint: "POST /auth/logout", rf: RF-AUTH-006}
|
|
- {name: refresh, endpoint: "POST /auth/refresh", rf: RF-AUTH-002}
|
|
- {name: forgotPassword, endpoint: "POST /auth/forgot-password", rf: RF-AUTH-003}
|
|
- {name: resetPassword, endpoint: "POST /auth/reset-password", rf: RF-AUTH-003}
|
|
- {name: getMe, endpoint: "GET /auth/me", rf: RF-AUTH-001}
|
|
|
|
hooks:
|
|
- name: useAuth
|
|
file: hooks/useAuth.ts
|
|
rf: RF-AUTH-001
|
|
returns: "{user, isAuthenticated, login, logout}"
|
|
description: Hook principal de autenticacion
|
|
|
|
- name: useRequireAuth
|
|
file: hooks/useRequireAuth.ts
|
|
rf: RF-AUTH-001
|
|
returns: void
|
|
description: Redirige a login si no autenticado
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# MGN-002: USERS
|
|
# ---------------------------------------------------------------------------
|
|
- id: MGN-002
|
|
name: users
|
|
path: apps/frontend/src/features/users/
|
|
status: documented
|
|
rf: [RF-USERS-001, RF-USERS-002, RF-USERS-003, RF-USERS-004, RF-USERS-005]
|
|
|
|
pages:
|
|
- name: UsersPage
|
|
file: pages/UsersPage.tsx
|
|
route: /users
|
|
rf: RF-USERS-001
|
|
components: [UserTable, UserFilters, CreateUserModal]
|
|
|
|
- name: UserDetailPage
|
|
file: pages/UserDetailPage.tsx
|
|
route: /users/:id
|
|
rf: RF-USERS-001
|
|
components: [UserForm, UserRoles]
|
|
|
|
- name: ProfilePage
|
|
file: pages/ProfilePage.tsx
|
|
route: /profile
|
|
rf: RF-USERS-002
|
|
components: [ProfileForm, AvatarUpload]
|
|
|
|
- name: PreferencesPage
|
|
file: pages/PreferencesPage.tsx
|
|
route: /settings/preferences
|
|
rf: RF-USERS-003
|
|
components: [PreferencesForm]
|
|
|
|
components:
|
|
- name: UserTable
|
|
file: components/UserTable.tsx
|
|
rf: RF-USERS-001
|
|
props: [users, onEdit, onDelete, pagination]
|
|
|
|
- name: UserForm
|
|
file: components/UserForm.tsx
|
|
rf: RF-USERS-001
|
|
props: [user, onSubmit, isLoading]
|
|
|
|
- name: UserFilters
|
|
file: components/UserFilters.tsx
|
|
rf: RF-USERS-005
|
|
props: [filters, onFilterChange]
|
|
|
|
- name: ProfileForm
|
|
file: components/ProfileForm.tsx
|
|
rf: RF-USERS-002
|
|
props: [profile, onSubmit]
|
|
|
|
- name: AvatarUpload
|
|
file: components/AvatarUpload.tsx
|
|
rf: RF-USERS-002
|
|
props: [currentAvatar, onUpload]
|
|
|
|
- name: PreferencesForm
|
|
file: components/PreferencesForm.tsx
|
|
rf: RF-USERS-003
|
|
props: [preferences, onSubmit]
|
|
|
|
- name: UserSearchInput
|
|
file: components/UserSearchInput.tsx
|
|
rf: RF-USERS-005
|
|
props: [onSelect, placeholder]
|
|
|
|
stores:
|
|
- name: usersStore
|
|
file: stores/usersStore.ts
|
|
rf: [RF-USERS-001, RF-USERS-005]
|
|
state:
|
|
- {name: users, type: "User[]"}
|
|
- {name: selectedUser, type: "User | null"}
|
|
- {name: isLoading, type: boolean}
|
|
- {name: pagination, type: PaginationState}
|
|
- {name: filters, type: UserFilters}
|
|
actions:
|
|
- {name: fetchUsers, params: [filters]}
|
|
- {name: createUser, params: [data]}
|
|
- {name: updateUser, params: [id, data]}
|
|
- {name: deleteUser, params: [id]}
|
|
- {name: searchUsers, params: [query]}
|
|
|
|
api:
|
|
- name: usersApi
|
|
file: api/usersApi.ts
|
|
methods:
|
|
- {name: getUsers, endpoint: "GET /users"}
|
|
- {name: getUser, endpoint: "GET /users/:id"}
|
|
- {name: createUser, endpoint: "POST /users"}
|
|
- {name: updateUser, endpoint: "PATCH /users/:id"}
|
|
- {name: deleteUser, endpoint: "DELETE /users/:id"}
|
|
- {name: getProfile, endpoint: "GET /users/:id/profile"}
|
|
- {name: updateProfile, endpoint: "PATCH /users/:id/profile"}
|
|
- {name: uploadAvatar, endpoint: "POST /users/:id/avatar"}
|
|
- {name: getPreferences, endpoint: "GET /users/:id/preferences"}
|
|
- {name: updatePreferences, endpoint: "PATCH /users/:id/preferences"}
|
|
- {name: searchUsers, endpoint: "GET /users/search"}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# MGN-003: ROLES
|
|
# ---------------------------------------------------------------------------
|
|
- id: MGN-003
|
|
name: roles
|
|
path: apps/frontend/src/features/roles/
|
|
status: documented
|
|
rf: [RF-RBAC-001, RF-RBAC-002, RF-RBAC-003, RF-RBAC-004]
|
|
|
|
pages:
|
|
- name: RolesPage
|
|
file: pages/RolesPage.tsx
|
|
route: /settings/roles
|
|
rf: RF-RBAC-001
|
|
components: [RoleTable, CreateRoleModal]
|
|
|
|
- name: RoleDetailPage
|
|
file: pages/RoleDetailPage.tsx
|
|
route: /settings/roles/:id
|
|
rf: [RF-RBAC-001, RF-RBAC-002]
|
|
components: [RoleForm, PermissionMatrix]
|
|
|
|
- name: PermissionsPage
|
|
file: pages/PermissionsPage.tsx
|
|
route: /settings/permissions
|
|
rf: RF-RBAC-002
|
|
components: [PermissionList]
|
|
|
|
components:
|
|
- name: RoleTable
|
|
file: components/RoleTable.tsx
|
|
rf: RF-RBAC-001
|
|
props: [roles, onEdit, onDelete]
|
|
|
|
- name: RoleForm
|
|
file: components/RoleForm.tsx
|
|
rf: RF-RBAC-001
|
|
props: [role, onSubmit]
|
|
|
|
- name: PermissionMatrix
|
|
file: components/PermissionMatrix.tsx
|
|
rf: RF-RBAC-002
|
|
props: [roleId, permissions, onToggle]
|
|
description: Matriz visual modulo x accion
|
|
|
|
- name: UserRoleAssignment
|
|
file: components/UserRoleAssignment.tsx
|
|
rf: RF-RBAC-003
|
|
props: [userId, assignedRoles, onAssign, onRemove]
|
|
|
|
stores:
|
|
- name: rolesStore
|
|
file: stores/rolesStore.ts
|
|
rf: [RF-RBAC-001, RF-RBAC-002]
|
|
state:
|
|
- {name: roles, type: "Role[]"}
|
|
- {name: permissions, type: "Permission[]"}
|
|
- {name: selectedRole, type: "Role | null"}
|
|
actions:
|
|
- {name: fetchRoles, params: []}
|
|
- {name: createRole, params: [data]}
|
|
- {name: updateRole, params: [id, data]}
|
|
- {name: deleteRole, params: [id]}
|
|
- {name: fetchPermissions, params: []}
|
|
- {name: togglePermission, params: [roleId, permissionId]}
|
|
|
|
hooks:
|
|
- name: usePermission
|
|
file: hooks/usePermission.ts
|
|
rf: RF-RBAC-004
|
|
usage: "const canEdit = usePermission('users', 'write', 'all')"
|
|
description: Verifica permiso del usuario actual
|
|
|
|
- name: useHasRole
|
|
file: hooks/useHasRole.ts
|
|
rf: RF-RBAC-004
|
|
usage: "const isAdmin = useHasRole('admin')"
|
|
description: Verifica rol del usuario actual
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# MGN-004: TENANTS
|
|
# ---------------------------------------------------------------------------
|
|
- id: MGN-004
|
|
name: tenants
|
|
path: apps/frontend/src/features/tenants/
|
|
status: documented
|
|
rf: [RF-TENANTS-001, RF-TENANTS-002, RF-TENANTS-003, RF-TENANTS-005]
|
|
|
|
pages:
|
|
- name: TenantsPage
|
|
file: pages/TenantsPage.tsx
|
|
route: /admin/tenants
|
|
rf: RF-TENANTS-001
|
|
description: Lista de tenants (super admin)
|
|
|
|
- name: TenantSettingsPage
|
|
file: pages/TenantSettingsPage.tsx
|
|
route: /settings/organization
|
|
rf: RF-TENANTS-002
|
|
components: [TenantSettingsForm]
|
|
|
|
- name: OnboardingPage
|
|
file: pages/OnboardingPage.tsx
|
|
route: /onboarding
|
|
rf: RF-TENANTS-005
|
|
components: [OnboardingWizard]
|
|
|
|
- name: PlansPage
|
|
file: pages/PlansPage.tsx
|
|
route: /settings/subscription
|
|
rf: RF-TENANTS-003
|
|
components: [PlanCard, SubscriptionStatus]
|
|
|
|
components:
|
|
- name: TenantSettingsForm
|
|
file: components/TenantSettingsForm.tsx
|
|
rf: RF-TENANTS-002
|
|
props: [settings, onSubmit]
|
|
|
|
- name: OnboardingWizard
|
|
file: components/OnboardingWizard.tsx
|
|
rf: RF-TENANTS-005
|
|
props: [onComplete]
|
|
description: Wizard multi-paso de onboarding
|
|
|
|
- name: PlanCard
|
|
file: components/PlanCard.tsx
|
|
rf: RF-TENANTS-003
|
|
props: [plan, isCurrentPlan, onSelect]
|
|
|
|
- name: SubscriptionStatus
|
|
file: components/SubscriptionStatus.tsx
|
|
rf: RF-TENANTS-003
|
|
props: [subscription]
|
|
|
|
stores:
|
|
- name: tenantStore
|
|
file: stores/tenantStore.ts
|
|
rf: [RF-TENANTS-001, RF-TENANTS-002, RF-TENANTS-003]
|
|
state:
|
|
- {name: currentTenant, type: "Tenant | null"}
|
|
- {name: settings, type: "TenantSettings | null"}
|
|
- {name: subscription, type: "Subscription | null"}
|
|
- {name: plans, type: "Plan[]"}
|
|
actions:
|
|
- {name: fetchCurrentTenant, params: []}
|
|
- {name: updateSettings, params: [data]}
|
|
- {name: fetchPlans, params: []}
|
|
- {name: changePlan, params: [planId]}
|
|
- {name: cancelSubscription, params: []}
|
|
|
|
hooks:
|
|
- name: useTenant
|
|
file: hooks/useTenant.ts
|
|
rf: RF-TENANTS-001
|
|
returns: "{tenant, settings, isLoading}"
|
|
description: Acceso a tenant actual
|
|
|
|
- name: useSubscription
|
|
file: hooks/useSubscription.ts
|
|
rf: RF-TENANTS-003
|
|
returns: "{subscription, hasFeature, isWithinLimits}"
|
|
description: Verificar features del plan
|
|
|
|
# =============================================================================
|
|
# COMPONENTES COMPARTIDOS
|
|
# =============================================================================
|
|
|
|
shared:
|
|
path: apps/frontend/src/shared/
|
|
|
|
ui:
|
|
- {name: Button, file: ui/Button.tsx, variants: [primary, secondary, danger]}
|
|
- {name: Input, file: ui/Input.tsx, types: [text, email, password, number]}
|
|
- {name: Select, file: ui/Select.tsx}
|
|
- {name: Checkbox, file: ui/Checkbox.tsx}
|
|
- {name: Modal, file: ui/Modal.tsx}
|
|
- {name: Drawer, file: ui/Drawer.tsx}
|
|
- {name: Table, file: ui/Table.tsx}
|
|
- {name: Pagination, file: ui/Pagination.tsx}
|
|
- {name: Badge, file: ui/Badge.tsx}
|
|
- {name: Avatar, file: ui/Avatar.tsx}
|
|
- {name: Dropdown, file: ui/Dropdown.tsx}
|
|
- {name: Tabs, file: ui/Tabs.tsx}
|
|
- {name: Card, file: ui/Card.tsx}
|
|
|
|
layout:
|
|
- {name: AppLayout, file: layout/AppLayout.tsx, description: Layout principal}
|
|
- {name: Header, file: layout/Header.tsx}
|
|
- {name: Sidebar, file: layout/Sidebar.tsx}
|
|
- {name: Footer, file: layout/Footer.tsx}
|
|
- {name: PageHeader, file: layout/PageHeader.tsx}
|
|
|
|
feedback:
|
|
- {name: Alert, file: feedback/Alert.tsx, types: [success, error, warning, info]}
|
|
- {name: Toast, file: feedback/Toast.tsx}
|
|
- {name: Spinner, file: feedback/Spinner.tsx}
|
|
- {name: Skeleton, file: feedback/Skeleton.tsx}
|
|
- {name: EmptyState, file: feedback/EmptyState.tsx}
|
|
- {name: ErrorBoundary, file: feedback/ErrorBoundary.tsx}
|
|
|
|
forms:
|
|
- {name: FormField, file: forms/FormField.tsx}
|
|
- {name: FormLabel, file: forms/FormLabel.tsx}
|
|
- {name: FormError, file: forms/FormError.tsx}
|
|
- {name: DatePicker, file: forms/DatePicker.tsx}
|
|
- {name: FileUpload, file: forms/FileUpload.tsx}
|
|
- {name: SearchInput, file: forms/SearchInput.tsx}
|
|
|
|
# =============================================================================
|
|
# ROUTING
|
|
# =============================================================================
|
|
|
|
routing:
|
|
public_routes:
|
|
- {path: /login, component: LoginPage, feature: auth}
|
|
- {path: /forgot-password, component: ForgotPasswordPage, feature: auth}
|
|
- {path: /reset-password/:token, component: ResetPasswordPage, feature: auth}
|
|
- {path: /onboarding, component: OnboardingPage, feature: tenants}
|
|
|
|
private_routes:
|
|
- {path: /, component: DashboardPage, feature: dashboard}
|
|
- {path: /profile, component: ProfilePage, feature: users}
|
|
- {path: /users, component: UsersPage, feature: users, permission: "users:read:all"}
|
|
- {path: /users/:id, component: UserDetailPage, feature: users}
|
|
- {path: /settings/preferences, component: PreferencesPage, feature: users}
|
|
- {path: /settings/roles, component: RolesPage, feature: roles, permission: "roles:read:all"}
|
|
- {path: /settings/roles/:id, component: RoleDetailPage, feature: roles}
|
|
- {path: /settings/organization, component: TenantSettingsPage, feature: tenants}
|
|
- {path: /settings/subscription, component: PlansPage, feature: tenants}
|
|
- {path: /admin/tenants, component: TenantsPage, feature: tenants, role: super_admin}
|
|
|
|
# =============================================================================
|
|
# DEPENDENCIAS
|
|
# =============================================================================
|
|
|
|
dependencies:
|
|
production:
|
|
- "react": "^18.2.0"
|
|
- "react-dom": "^18.2.0"
|
|
- "react-router-dom": "^6.20.0"
|
|
- "zustand": "^4.4.0"
|
|
- "axios": "^1.6.0"
|
|
- "zod": "^3.22.0"
|
|
- "react-hook-form": "^7.48.0"
|
|
- "@hookform/resolvers": "^3.3.0"
|
|
- "tailwindcss": "^3.4.0"
|
|
- "@headlessui/react": "^1.7.0"
|
|
- "@heroicons/react": "^2.1.0"
|
|
- "date-fns": "^2.30.0"
|
|
- "clsx": "^2.0.0"
|
|
|
|
development:
|
|
- "vite": "^5.0.0"
|
|
- "typescript": "^5.3.0"
|
|
- "vitest": "^1.0.0"
|
|
- "@testing-library/react": "^14.1.0"
|
|
- "@testing-library/jest-dom": "^6.1.0"
|
|
- "@types/react": "^18.2.0"
|
|
- "@types/react-dom": "^18.2.0"
|
|
|
|
# =============================================================================
|
|
# TESTS
|
|
# =============================================================================
|
|
|
|
tests:
|
|
framework: Vitest
|
|
target_coverage: 70%
|
|
structure:
|
|
unit: "src/**/__tests__/*.test.ts"
|
|
component: "src/**/__tests__/*.test.tsx"
|
|
integration: "src/__tests__/integration/*.test.tsx"
|
|
|
|
# =============================================================================
|
|
# HISTORIAL
|
|
# =============================================================================
|
|
|
|
history:
|
|
- date: "2026-01-06"
|
|
action: "Implementacion Sprints 1-3 (109 SP)"
|
|
author: ORQUESTADOR-Claude-Opus
|
|
sprint: "1-3"
|
|
changes:
|
|
- "25 paginas implementadas"
|
|
- "4 Zustand stores creados"
|
|
- "23 rutas agregadas a router"
|
|
- "Feature catalogs completado (100%)"
|
|
- "Feature settings estructura creada"
|
|
- "Build status: Pass (4.07s)"
|
|
features_created:
|
|
catalogs:
|
|
status: "100% implementado"
|
|
pages: 17
|
|
stores: 4
|
|
hooks: 4
|
|
components: 4
|
|
settings:
|
|
status: "parcial (2 pages)"
|
|
pages: 2
|
|
stores: 0
|
|
hooks: 3
|
|
components: 7
|
|
|
|
- date: "2025-12-05"
|
|
action: "Reestructuracion completa siguiendo filosofia GAMILIT"
|
|
author: Requirements-Analyst
|
|
changes:
|
|
- "Documentados 4 features foundation completos"
|
|
- "Agregada trazabilidad RF por componente y page"
|
|
- "Documentados stores, hooks, api clients"
|
|
- "Definido routing con permisos"
|