# Handoff para frontend: autenticacion, farmacia y registro

Este documento esta pensado para un agente o equipo frontend que va a implementar la integracion completa con las APIs actuales del backend.

La referencia tecnica detallada sigue siendo `docs/frontend/authentication-api.md`. Este archivo resume que pantalla consume cada endpoint, que datos guardar, que errores manejar y que cosas no deben hacerse.

## Resumen rapido

- La SPA usa Laravel Sanctum con sesion y cookies.
- No existen Bearer tokens ni Personal Access Tokens.
- Axios o el cliente HTTP debe usar `withCredentials: true`.
- Antes de `login`, `register` o `logout`, solicitar `GET /sanctum/csrf-cookie`.
- Para saber si hay sesion activa, consultar `GET /api/v1/auth/me`.
- La farmacia se busca por codigo, pero para registrar se envia su UUID publico como `pharmacy_id`.

## Configuracion base del cliente HTTP

```ts
import axios from 'axios';

export const api = axios.create({
  baseURL: import.meta.env.VITE_API_URL,
  withCredentials: true,
  withXSRFToken: true,
  headers: {
    Accept: 'application/json',
  },
});
```

Suposiciones para entorno frontend:

- `VITE_API_URL` debe apuntar al backend Laravel.
- Backend y frontend deben estar configurados para trabajar con cookies stateful de Sanctum.
- La cookie de sesion es `HttpOnly`; no debe intentarse leerla desde JavaScript.

## Pantallas y flujo esperado

### 1. Pantalla de registro

Objetivo:

- Permitir que el usuario busque su farmacia.
- Conservar el UUID publico de la farmacia encontrada.
- Enviar la solicitud de registro pendiente.

Flujo:

1. El usuario escribe el codigo de farmacia.
2. Frontend llama `GET /api/v1/public/pharmacies/by-code/{code}`.
3. Si responde `200`, guardar `response.data.data.id` como `pharmacy_id`.
4. Mostrar al usuario `code`, `name` y `city` de la farmacia encontrada.
5. Cuando el usuario envie el formulario, llamar `GET /sanctum/csrf-cookie`.
6. Enviar `POST /api/v1/auth/register` con el `pharmacy_id` guardado.
7. Si responde `201`, mostrar el mensaje de exito y no iniciar sesion.

Notas importantes:

- No enviar `pharmacy_code` al endpoint de registro.
- No enviar el nombre de la farmacia.
- No enviar IDs numericos internos.
- El backend puede devolver `404 PHARMACY_NOT_FOUND` si la farmacia no existe o esta inactiva.

### 2. Pantalla de login

Objetivo:

- Iniciar sesion con username o email usando cookies de sesion.

Flujo:

1. El usuario completa `login` y `password`.
2. Frontend llama `GET /sanctum/csrf-cookie`.
3. Frontend envia `POST /api/v1/auth/login`.
4. Si responde `200`, llamar `GET /api/v1/auth/me`.
5. Guardar en estado global el usuario autenticado desde `response.data.data.user`.

Notas importantes:

- `login` acepta username o email.
- No esperar tokens en la respuesta.
- No guardar tokens en localStorage o sessionStorage.
- Si falla, el backend siempre responde `401 INVALID_CREDENTIALS` con mensaje generico.

### 3. Carga inicial de la app

Objetivo:

- Saber si el navegador ya tiene una sesion valida.

Flujo:

1. Al montar la app o al refrescar navegador, llamar `GET /api/v1/auth/me`.
2. Si responde `200`, guardar `response.data.data.user`.
3. Si responde `401`, tratar al usuario como invitado o no autenticado.

### 4. Logout

Objetivo:

- Cerrar la sesion del navegador actual.

Flujo:

1. Llamar `GET /sanctum/csrf-cookie` si el flujo del cliente lo requiere antes del `POST`.
2. Enviar `POST /api/v1/auth/logout`.
3. Limpiar el estado local del usuario.
4. Redirigir a login o a la vista publica definida por la SPA.

## Endpoints que debe usar frontend

### Buscar farmacia

`GET /api/v1/public/pharmacies/by-code/{code}`

Uso:

- Se usa en la pantalla de registro, antes de enviar el formulario.

Respuesta exitosa:

```json
{
  "success": true,
  "message": "Farmacia encontrada correctamente.",
  "data": {
    "id": "8d20d56e-83ce-48c7-a713-b26aee541a42",
    "code": "FAR001",
    "name": "Farmacia Ejemplo",
    "city": "Santiago"
  }
}
```

Que guardar:

- `data.id` como `pharmacy_id`

Que mostrar:

- `data.code`
- `data.name`
- `data.city`

Errores importantes:

- `404 PHARMACY_NOT_FOUND`
- `429 TOO_MANY_REQUESTS`

### Crear solicitud de registro

`POST /api/v1/auth/register`

Uso:

- Se usa en la pantalla de registro.

Payload esperado:

