# Constitución del Proyecto — Sistema Base

> Reglas innegociables para toda IA o desarrollador que contribuya a este proyecto.
> La guía práctica, mapa de archivos y referencia rápida viven en [`AGENTS.md`](AGENTS.md).
> Si hay conflicto entre ambos, **gana esta constitución**.

---

## §1. Principios

1. **Cambios mínimos.** Cada modificación debe tener el alcance más pequeño posible que resuelva el problema. No refactorizar lo no pedido.
2. **Convenciones sobre configuración.** Seguir los patrones existentes (ver [`AGENTS.md`](AGENTS.md)). No introducir nuevas librerías, frameworks ni patrones sin un ADR.
3. **No sobre-ingeniería.** La solución más simple que cumpla los requisitos es la correcta.
4. **Tests solo si se piden.** Este proyecto no exige cobertura obligatoria; si un spec solicita tests, se implementan.
5. **Documentación viva.** Todo cambio de estado en specs, features o migraciones se actualiza en el índice correspondiente **en el mismo commit**.

---

## §2. Arquitectura

Capas obligatorias en este orden:

```
Controller → Form Request (validación) → [Service/Repository opcional] → Model
```

- **Controladores delgados:** validación + consulta + redirect/vista.
- **Lógica reutilizable** en el modelo o en clases de soporte (traits, services), no duplicada entre controladores.
- **Plantillas Blade** extienden `layouts.app` (panel) o `layouts.guest` (públicas).
- **Componentes UI** en `resources/views/components/`: `<x-card>`, `<x-input>`, `<x-select>`, `<x-button>`, `<x-label>`, `<x-error>`, `<x-flash>`.
- **Componentes React** en `resources/js/{modulo}/`. Se montan como "islands" dentro de vistas Blade vía `<div id="...">`. Sin router cliente, sin SPA, sin reemplazo de páginas Blade. Ver [ADR-0006](docs/adr/0006-react-adoption.md).

Stack obligatorio (ver [`AGENTS.md §2`](AGENTS.md) para tabla completa):

| Capa | Tecnología |
|---|---|
| Backend | PHP 8.2+ / Laravel 13 |
| Plantillas | Blade (SSR por defecto) |
| CSS | Tailwind CSS 4 vía Vite |
| Componentes interactivos | React 18 + TypeScript (vía Vite) |
| Interacciones ligeras | Alpine.js (convive con React para toggles, modals, dropdowns) |
| Gráficos | Chart.js |
| Iconos | FontAwesome Free |
| BD | MySQL/MariaDB, `utf8mb4_unicode_ci` |
| Permisos | spatie/laravel-permission |

---

## §3. Aislamiento per-usuario (SaaS multiusuario)

> **Pivote (ADR-0007):** este proyecto derivó de una plantilla multi-empresa a un **SaaS per-usuario**
> (LinkVault AI). El aislamiento ya no es por `company_id` sino por `user_id`. La capa de empresas
> (`companies`, `company_id`, `CompanyController`) se retira en
> [C003](specs/changes/C003-pivot-per-user-retire-companies.md). Esta regla rige el código nuevo desde ya;
> el código heredado se migra en C003.

**Regla de oro:** todo dato de dominio que pertenezca a un usuario lleva `user_id` (FK a `users`,
`cascadeOnDelete`).

- El **superadmin** opera a nivel **plataforma** (usuarios, planes, prompts, logs, consumo de IA). Se
  detecta con `$user->isSuperAdmin()`. NO accede al contenido privado de un usuario salvo una función
  explícita de soporte con auditoría.
- Cualquier consulta de un usuario normal DEBE filtrarse por su propiedad:

```php
Model::query()->where('user_id', $request->user()->id)
```

- En `store`/`update`, NUNCA aceptar `user_id` del request: forzar `$request->user()->id`.
- En `show`/`edit`/`update`/`destroy`, autorizar con una **Policy** de propiedad
  (`$this->authorize($model)` ⇒ `abort_unless($model->user_id === $user->id, 403)`). Ver ADR-0007 D2.

---

## §4. Seguridad

