# baddies · Backend (PHP + MySQL)

Capa de datos real que reemplaza al `localStorage` del demo. Cada `S.patch()`
del front pasa a ser un POST a estos endpoints. Pensado para **cPanel**
(PHP 8.1+, MySQL/MariaDB).

## Archivos

| Archivo | Qué hace |
|---|---|
| `schema.sql` | Crea todas las tablas (modelos, tarifas, horarios, media, dúos, usuarios, favoritas, sesiones, verificaciones, pagos). |
| `config.php` | Conexión PDO + helpers (JSON, sesión por token, slug, validación). **Edita el bloque CONFIG.** |
| `registro.php` | Alta de modelo (con resultado KYC) y de usuario. |
| `auth.php` | Login / logout / sesión actual. |
| `perfil.php` | Lee y actualiza el perfil (el equivalente real de `S.patch`). |
| `media.php` | Subida real de fotos/video a disco (no data URLs). |
| `directorio.php` | Listado público para el home, con filtros. |
| `favoritas.php` | Favoritas del usuario. |
| `amigas.php` | Dúos / invitaciones entre modelos. |
| `pago-flow.php` | **Plantilla** de Flow. No operar hasta tener aprobación de rubro. |
| `baddies-api.js` | Cliente JS: reemplazo drop-in de `baddies-estado.js`. |

## Instalación en cPanel

1. **Base de datos**: en *MySQL Databases* crea una base y un usuario, asígnalo con todos los permisos.
2. **Importar esquema**: en *phpMyAdmin* → pestaña *Importar* → sube `schema.sql`.
3. **Subir archivos**: copia la carpeta `backend/` a `public_html/backend/`.
4. **Credenciales**: edita `config.php` → bloque `CONFIG` (DB_NAME, DB_USER, DB_PASS).
5. **Carpeta de subidas**: crea `public_html/backend/uploads/` con permiso de escritura (755). Se crean subcarpetas por modelo automáticamente.
6. **SSL**: activa AutoSSL (el `.htaccess` ya fuerza HTTPS).

## Estado del cableado front ↔ backend

> **Interruptor único:** todas las pantallas leen `baddies-config.js` (en la raíz, junto a los HTML).
> Para salir en vivo, edita ese archivo y pon `USE_API: true`. Eso activa el backend en home,
> perfil, panel, registro y admin de una sola vez. En `false`, todo corre en modo demo.


- **`baddies-registro.html`**: flag `USE_API`. En `true` postea a `registro.php` (modelo y usuario).
- **`baddies-panel-modelo.html`**: flag `USE_API`. En `true`, cada `S.patch` (estado, comuna, tarifas, horarios, disponibilidad, privacidad, fase) **sincroniza con `perfil.php`**. Además tiene el botón **"Enviar a revisión"** (borrador→en_revisión) y "Reactivar" (pausada→activa).
- **`baddies-perfil.html`**: flag `USE_API`. En `true`, hidrata el perfil público real desde `perfil.php?slug=` (la URL define a quién mostrar: `baddies-perfil.html?u=<slug>`) — nombre, estado, tarifas, disponibilidad, sello y **fotos/cover reales**.
- **`baddies-admin.html`**: flag `USE_API` para el panel interno.
- **`baddies-home.html`**: flag `USE_API`. En `true`, hidrata el directorio real desde `directorio.php` (perfiles activos+públicos, con foto, categorías, rating, precio). Si el backend está vacío o no responde, mantiene el demo.
- **Subida de fotos del panel**: con `USE_API=true`, `upFotos`/`upCover`/`upVideo` suben los archivos de verdad a `media.php` (disco del servidor) y refrescan desde `perfil.php`. En `false` siguen usando data URLs locales (demo).

### Transiciones de fase (seguridad)

`perfil.php` solo permite a la modelo: `borrador→en_revision` (exige KYC verificado),
`activa→pausada/de_tour`, y `pausada/de_tour→activa`. **NO** puede auto-aprobarse
(`→activa` desde borrador/en_revision): eso es exclusivo del admin (`admin.php`).
Validado contra MySQL: intento de auto-aprobación devuelve 403, y enviar a revisión
sin KYC devuelve 409.