```json
{
  "pharmacy_id": "8d20d56e-83ce-48c7-a713-b26aee541a42",
  "first_name": "Albert",
  "last_name": "Mata",
  "whatsapp": "(809) 555-1234",
  "whatsapp_confirmation": "8095551234",
  "phone": "809-555-9876",
  "identification_number": "001-1234567-8",
  "username": "Albert01",
  "password": "Password123!",
  "password_confirmation": "Password123!",
  "email": "USER@example.com",
  "city": "Santo Domingo",
  "nickname": "Beto",
  "terms_accepted": true
}
```

Respuesta exitosa:

```json
{
  "success": true,
  "message": "Tu solicitud de registro fue recibida y esta pendiente de revision.",
  "data": []
}
```

Comportamiento esperado:

- No se crea sesion.
- No se crea usuario autenticado.
- No se devuelve token.
- Solo se crea una solicitud pendiente de revision.

Errores importantes:

- `422 VALIDATION_ERROR`
- `422 REGISTRATION_DATA_ALREADY_EXISTS`
- `404 PHARMACY_NOT_FOUND`
- `429 TOO_MANY_REQUESTS`

Campos que frontend no debe enviar:

- `pharmacy_code`
- `status`
- `approved_at`
- `rejected_at`
- `reviewed_by`
- `request_ip`
- `request_user_agent`
- `role`
- `role_id`
- `roles`
- `permissions`

### Login

`POST /api/v1/auth/login`

Uso:

- Se usa en la pantalla de login.

Payload esperado:

```json
{
  "login": "albertmat34",
  "password": "Password123!",
  "remember": false
}
```

Respuesta exitosa:

```json
{
  "success": true,
  "message": "Usuario autenticado.",
  "data": {
    "user": {
      "id": "uuid-del-usuario",
      "first_name": "Albert",
      "last_name": "Martinez",
      "username": "albertmat34",
      "email": "albert@example.com",
      "status": "active",
      "roles": ["dependent"],
      "pharmacy": {
        "id": "uuid-publico-de-farmacia",
        "code": "FAR001",
        "name": "Farmacia Ejemplo"
      }
    }
  }
}
```

Errores importantes:

- `401 INVALID_CREDENTIALS`
- `429 TOO_MANY_REQUESTS`

### Usuario autenticado actual

`GET /api/v1/auth/me`

Uso:

- Se usa al cargar la app.
- Se usa despues de login.
- Se puede usar para refrescar el usuario autenticado.

Respuesta exitosa:

```json
{
  "success": true,
  "message": "Usuario autenticado.",
  "data": {
    "user": {
      "id": "uuid-del-usuario",
      "first_name": "Albert",
      "last_name": "Martinez",
      "username": "albertmat34",
      "email": "albert@example.com",
      "status": "active",
      "roles": ["dependent"],
      "pharmacy": {
        "id": "uuid-publico-de-farmacia",
        "code": "FAR001",
        "name": "Farmacia Ejemplo"
      }
    }
  }
}
```

Errores importantes:

- `401 UNAUTHENTICATED`

### Logout

`POST /api/v1/auth/logout`

Uso:

- Se usa para cerrar sesion.

Respuesta exitosa:

```json
{
  "success": true,
  "message": "Sesion cerrada correctamente.",
  "data": []
}
```

Errores importantes:

- `401 UNAUTHENTICATED`

## Estructura general de respuestas

Exito:

```json
{
  "success": true,
  "message": "Mensaje",
  "data": {}
}
```

Error:

```json
{
  "success": false,
  "message": "Mensaje de error",
  "errors": {
    "field_name": [
      "Detalle del error"
    ]
  },
  "error_code": "ERROR_CODE"
}
```

Regla de frontend:

- Mostrar `message` como mensaje general.
- Si `error_code` es `VALIDATION_ERROR` o `REGISTRATION_DATA_ALREADY_EXISTS`, pintar errores por campo usando `errors`.
- Si `error_code` es `UNAUTHENTICATED`, limpiar sesion local.
- Si `error_code` es `INVALID_CREDENTIALS`, mostrar mensaje generico de credenciales.

## Datos que frontend debe asumir como publicos

Usuario autenticado:

- `id` es UUID publico del usuario
- `roles` es una lista de nombres de roles
- `pharmacy.id` es UUID publico de la farmacia

Farmacia:

- `id` es UUID publico
- Nunca se expone el ID numerico interno

## Datos que frontend no debe asumir ni reconstruir

- No inferir permisos reales solo desde `roles`
- No intentar autenticar con Bearer token
- No esperar `token`, `access_token` ni `personal_access_token`
- No usar IDs internos
- No enviar campos internos o administrativos

## Checklist de implementacion para el agente frontend

- Crear un cliente HTTP compartido con credenciales habilitadas
- Implementar bootstrap de sesion con `GET /api/v1/auth/me`
- Implementar busqueda de farmacia por codigo
- Guardar `pharmacy_id` usando el UUID devuelto por la busqueda
- Implementar formulario de registro con validaciones alineadas al backend
- Implementar login con flujo Sanctum stateful
- Implementar persistencia de usuario autenticado en el estado global
- Implementar logout limpiando estado local
- Manejar `401`, `404`, `422` y `429` de forma consistente
- No implementar almacenamiento de tokens

## Documento fuente

Para detalles de contrato y ejemplos adicionales, usar como fuente tecnica:

- `docs/frontend/authentication-api.md`
