API en inglés: /animals, /species, campo profile (lectura y escritura) y GraphQL

- REST: rutas animals/species, campo «profile» con nombres y valores en inglés
  (available/pending/adopted, male/female…), escribible con validación; los datos
  comunes se copian a las traducciones y los textos no. Metadatos internos ocultos.
- GraphQL: animals / speciesList, tipos AnimalProfile y enums, filtros
  where { language, adoptionStatus }.
- Las peticiones a la API usan el idioma inglés (descripciones, errores).
- Esquema OpenAPI: componente AnimalProfile y cuerpos JSON documentados.
- La web y sus URLs siguen en castellano/euskera; los datos internos no cambian.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 09:15:05 +02:00
parent 1630428b46
commit c9011d4677
3 changed files with 372 additions and 101 deletions

View File

@@ -68,25 +68,51 @@ Cada ficha tiene su propio enlace y botones para compartirla por WhatsApp o Face
- En *Diseño → Cabecera* se elige cómo sale el logo arriba: símbolo + nombre, logo completo o solo el nombre.
## APIs
## APIs (in English)
| API | Dirección | Qué incluye |
The API is in English (routes, fields, values and messages), whatever the site language. The public website keeps its Spanish/Basque URLs (`/adopta/`, `/especie/perro/`).
| API | Endpoint | Notes |
|---|---|---|
| REST | `/wp-json/wp/v2/animales`, `/wp-json/wp/v2/especies` | Animales con el campo `ficha` (valores y textos legibles en su idioma). Se puede filtrar por idioma con `?lang=es` o `?lang=eu`. |
| GraphQL (WPGraphQL) | `/graphql` | Tipos `Animal` / `Especie` con el campo `ficha`. Explorador GraphiQL en el panel (menú GraphQL). |
| Swagger / OpenAPI 3 | `/rest-api/docs/` (interfaz) y `/rest-api/schema` (esquema) | Documentación interactiva de la API REST. Por defecto solo para usuarios conectados; `API_DOCS_PUBLIC=true` la hace pública. |
| REST | `/wp-json/wp/v2/animals`, `/wp-json/wp/v2/species` | Every animal has a `profile` object (read **and write**). Filter by language with `?lang=es` / `?lang=eu`. |
| GraphQL (WPGraphQL) | `/graphql` | `animals(where: { language: "eu", adoptionStatus: AVAILABLE })`, `speciesList`, type `AnimalProfile`. GraphiQL IDE in the dashboard. |
| OpenAPI 3 / Swagger | `/rest-api/docs/` (UI), `/rest-api/schema` (JSON) | Logged-in users only unless `API_DOCS_PUBLIC=true`. «Try it out» uses your WordPress session. |
Ejemplo de consulta GraphQL:
`profile` fields:
| Field | Type | Values / notes |
|---|---|---|
| `status` | string | `available`, `pending`, `adopted` (adopted animals are hidden from public listings) |
| `featured` | boolean | shown on the home page |
| `sex` | string | `male`, `female` |
| `birthDate`, `arrivalDate` | date `YYYY-MM-DD` | nullable |
| `age`, `ageUnit` | number, `years`/`months` | approximate age when the birth date is unknown |
| `size` | string | `small`, `medium`, `large` (dogs) |
| `galleryIds` | int[] | extra photos (attachment IDs); `photos` (read-only) = main photo + gallery URLs |
| `video` | URL | YouTube, Vimeo, Instagram or a media file |
| `personality`, `needs`, `compatibility`, `idealHome` | string | **per language** (each translation has its own) |
| `language`, `labels` | read-only | language of the translation and human-readable values in that language |
Shared fields (status, dates, size, photos…) are copied to every translation when written; texts are not.
```graphql
{
animales(first: 10) {
nodes { title uri especies { nodes { name } } ficha { estado edad edadUnidad compatible textos { estado edad } } }
animals(first: 10, where: { language: "es", adoptionStatus: AVAILABLE }) {
nodes { title uri language speciesList { nodes { name } } profile { status sex featured size personality labels { age } } }
}
}
```
Para escribir en la API REST (crear o editar animales) se usan las *contraseñas de aplicación* de WordPress (Usuarios → Perfil) con autenticación Basic sobre HTTPS; Swagger lo admite desde el botón «Authorize». Los mensajes del formulario no se exponen en ninguna API.
```bash
# Update an animal (application password: Users → Profile → Application passwords)
curl -u 'user:xxxx xxxx xxxx xxxx' -H 'Content-Type: application/json' \
-d '{"profile":{"status":"pending","featured":true}}' \
https://gureametsabilagun.pireon.dev/wp-json/wp/v2/animals/123
```
Contact-form messages are never exposed by any API.
> Note: the *WP API SwaggerUI* package on wordpress.org ships without its UI assets, so `/rest-api/docs/` is served by our own page (official Swagger UI, pinned version with SRI). The plugin is still used to generate the OpenAPI schema, which we post-process to document `profile`.
## Diseño