From 13e507fbb9eb7f146f89607d2f97e56cb164ec38 Mon Sep 17 00:00:00 2001 From: Renato Date: Wed, 5 Aug 2026 05:36:56 +0800 Subject: [PATCH] docs: documentar traduccion de titulos y moderacion en AGENTS.md --- AGENTS.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2043c09..9e71c6c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -199,8 +199,27 @@ SQLite vía `better-sqlite3`. Ruta: `process.env.DB_PATH` o `data/worst-scan.db` 1. Lista `api.galleries.list("completed", 1, 100)` + `api.galleries.translated()` del pipeline. 2. Por cada gid: `api.galleries.summary(gid)`. 3. `cleanTitle()` + `slugify(cleanT, gid)`; sintetiza summary (`synopsis` o `generateSummary()`). - 4. **Auto-publica todo:** no existe → `createPost({..., published: 1})`; existe → `updatePost`. - 5. `cacheCover(gid, "http://127.0.0.1:{PORT||3000}/api/proxy/galleries/{gid}/cover")`. + 4. **Moderación:** `moderateTags()` (ver §Moderación) — tags prohibidos → cuarentena (`published: 0`) + `notifyQuarantine()` a Discord de moderación. + 5. **Traducción de título:** `translateTitle()` → `title_es` (vía proxy free-ide local, deepseek-v4-flash-free con fallback big-pickle). Solo si no existe `title_es`. + 6. **Auto-publica:** no existe → `createPost({...})`; existe → `updatePost`. Si pasó a tener tags dudosos → `publishPost(id, false)` (cuarentena). + 7. `cacheCover(gid, "http://127.0.0.1:{PORT||3000}/api/proxy/galleries/{gid}/cover")`. + 8. Posts limpios nuevos → `notifyNewPost()` (Discord de novedades). + +## Traducción de títulos (`src/lib/translate.ts`) + +- Traduce títulos de manga al español latinoamericano usando el **proxy free-ide local** (`FREE_IDE_PROXY_URL`, default `127.0.0.1:6446/v1`, key `FREE_IDE_PROXY_KEY`). +- Modelos: `deepseek-v4-flash-free` (primario) → `big-pickle` (fallback). `max_tokens: 200` para que el razonamiento no consuma toda la respuesta. +- Heurística `isProbablySpanish()`: no traduce lo que ya parece español (evita re-traducir nombres propios). +- `displayTitle(post)` (`src/lib/title.ts`): devuelve `title_es || title` — usarlo en TODA la UI pública (cards, home hero, página de post, RSS). +- Migración masiva de existentes: `node scripts/translate_existing.js` (con `LIMIT=n` para probar un lote). + +## Moderación de contenido (`src/lib/moderation.ts`) + +- **Capa 1 — tags explícitos:** `lolicon`, `shotacon`, `loli`, `shota`, `child`, `children`, `kids`, `minor` (regex de palabra completa — `hololive` NO cae). +- **Capa 2 — contexto:** combinaciones de tags que sugieren menores sin tag explícito (`small breasts + crying + defloration`, etc.). +- Posts dudosos → cuarentena (`published=0`) + aviso a Discord de moderación (`DISCORD_MODERATION_WEBHOOK_URL`) con links ✅ Aprobar / 🗑️ Rechazar. +- Decisión: `GET /api/review/[id]?action=approve|reject&token=DISCORD_MOD_TOKEN` (protegido por token, no sesión). +- Auditoría manual: `node scripts/audit_lolicon.js`. > ⚠️ **BLOQUEANTE CONOCIDO:** el endpoint `/galleries` del pipeline solo lista las galleries del UrlQueue activo (~6), no las traducidas en `output/artifacts/` (~38 invisibles). El poller no puede descubrirlas. Solución: que `/galleries` escanee `output/artifacts/` o use `/galleries/translated`.