# Contexto / avance — SEO público Labento (P0+P1)

**Fecha:** 2026-08-06  
**Estado:** **P0+P1 implementados en código.** Sitemap estratégico documentado. Ops pendiente (GSC + dominio prod).  
**Plan maestro:** [`PLAN_SEO.md`](./PLAN_SEO.md)  
**Sitemap (marca + crawl):** [`SITEMAP_SEO.md`](./SITEMAP_SEO.md)  
**Complementa:** [`MANUAL_IDENTIDAD_PUBLICA.md`](./MANUAL_IDENTIDAD_PUBLICA.md), [`PLAN_LANDING_REGISTRO.md`](./PLAN_LANDING_REGISTRO.md)

---

## 1. Objetivo

Que un dueño de laboratorio que busca software en Google pueda:

1. **Encontrar** Labento (indexación limpia de `/` y `/registro`).
2. **Entender** el producto (caja + lab + resultados, SaaS).
3. **Confiar** lo suficiente para ir a registro (copy pricing honesto).

**Guardrail:** no indexar portal de resultados (`/r/*`, `/s/*`), login ni backoffice.

---

## 2. Posicionamiento (marca → SERP)

| Elemento | Valor canónico |
|----------|----------------|
| Marca | **Labento** (Branded House) |
| Categoría | Software / LIMS SaaS para laboratorios clínicos |
| Beneficio | Un solo sistema: **caja → laboratorio → entrega de resultados** |
| Pricing (voz obligatoria) | **$0 en fase de desarrollo** · precios del software **por determinarse** · sin tarjeta |
| KW primaria | `software para laboratorios clínicos` |
| H1 landing | Beneficio-first: *«Todo el laboratorio, unificado»* (no forzar KW en H1) |

**Title / description canónicos (código):**

| URL | Title | Description (resumen) |
|-----|-------|------------------------|
| `/` | Labento — Software para laboratorios clínicos | POS + captura + entrega; $0 desarrollo; sin tarjeta; precios TBD |
| `/registro` | Crear mi laboratorio — Labento | Registro en minutos; $0 desarrollo; sin tarjeta; precios TBD |
| `/login` | Acceso — Labento | **noindex, follow** (no es canal de adquisición) |

---

## 3. Qué se implementó (2026-08-04)

### P0 — Crawl e indexación

| Ítem | Detalle |
|------|---------|
| `GET /robots.txt` | `App\Controllers\Seo::robots` — `Allow: /` + Disallow app/portal + `Sitemap:` con `base_url()` |
| `GET /sitemap.xml` | `Seo::sitemap` — `/`, `/registro`, `/privacidad`, `/terminos` (+ `lastmod`) |
| Estático | **Eliminado** `public/robots.txt` (antes `Disallow: /` bloqueaba todo; el archivo estático pisa la ruta CI) |

### P1 — On-page, schema, higiene

| Ítem | Detalle |
|------|---------|
| JSON-LD | `app/Views/partials/jsonld_landing.php`: `SoftwareApplication`, `Organization`, `WebSite`, `FAQPage` (mismas FAQs del acordeón) |
| Include | Landing → sección `head` del layout público |
| Login | `meta robots noindex, follow` + favicon + `lang=es-MX` |
| Backoffice | `noindex, nofollow` en layouts admin / empleado / lab / super |
| Layout público | `lang="es-MX"`, favicon, `renderSection('head')` |
| Copy | `Home.php`, `Registro.php`, default de `opengraph.php` alineados al pricing del manual |
| Matomo | Ya incluido en layouts (sesión previa); no sustituye GSC |

### Tests

- `tests/unit/LandingRegistroTest.php` — contratos robots, sitemap, JSON-LD, noindex login, titles, `es-MX`/favicon.
- Verificado: `phpunit tests/unit/LandingRegistroTest.php` (17 tests OK).
- Live en contenedor: `/robots.txt`, `/sitemap.xml`, `/` (ld+json), `/login` (noindex).

---

## 4. Mapa de archivos

