docs: README raíz, api y web al día (módulos, acciones del proxy, auditoría, extensiones, bancos y finanzas)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
99c0a9259c
commit
89e25ad8e6
4 files changed
+53
-7
No files matched your search
+15
-2
@@ -65,13 +65,26 @@ El frontend arma los parámetros OData y el cuerpo; el backend solo valida y eje
|
||||
| `GET /api/sl/:recurso/:clave?$select` | Un registro. La clave se valida y escapa según su tipo. |
|
||||
| `POST /api/sl/:recurso` | Crea; devuelve lo que responde SAP (ej. `DocEntry`, `DocNum`). |
|
||||
| `PATCH /api/sl/:recurso/:clave` | Modifica (204). Acepta `If-Match` con el `odata.etag` leído (concurrencia optimista: SAP responde 412 si el documento cambió). |
|
||||
| `POST /api/sl/:recurso/:clave/:accion` | Acción de un registro (hoy `Cancel` de pagos y asientos). Solo las que el recurso declara en `actions`; requiere el permiso de escritura. |
|
||||
| `POST /api/sl/:accion` | Acción de solo consulta sin registro (`SeriesService_GetDocumentSeries`, series de numeración): cualquier sesión. |
|
||||
|
||||
Reglas:
|
||||
- **Solo recursos registrados** en `src/sl/sl-resources.ts`; el resto es 404. Nunca registrar `EmployeesInfo` (contiene `U_WEB_PASS`).
|
||||
- Cada recurso declara clave, métodos y la ruta de menú que gobierna lectura/escritura. Los catálogos de consulta (`Items`, `Warehouses`...) se leen con cualquier sesión.
|
||||
- Parámetros OData fuera de la lista (`$apply`...) → 400. `$expand` solo si el recurso declara qué colecciones admite.
|
||||
- Cabeceras B1S-* permitidas: `B1S-ReplaceCollectionsOnPatch` (PATCH), `B1S-CaseInsensitive` y `B1S-PageSize` (GET). Se fijan solas: `B1S-PageSize` = `$top` y `B1S-CaseInsensitive` si hay `$filter`.
|
||||
- No hay DELETE ni acciones (`Cancel`, `Close`); se agregan por recurso cuando haga falta.
|
||||
- Las escrituras dejan una línea `AUDIT <usuario> <método> <recurso>` en el log.
|
||||
- No hay DELETE. Las acciones (`Cancel`) existen solo donde el recurso las declara en `actions` (pagos recibidos y efectuados, asientos); `Close` y las demás se agregan por recurso cuando haga falta.
|
||||
- Las escrituras y las acciones se registran en la auditoría (ver abajo) y dejan una línea `AUDIT` en el log.
|
||||
|
||||
Agregar un recurso nuevo = una línea en `SL_RESOURCES`. El test en vivo (`SAP_LIVE=1 npm run test:e2e`) comprueba que todos existan en el Service Layer del cliente.
|
||||
|
||||
## Auditoría
|
||||
|
||||
Tabla `audit_log` en la misma SQLite. Registra inicios de sesión (correctos, fallidos con su motivo y cierres), cada creación, modificación y acción (`sl_action`) que pasa por el proxy (recurso, clave, resultado y **solo los nombres de los campos**, nunca valores ni contraseñas), las operaciones denegadas por permisos y los cambios de permisos de menú. Las lecturas no se auditan. `AuditService.record` nunca lanza: un fallo del registro no cambia la operación del usuario.
|
||||
|
||||
| Endpoint | Quién | Descripción |
|
||||
|---|---|---|
|
||||
| `GET /api/audit?usuario&accion&recurso&resultado&desde&hasta&page` | Administrador | Consulta; 50 por página (máx. 200) |
|
||||
|
||||
Pendiente de afinar: retención programada, IP real detrás del proxy de desarrollo, exportar a CSV.
|
||||
|
||||
+20
-3
@@ -15,7 +15,7 @@ Es un ERP, no un sitio publicitario: rápido y ligero.
|
||||
- Sin librerías de UI (nada de Material/PrimeNG): componentes propios, densos (13 px).
|
||||
- Fuentes del sistema, sin webfonts; sin animaciones.
|
||||
- Zoneless + `OnPush`; rutas con `loadComponent` para cargar solo lo que se usa.
|
||||
- Presupuesto del bundle inicial: aviso a 260 kB, error a 400 kB (`angular.json`). Hoy: ~200 kB (56 kB comprimido).
|
||||
- Presupuesto del bundle inicial en `angular.json` (aviso a 300 kB). Hoy: ~289 kB (82 kB comprimido). La configuración de las pantallas (documentos, maestros, pagos) se carga en diferido con un `resolve`; el enrutador solo necesita sus listas de rutas (`*-paths.ts`).
|
||||
- Listas largas con paginación del servidor (`$top/$skip`) o virtualización.
|
||||
|
||||
## Temas
|
||||
@@ -39,7 +39,7 @@ Tokens de color: `--app --shell --shell-ink --shell-quiet --win --panel --line -
|
||||
|
||||
- `core/auth`: `SessionStore` (sesión en localStorage, compartida entre pestañas, con timeout deslizante según el servidor), `AuthService` (login/logout/expire), interceptor (Bearer en `/api`, renueva actividad y atiende los 401) y guards (`authGuard`, `guestGuard`, `permissionGuard`).
|
||||
- `core/menu`: `MenuService` carga `GET /api/user/menu` una vez por sesión; el menú visible sale de `MENU` (`@basic-erp/sap-types`) filtrado por permisos.
|
||||
- `app.routes.ts` genera una ruta por pantalla del menú; las que aún no existen muestran "no disponible" (`ComingSoonPage`). Para construir una pantalla, se reemplaza su `loadComponent`.
|
||||
- `app.routes.ts` genera una ruta por pantalla del menú (documentos, maestros, pagos, asientos, administración); una ruta del menú sin pantalla muestra "no disponible" (`ComingSoonPage`). Un test comprueba que cada ruta del menú tiene su pantalla y su permiso.
|
||||
- Un 401 en cualquier llamada cierra la sesión local y lleva al login recordando la ruta (`?returnUrl=`, solo rutas internas).
|
||||
|
||||
## Componentes compartidos (`src/app/shared`)
|
||||
@@ -126,7 +126,7 @@ Las tres rutas las gobierna el permiso de menú de la ruta padre. Se generan sol
|
||||
|
||||
#### Formulario de documentos de ventas y compras (`document-form.page`)
|
||||
|
||||
Lo usan las pantallas con `partner` en su `DocumentScreen` (ventas y compras); el resto de documentos muestra aún un aviso.
|
||||
Lo usan todas las pantallas de documento: ventas y compras (con socio, líneas con precios e impuestos) y las de inventario y solicitudes (sin socio ni totales). Cada pantalla declara su `DocumentLayout` (`document-layouts.ts`): campos de cabecera y pie (máximo 2 columnas), columnas de línea y colección que se guarda; el formulario no sabe de qué documento se trata.
|
||||
|
||||
- **Cabecera**: socio de negocio (lista de valores filtrada por `CardType`; no se cambia en un documento ya creado), Nº de referencia, fechas y descuento %; **líneas** con `sbo-lines-grid`; **totales** informativos (SAP recalcula al guardar) con las tasas de `SalesTaxCodes` (también en compras: el Service Layer no tiene un maestro propio; `partner.taxResource` permite cambiarlo en una rama de cliente).
|
||||
- **Códigos escritos a mano**: al salir del campo (socio con `resolveOnLeave` en `sbo-lookup-field`; artículo, almacén e impuesto en la grilla) se buscan con `SlLookupApi` (`core/sl/sl-lookup.ts`) en la misma lista que abre "…": se normaliza el código y se completa nombre/descripción; si no existe se avisa (en el campo o en la barra de estado) y la celda vuelve a su valor.
|
||||
@@ -137,6 +137,23 @@ Lo usan las pantallas con `partner` en su `DocumentScreen` (ventas y compras); e
|
||||
- **Navegación** primero / anterior / siguiente / último por `DocEntry`.
|
||||
- La lógica sin Angular está en `document-model.ts` (totales, payload, validación, navegación) y el acceso HTTP en `core/sl/sl-document.ts`.
|
||||
|
||||
### Campos por cliente (extensiones)
|
||||
|
||||
Cada módulo tiene su archivo de extensiones, vacío en `main` (`ventas.extensions.ts`, `compras.extensions.ts`, `inventario.extensions.ts`, `socios.extensions.ts`, `articulos.extensions.ts`, `finanzas.extensions.ts`). La rama `cliente/<nombre>` agrega ahí, por ruta de pantalla, campos de cabecera o pie, columnas de línea y de lista (estándar o `U_*`), y puede **ocultar** (`hide…`) o dejar de **solo lectura** (`readOnly…`) lo que no use. Un nombre inexistente, ocultar un campo obligatorio o una ruta ajena lanzan un error al arrancar.
|
||||
|
||||
### Maestros (`features/masters`)
|
||||
|
||||
Clientes, proveedores, artículos y plan de cuentas comparten una lista y un formulario (`MasterScreen` / `MasterLayout`): código y nombre arriba y los demás campos en pestañas, con tablas editables (`sbo-rows-table`: direcciones, contactos, precios, stock por almacén). El código y los campos `immutable` no se cambian una vez creado el registro; al modificar se envía `If-Match` y un 412 avisa del conflicto. El plan de cuentas abre como **árbol** (`chart-tree.page`) y su formulario muestra las casillas de grupo.
|
||||
|
||||
### Bancos y finanzas
|
||||
|
||||
- **Pagos recibidos y efectuados** (`features/banking`): un mismo formulario configurado por `PaymentScreen`. Se aplican a las facturas y notas de crédito abiertas del socio, a cuenta (lo que sobra de los medios queda como anticipo) o a cuentas contables; medios: efectivo, transferencia, cheques y, en los recibidos, tarjetas de crédito. Un pago contabilizado no se edita: se consulta y se anula (`Cancel`). Lógica sin Angular en `payment-model.ts`.
|
||||
- **Asientos contables** (`features/finance`): líneas con cuenta, debe o haber, dimensiones, proyecto, referencias y vencimiento; solo se crea si cuadra. Los manuales se cancelan (SAP genera el reverso). Lógica en `journal-model.ts`.
|
||||
|
||||
### Administración
|
||||
|
||||
`/admin/permisos` (permisos de menú) y `/admin/auditoria` (consulta de la auditoría: filtros por usuario, acción, recurso, resultado y fechas), solo con acceso total.
|
||||
|
||||
### Permisos de menú (`/admin/permisos`)
|
||||
|
||||
Pantalla del módulo "Administración", solo para quien tiene acceso total (`*`; el API de permisos exige ser administrador). Lista los usuarios web con permisos y, al elegir uno, muestra los módulos y pantallas con casillas (el módulo completo se guarda como `/modulo/*`, las pantallas sueltas como rutas). "Acceso total" guarda `*`; "Administración" no tiene casilla: solo llega con acceso total. Los patrones que no corresponden a ninguna pantalla actual se conservan. Un usuario nuevo se agrega por su `U_WEB_USER` y no existe hasta pulsar Guardar. El servidor impide quitar al último administrador. La conversión casillas ↔ patrones está en `features/admin/permissions-model.ts`.
|
||||
|
||||
Reference in new issue
Block a user