1. **CSRF:** `@csrf` en todo formulario; `@method('PUT'|'PATCH'|'DELETE')` según la ruta.
2. **Nunca interpolar** entrada del usuario en SQL crudo; usar Eloquent/Query Builder con bindings.
3. **Nunca `{!! !!}`** con datos del usuario; siempre `{{ }}`.
4. **Acciones destructivas:** formulario POST/DELETE con `onsubmit="return confirm('...')"`, jamás un enlace GET.
5. **No exponer** en vistas ni logs: contraseñas, tokens, datos de otras empresas.
6. **Rate limiting** en endpoints sensibles a fuerza bruta (login y similares).
7. **Un usuario no puede eliminarse a sí mismo**; un admin no puede gestionar superadmins ni usuarios de otra empresa ni asignar el rol `superadmin`.
8. **Protección en 3 capas** (ruta + controlador + vista) para toda acción protegida por permisos.

---

## §5. Idioma

- **Toda la interfaz**, mensajes, validaciones y comentarios: **español**.
- Las rutas web usan slugs en español (`/usuarios`, `/empresas`, `/configuracion`).
- Los nombres internos de rutas, tablas, modelos y permisos van en **inglés** (`users.index`, tabla `users`, permiso `users.view`).

---

## §6. Specs y SDD (Spec-Driven Development)

1. **Toda feature o cambio significativo requiere spec aprobada antes de código.** Excepción: hotfixes <2h con aprobación retroactiva.
2. **Plantillas obligatorias:** [`docs/spec-template-feature.md`](docs/spec-template-feature.md), [`docs/spec-template-change.md`](docs/spec-template-change.md), [`docs/spec-template-hotfix.md`](docs/spec-template-hotfix.md).
3. **Workflow de 5 fases:** DRAFT → REVIEW → PLAN → IMPLEMENT → VERIFY. Ver [`docs/workflow.md`](docs/workflow.md).
4. **Índices vivos** (actualizar en el mismo commit del cambio):
   - [`specs/INDEX.md`](specs/INDEX.md) — estado de todos los specs.
   - [`docs/features/INDEX.md`](docs/features/INDEX.md) — catálogo de features shipped.
   - [`database/migrations/INDEX.md`](database/migrations/INDEX.md) — navegación de migraciones.
5. **Specs inmutables una vez `shipped`.** Cambios futuros → spec nuevo que referencia al viejo.
6. **Convención de commits:** `[F###|C###|H###]: acción corta`. Ej: `C001: extraer CompanyScoped trait`.

---

## §7. Mensajería al usuario

- Toda retroalimentación al usuario se muestra vía el componente `<x-flash />` del layout.
- Tras una escritura, redirect con flash: `->with('success', '...')` o `->with('error', '...')`.
- Mensajes de éxito/error en español, terminados en punto.

---

## §8. Git

1. **Sin push forzado a main.**
2. **Commits pequeños y atómicos.** Un commit = un cambio lógico.
3. **Mismo commit:** cualquier cambio de estado en índices o docs viaja en el mismo commit que su causa.
4. **Convención:** `[F###|C###|H###]: acción corta` (ver §6.6).

---

## §9. Migraciones como historial inmutable

1. **Una migración ejecutada NUNCA se edita.** Corrección = nueva migración.
2. **Prohibido `migrate:fresh`** en producción o entornos compartidos.
3. **Nueva migración → fila añadida** en [`database/migrations/INDEX.md`](database/migrations/INDEX.md) en el mismo commit.
4. Si dos migraciones del mismo lote dependen entre sí (FK), el timestamp del archivo debe garantizar el orden.

---

## §10. Modificación de esta constitución

Cambiar cualquier sección de este archivo requiere:

1. Crear un **ADR** en [`docs/adr/`](docs/adr/) justificando el cambio.
2. Actualizar esta constitución en el mismo commit o PR.
3. Notificar al equipo (si aplica).

---

*Última actualización: 2026-06-14 — ADR-0007 aceptado, §3 reescrita a aislamiento per-usuario (pivote LinkVault AI vía C003).*
