# 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: 19
  total_pages: 42
  total_components: 150
  total_stores: 18
  total_hooks: 25
  total_api_clients: 19
  implemented: 6   # auth, users, tenants, catalogs, settings (partial)
  documented: 10

  # 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"