| Archivo | Rol |
|---------|-----|
| `app/Controllers/Seo.php` | robots + sitemap |
| `app/Config/Routes.php` | rutas `sitemap.xml`, `robots.txt` |
| `app/Views/partials/jsonld_landing.php` | schema.org |
| `app/Views/public/landing.php` | datos FAQs + section head |
| `app/Views/layouts/public.php` | head marketing |
| `app/Views/layouts/{admin,empleado,lab,super}.php` | noindex backoffice |
| `app/Views/auth/login.php` | noindex login |
| `app/Controllers/Home.php` / `Registro.php` | title/OG |
| `app/Views/partials/opengraph.php` | description default |
| `docs/PLAN_SEO.md` | plan + bitácora + gaps actualizados |
| `docs/CONTEXTO_SEO.md` | **este archivo** (handoff de sesión) |

---

## 5. Superficie indexable vs no

| Zona | Política |
|------|----------|
| `/`, `/registro` | index, follow (default) · en sitemap |
| `/privacidad`, `/terminos` | index, follow · en sitemap (EEAT) |
| `/login` | noindex, follow |
| `/r/*`, `/s/*` | noindex, nofollow (layout portal) + Disallow robots |
| Backoffice | auth + noindex, nofollow + Disallow robots |
| Blog / landings de función | **Later** — ver `SITEMAP_SEO.md` pilares; no abrir sin baseline GSC |

---

## 6. Pendiente (siguiente sesión)

### Ops (obligatorio para SEO real)

1. `app.baseURL` en **producción** = dominio canónico HTTPS.
2. Google Search Console: verificar propiedad + enviar `https://DOMINIO/sitemap.xml`.
3. Confirmar que el edge/host **no** sirve un `robots.txt` estático viejo que pise la app.

### P2 — Next (producto / EEAT)

- ~~Páginas `/privacidad` y `/terminos` + links en footer~~ **hecho**.
- Contacto/soporte real en footer (si aplica).
- Medir queries en GSC y afinar descriptions.
- Opcional: `/precios` solo con voz $0/TBD (sin tiers inventados).

### P3 / Later

- Contenido por intent (guías); no abrir blog sin baseline de impresiones.
- CWV profundo (fonts, LCP) después de indexación limpia.
- OG 1200×630 si se regenera cover; `sameAs` cuando existan redes.

### Explicit non-goals (siguen vigentes)

- Schema `Review` sobre escenarios por rol.
- SEO del backoffice como canal.
- Comprar backlinks / keyword stuffing en H1.

---

## 7. Cómo verificar en local

```bash
# Contenedor labsaas
docker exec labsaas curl -s http://127.0.0.1/robots.txt
docker exec labsaas curl -s http://127.0.0.1/sitemap.xml
docker exec labsaas curl -s http://127.0.0.1/ | grep -E 'ld\+json|SoftwareApplication|FAQPage'
docker exec labsaas curl -s http://127.0.0.1/login | grep noindex
docker exec labsaas vendor/bin/phpunit tests/unit/LandingRegistroTest.php
```

---

## 8. Notas para el agente que retome

1. Leer este archivo + `PLAN_SEO.md` antes de tocar SEO o marketing público.
2. **No reintroducir** `public/robots.txt` con `Disallow: /` — rompe todo el crawl.
3. Si se añade URL de marketing (p. ej. `/privacidad`), actualizar `Seo::sitemap` y el footer.
4. FAQs del schema = array `$faqs` en `landing.php`; no duplicar textos en otro lado sin sincronizar.
5. Pricing: una sola voz (`$0 en desarrollo` / `precios por determinarse`) en title, meta, schema, FAQ y footer.
6. Matomo está en partials; analytics de producto ≠ Search Console.

---

## 9. OG cover (rebrand visual)

| | |
|--|--|
| Archivo | `public/img/og-cover.jpg` |
| Tamaño | **1200×630** (ratio OG) |
| Marca en imagen | **Labento** (reemplazó labSoft / labSoft legacy) |
| Copy en cover | «Software para laboratorios clínicos» + chips POS · Kanban · Resultados |
| Meta | `partials/opengraph.php` → default `img/og-cover.jpg` |

Tras deploy: refrescar caché de Facebook Sharing Debugger / Twitter Card Validator si el preview sigue mostrando el cover viejo.

---

*Última actualización: 2026-08-06 — sitemap estratégico (`SITEMAP_SEO.md`) + `lastmod` en XML.*
