Files
don_confiao_frontend/AGENTS.md

162 lines
7.9 KiB
Markdown

# Don Confiao - Frontend
## Tech Stack
- **Framework:** Vue 3 (Composition API)
- **UI Library:** Vuetify 3
- **Routing:** Vue Router 4 (auto-routes con `unplugin-vue-router`)
- **State:** Pinia
- **HTTP:** Axios
- **Build:** Vite
- **Linting:** ESLint
## Project Structure
```
src/
├── assets/ # Imágenes, iconos estáticos
├── components/ # Componentes Vue reutilizables
├── layouts/ # Layouts de página
├── pages/ # Vistas (auto-routed desde文件名)
├── plugins/ # Configuración de Vuetify, etc.
├── router/ # Configuración de rutas
├── services/ # API services (auth.js, etc.)
│ ├── api.js # Clase wrapper que делегат methods
│ ├── 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
│ └── http.js # Axios instance con interceptors
├── stores/ # Pinia stores
└── styles/ # SCSS settings
```
## Important Conventions
### Auto-imports
- Componentes en `src/components/` se auto-importan por nombre
- Los archivos en `src/pages/*.vue` se routing automáticamente via `unplugin-vue-router`
- Alias `@` = `src/`
### Pages (CRITICAL)
**Siempre importar componentes en los archivos de página:**
```vue
<template>
<MiComponente />
</template>
<script setup>
import MiComponente from '@/components/MiComponente.vue';
</script>
```
### Componentes
- Usar Composition API (`<script setup>` o `export default { }`)
- Naming: PascalCase (ej: `LoginDialog.vue`, `CartGrid.vue`)
- Componentes de página van en `pages/`, componentes reutilizables en `components/`
### Servicios API
- Ubicación: `src/services/`
- Usar Axios para HTTP requests
- JWT tokens en localStorage (`access_token`, `refresh_token`)
- La API se inyecta globalmente via `app.provide('api', api)` y se usa con `inject('api')`
### Routing
- Rutas automáticas basadas en archivos en `src/pages/` (no se registran rutas a mano, excepto en casos especiales)
- `router/index.js` usa `setupLayouts(routes)` + guard `beforeEach`:
- Meta `requiresAuth` → redirige a `/autenticarse` si no hay token
- Meta `requiresAdmin` (o rutas en `ADMIN_ROUTES`) → redirige si el usuario no es admin
- **Rutas públicas** (ej: `/pedido/:code?`) NO deben llevar `requiresAuth`
## Environment Variables
- `VITE_DJANGO_BASE_URL` - URL del backend Django
- `VITE_API_IMPLEMENTATION` - Selecciona la implementación de API (default: django)
## Commands
```bash
npm run dev # Desarrollo (puerto 3000)
npm run preview # Preview build
npm run lint # ESLint --fix (¡OJO: reformatea archivos, ver sección Lint!)
npm test # Vitest (unit tests)
npm run test:watch
npx vite build --outDir /tmp/opencode/dist-check # Verificar build sin tocar dist/
```
## Lint y Estilos (IMPORTANTE)
### El repo mezcla DOS estilos JS (~50/50)
No hay un estilo mayoritario. El código histórico está partido:
- **StandardJS** (2 espacios, sin semicolons, comillas simples): `main.js`, `stores/*`, `plugins/*`, `router/index.js`, `services/http.js` y muchos `.vue`
- **4 espacios + semicolons + comillas dobles**: la mayoría de `services/` y otros `.vue`
### 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/**`)
- **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`)
### PELIGRO: `npm run lint` usa `--fix`
- Reformatea automáticamente TODO archivo no ignorado que no cumpla estilo
- Puede modificar decenas de archivos de golpe. Antes de usarlo revisar qué está ignorado
- Para **evaluar** sin modificar: `npx eslint . --ignore-path .gitignore` (sin `--fix`)
- Para desglosar por archivo/regla: `npx eslint . --ignore-path .gitignore --format json | node -e "..."`
## Testing (Vitest)
- Correr con `npm test` (`vitest run`)
- Infra en `tests/setup.js` (polyfills: `navigator.clipboard`, `ResizeObserver`, `IntersectionObserver`, `matchMedia`) + `vitest.config.mjs`
- **`vitest.config.mjs` requiere `server.deps.inline: ['vuetify']`** para montar componentes Vuetify en jsdom
- 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`
## Common Issues
1. **Página en blanco:** Verificar que los componentes en `src/pages/*.vue` tengan import explícito
2. **`npm run build` falla con `EACCES`:** `dist/` tiene archivos root (docker, gitignored) y no se puede borrar. Verificar el build con `npx vite build --outDir /tmp/opencode/dist-check`
3. **Build falla con "Illegal '/' in tags" / "Invalid end tag":** tags de `CurrencyText` malformados pre-existentes (ej: `<CurrencyText <:value="..."/CurrencyText >` o `</CurrencyText>` duplicado). Buscar `CurrencyText` mal cerrado en `ReconciliationJar.vue` / `ReconciliationJarView.vue`
4. **Después de mergear `main`:** correr `npm install` — las deps nuevas (ej: `leaflet` en `StoreLocation.vue`) quedan en `package.json` pero no instaladas → el build falla con "Rollup failed to resolve import"
5. **Errores de lint:** ver sección Lint y Estilos (el repo no cumple un único estilo; no "arreglar" el lint de archivos pre-existentes)
## Git Commits
**Antes de hacer commit:**
1. **SIEMPRE pedir permiso al usuario antes de hacer commit**
2. Mostrar resumen de los cambios que se incluirán
**Formato de mensajes:**
- Usar prefijo `#<numero>` para referenciar el issue (ej: `#28 feat: add login` donde #28 es el número del issue en GitHub/GitLab)
- Prefijos válidos: `feat`, `fix`, `chore`, `docs`, `refactor`, `style`
## Análisis del Proyecto
### Flujo de Autenticación
1. **Login:** `AuthService.login(credentials)` → obtiene JWT tokens → guarda en localStorage
2. **Token:** Se envía en headers via interceptor en `http.js` (`Authorization: Bearer <token>`)
3. **Refresh:** El interceptor renueva automáticamente el token si expira (401)
4. **Logout:** `AuthService.logout()` → limpia localStorage
### Estructura de API
- `api.js`: Interfaz genérica con métodos como `getCustomers()`, `getProducts()`, etc.
- `api-implementation.js`: Factory que selecciona implementación (actualmente solo Django)
- `django-api.js`: Implementación concreta con endpoints de Django
### Componentes Principales
- **NavBar.vue**: Barra de navegación con menú de usuario
- **LoginDialog.vue**: Diálogo de inicio de sesión
- **Purchase.vue / AdminPurchase.vue**: Componentes de compra
- **Cart.vue**: Carrito de compras
- **SummaryPurchase.vue**: Resumen de compra
### Endpoints Django Comunes
- `/api/token/` - Autenticación (login/refresh)
- `/users/me/` - Usuario actual
- `/don_confiao/api/customers/` - Clientes
- `/don_confiao/api/products/` - Productos
- `/don_confiao/api/sales/` - Ventas
- `/don_confiao/api/resumen_publico/<code>` - Resumen público de pedido por código (AllowAny)
## Consulta Pública de Pedidos
- Ruta `/pedido/:code?` (pública, sin `requiresAuth`)
- `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`