#49 docs: documentar provenance (gráficos, admin CRUD, patrones de testing)
This commit is contained in:
26
AGENTS.md
26
AGENTS.md
@@ -14,8 +14,13 @@
|
||||
src/
|
||||
├── assets/ # Imágenes, iconos estáticos
|
||||
├── components/ # Componentes Vue reutilizables
|
||||
│ ├── order/ # Componentes del resumen de pedido público
|
||||
│ ├── provenance/ # Provenance (público + admin): gráficos, sección y CRUD admin
|
||||
│ │ └── admin/ # Organizaciones, Proveedores, Geografía, SupplierLinkDialog
|
||||
│ └── graph/ # CytoscapeChart.vue (wrapper genérico de cytoscape)
|
||||
├── layouts/ # Layouts de página
|
||||
├── pages/ # Vistas (auto-routed desde文件名)
|
||||
│ └── admin/ # Páginas admin (products, organizations, suppliers, geography, ...)
|
||||
├── plugins/ # Configuración de Vuetify, etc.
|
||||
├── router/ # Configuración de rutas
|
||||
├── services/ # API services (auth.js, etc.)
|
||||
@@ -23,6 +28,7 @@ src/
|
||||
│ ├── api-implementation.js # Factory que selecciona implementación
|
||||
│ ├── auth.js # Manejo de auth (login, tokens JWT)
|
||||
│ ├── django-api.js # Implementación de API para Django
|
||||
│ ├── graph/ # Genérico de grafos: graph-layout.js (layout por columnas + cytoscape)
|
||||
│ └── http.js # Axios instance con interceptors
|
||||
├── stores/ # Pinia stores
|
||||
└── styles/ # SCSS settings
|
||||
@@ -89,12 +95,16 @@ No hay un estilo mayoritario. El código histórico está partido:
|
||||
### Config de ESLint
|
||||
- `.eslintrc.js` está **versionado** y extiende `vuetify` (estilo **StandardJS**)
|
||||
- Tiene `ignorePatterns` masivo: `src/**` excepto los archivos nuevos de la tarea
|
||||
(`!src/components/order/**`, `!src/components/PublicOrderSummary.vue`, `!src/pages/pedido/**`)
|
||||
(`!src/components/order/**`, `!src/components/PublicOrderSummary.vue`,
|
||||
`!src/components/provenance/**`, `!src/components/graph/*.vue`,
|
||||
`!src/services/graph/*.js`, `!src/pages/pedido/**`)
|
||||
- **Los archivos nuevos deben seguir StandardJS** para quedar lint-eados:
|
||||
- 2 espacios (indent), sin semicolons, comillas simples
|
||||
- `function () {}` con espacio, `const f = (x) => x` (arrow-parens en args únicos NO)
|
||||
- Sin trailing commas; `{ clave: valor }` con espacios internos
|
||||
- Eventos personalizados en kebab-case, `v-slot:nombre` (no `#nombre`)
|
||||
- Atributos en orden alfabético dentro de su categoría (`vue/attributes-order`):
|
||||
directivas (`v-if`, `v-model`) primero, luego props/attrs, luego `@eventos`
|
||||
|
||||
### PELIGRO: `npm run lint` usa `--fix`
|
||||
- Reformatea automáticamente TODO archivo no ignorado que no cumpla estilo
|
||||
@@ -109,6 +119,9 @@ No hay un estilo mayoritario. El código histórico está partido:
|
||||
- Los tests **no usan globals**: importar `describe/it/expect/vi` explícitamente desde `vitest`
|
||||
- Tests de páginas con router: esperar a que el router actualice `route.params` con un helper (`waitForRouteParam`)
|
||||
- Los `.d.ts` generados (`auto-imports.d.ts`, `components.d.ts`, `typed-router.d.ts`) están en `.gitignore`
|
||||
- **Diálogos Vuetify se teleportan a `document.body`**: en tests, el contenido NO está en `wrapper.text()`. Assertar sobre `document.body.textContent` (ver `tests/unit/components/provenance/ProvenanceDetailModal.spec.js`). Helpers para interactuar con inputs/buttons de diálogos en `tests/unit/components/provenance/admin/helpers.js` (`setBodyInput`, `clickBody`)
|
||||
- **Selects/autocompletados en tests**: escribir en su `<input>` NO cambia el `v-model`. Emitir `update:modelValue` sobre el componente (`findAllComponents({ name: 'VSelect' })` / `{ name: 'VAutocomplete' }`). OJO: `VAutocomplete` también matchea como `VSelect`, y `v-data-table` añade un `VSelect` (items-per-page); filtrar por `props('items')` cuando haya varios
|
||||
- **Listas largas** (municipios, proveedores): `v-autocomplete` con búsqueda, pero la selección debe conservarse aunque el filtro no la incluya → `items` computado que devuelve los filtrados + los seleccionados que no estén (patrón en `SuppliersManagement.vue`, `GeographyManagement.vue`, `SupplierLinkDialog.vue`)
|
||||
|
||||
## Common Issues
|
||||
1. **Página en blanco:** Verificar que los componentes en `src/pages/*.vue` tengan import explícito
|
||||
@@ -159,3 +172,14 @@ No hay un estilo mayoritario. El código histórico está partido:
|
||||
- `getPublicOrderSummary(code)` en `services/api.js` / `django-api.js`
|
||||
- Componentes modulares en `src/components/order/`: `OrderAccessInfo.vue` (código + link), `OrderCustomer.vue`, `OrderLines.vue`, `OrderPayment.vue`, `OrderTotal.vue`
|
||||
- Orquestador: `PublicOrderSummary.vue`; `OrderAccessInfo.vue` se comparte con `SummaryPurchase.vue`
|
||||
|
||||
## Provenance (Origen e historia de los productos)
|
||||
- Los gráficos se renderizan en el resumen público (`ProvenanceSection` dentro de `PublicOrderSummary.vue`) a partir de `product_provenance` embebido en el resumen (`GET /don_confiao/resumen_publico/<code>`). El backend NO genera los gráficos.
|
||||
- Payload: `[{ product: {id, name, catalogue_images[]}, suppliers: [{ supplier: {...}, organization|null, municipality|null, department|null, country|null }] }]`.
|
||||
- **Genérico reutilizable:**
|
||||
- `src/services/graph/graph-layout.js`: `computeColumnLayout` (layout por columnas puro) y `toCytoscapeElements` (adapta nodos/aristas a cytoscape, añade clase `has-image` si el nodo tiene imagen)
|
||||
- `src/components/graph/CytoscapeChart.vue`: wrapper de cytoscape.js (props `elements`, `styles` (map a `style` en cytoscape), `layout`, `height`; emite `select` con `node.data()`)
|
||||
- **Específico público** (`src/components/provenance/`): builders puros en `provenance-graph.js` (`buildSupplierOrganizationGraph`, `buildTerritoryGraph`, `hasAnySupplier`, `hasAnyTerritory`), los charts (que muestran "próximamente estará disponible" cuando no hay relaciones), `ProvenanceDetailModal.vue` y `ProvenanceSection.vue`
|
||||
- **Admin CRUD** (`src/components/provenance/admin/`): `OrganizationsManagement.vue`, `SuppliersManagement.vue`, `GeographyManagement.vue` (tabs países/departamentos/municipios), `SupplierLinkDialog.vue` (vincula productos↔proveedores, abierto desde `ProductsManagement.vue`). Páginas en `src/pages/admin/{organizations,suppliers,geography}.vue`; rutas en `ADMIN_ROUTES` (`router/index.js`); ítems en `NavBar.vue`
|
||||
- **Endpoints provenance**: `/don_confiao/api/organizations/`, `/suppliers/`, `/countries/`, `/departments/`, `/municipalities/` (CRUD); vincular productos con `PATCH /don_confiao/api/products/<id>/` body `{"suppliers": [ids]}`; detalle de producto (con `suppliers`) via `GET /don_confiao/api/products/<id>/`
|
||||
- Los tests mockean cytoscape (`vi.mock('cytoscape', ...)`) y la API con `global.provide: { api }`
|
||||
|
||||
Reference in New Issue
Block a user