### Validado de punta a punta (MySQL real)

El circuito completo se probó contra MariaDB con el `schema.sql` real:
registro modelo → `en_revision` → el admin lo ve en la cola → **aprobar** → `activa`
→ aparece en `directorio.php` → la modelo hace `patch` de su perfil → el admin
asigna el Sello → queda en la auditoría. Regla anti-trata confirmada en el servidor:
**sin KYC verificado el perfil queda en `borrador` y la aprobación es rechazada (409).**

## Cómo migrar el front del demo al backend

En cada HTML, cambia el script de estado:

```html
<!-- demo (localStorage) -->
<script src="baddies-estado.js"></script>
<!-- producción (API real) -->
<script src="backend/baddies-api.js"></script>
```

Y donde el demo hacía llamadas **síncronas**, pásalas a **asíncronas**:

```js
// demo
S.patch({ online: true, onlineHasta: Date.now() + 3*3600*1000 });

// producción
await BaddiesAPI.online(Date.now() + 3*3600*1000);
```

Equivalencias rápidas:

| Demo (`baddies-estado.js`) | Producción (`baddies-api.js`) |
|---|---|
| `S.load()` | `await BaddiesAPI.miPerfil()` |
| `S.patch({...})` | `await BaddiesAPI.patchPerfil({...})` |
| subir fotos (FileReader) | `await BaddiesAPI.subirFotos(input.files, 'cover')` |
| `S.CHICAS` (catálogo) | `await BaddiesAPI.directorio({ciudad:'Santiago'})` |
| favoritas en localStorage | `await BaddiesAPI.toggleFav(id, true)` |
| registro (finishModel) | `await BaddiesAPI.registrarModelo({...})` |

## Seguridad y modelo de negocio (recordatorio)

- **KYC**: el documento de identidad **nunca** llega al servidor. El front lo
  sube directo al proveedor (Didit); aquí solo se guarda el **resultado**
  (`verificada`, `edad_ok`, `fecha`, `referencia`). Ver tabla `verificaciones`.
- **Pagos**: baddies cobra solo **publicidad** (plan de la modelo) y la
  **membresía Premium del sitio** (usuario). Nunca comisión por encuentros.
- **Flow**: requiere aprobación comercial del rubro antes de activar
  `pago-flow.php`. Escribir a soporte@flow.cl primero.
- Contraseñas con `password_hash()`. Sesión por token en cookie httponly.

## Pendiente (no incluido aún)

- Webhook de confirmación de pago de Flow (estructura comentada en `pago-flow.php`).
- Acción del admin para ocultar una reseña abusiva (la columna `aprobada` ya existe en `resenas`; falta el control en el panel admin).
- Rate limiting / captcha en registro y login.

## Reseñas (`resenas.php` + tabla `resenas`)

Reales y validadas: solo usuarios con sesión (clientes verificados) pueden escribir,
una reseña por usuario por modelo (se actualiza), 1–5 estrellas, anónimas hacia el
público. El `rating` del perfil se recalcula como promedio de las reseñas aprobadas
y se refleja en el directorio. El perfil las lee/escribe con `USE_API` (botón
"Escribir reseña" → formulario; sin sesión redirige a registro de usuario).


## Novedades de back-office y cliente

- **Reportes** (`reportes.php` + tabla `reportes`): el botón "Reportar" del perfil envía denuncias reales. El admin las ve en la sección **Reportes** y puede **suspender el perfil** (sale del directorio) o **descartar**.
- **Clientes** (admin, `vista=usuarios` + `usuario_bloquear`): lista de visitantes registrados con verificación/Premium; el admin puede **bloquear** (corta sus sesiones) o desbloquear. Campo `bloqueado` en `usuarios`.
- **Resumen enriquecido**: reportes abiertos, clientes, reseñas, nuevas (7d), además del desglose por fase.
- **Panel de cliente** (`baddies-cuenta.html` + `cuenta.php`): favoritas (con foto), reseñas escritas y datos de cuenta (verificación, Premium, incógnito, cerrar sesión) en una sola llamada.
