Conceptos, valor y escenarios típicos de clon — menos código.
Conceptos, valor y escenarios típicos de clon — menos código.
Preparing Ring content
Preparing Ring content
Preparing Ring content
Usa las pestañas Fundador / Desarrollador de la barra lateral de la documentación para filtrar esta página. Los fundadores ven el flujo de negocio y los ajustes del operador. Los desarrolladores ven los servicios, las rutas, las variables de entorno y una prueba local.
News Kingdom es la capa de promoción que se apoya en el módulo de noticias de Ring. Los miembros con el rol member o superior escriben artículos que viven en su espacio personal en /{username}/{slug}. Después, el autor puede pedir un lugar en el feed principal /news. Ring puntúa el artículo, pide al autor que pague un precio basado en esa puntuación y lo envía a los administradores de la plataforma en Telegram para que den el sí o el no definitivo.
Cada solicitud de promoción pasa por un único campo del artículo, mainPageStatus:
| Etapa | Qué ocurre | mainPageStatus |
|---|---|---|
| Envío | El autor pide aparecer en la página principal | submitted |
| Puntuación | La IA o una heurística puntúa ética, spam, duplicados y mérito | ai_scored |
| Bloqueo estricto | Ética demasiado baja, o riesgo de spam o de duplicado demasiado alto | published_blog_only |
| Pago | Se fija el precio y se abre un checkout de PaymentConductor | payment_pending |
| Pagado | El webhook confirma el pago y los administradores reciben una tarjeta en Telegram | awaiting_admin_approval |
| Aprobado | El artículo pasa al feed principal de todo el sitio | published_main |
| Rechazado | El administrador lo rechaza. El artículo se queda en el blog del autor | rejected |
Mismo flujo: dónde vive el artículo antes y después de solicitar la promoción.
Requisito previo: el módulo de noticias, el editor y el feed principal al que promociona News Kingdom.
Depende de: cómo se enrutan el checkout news_promotion y sus webhooks.
Ver también: el bot de administración que lleva los botones Approve, Reject y Counter.
Usa las pestañas Fundador / Desarrollador de la barra lateral de la documentación para filtrar esta página. Los fundadores ven el flujo de negocio y los ajustes del operador. Los desarrolladores ven los servicios, las rutas, las variables de entorno y una prueba local.
News Kingdom es la capa de promoción que se apoya en el módulo de noticias de Ring. Los miembros con el rol member o superior escriben artículos que viven en su espacio personal en /{username}/{slug}. Después, el autor puede pedir un lugar en el feed principal /news. Ring puntúa el artículo, pide al autor que pague un precio basado en esa puntuación y lo envía a los administradores de la plataforma en Telegram para que den el sí o el no definitivo.
Cada solicitud de promoción pasa por un único campo del artículo, mainPageStatus:
| Etapa | Qué ocurre | mainPageStatus |
|---|---|---|
| Envío | El autor pide aparecer en la página principal | submitted |
| Puntuación | La IA o una heurística puntúa ética, spam, duplicados y mérito | ai_scored |
| Bloqueo estricto | Ética demasiado baja, o riesgo de spam o de duplicado demasiado alto | published_blog_only |
| Pago | Se fija el precio y se abre un checkout de PaymentConductor | payment_pending |
| Pagado | El webhook confirma el pago y los administradores reciben una tarjeta en Telegram | awaiting_admin_approval |
| Aprobado | El artículo pasa al feed principal de todo el sitio | published_main |
| Rechazado | El administrador lo rechaza. El artículo se queda en el blog del autor | rejected |
Mismo flujo: dónde vive el artículo antes y después de solicitar la promoción.
Requisito previo: el módulo de noticias, el editor y el feed principal al que promociona News Kingdom.
Depende de: cómo se enrutan el checkout news_promotion y sus webhooks.
Ver también: el bot de administración que lleva los botones Approve, Reject y Counter.
Usa las pestañas Fundador / Desarrollador de la barra lateral de la documentación para filtrar esta página. Los fundadores ven el flujo de negocio y los ajustes del operador. Los desarrolladores ven los servicios, las rutas, las variables de entorno y una prueba local.
News Kingdom es la capa de promoción que se apoya en el módulo de noticias de Ring. Los miembros con el rol member o superior escriben artículos que viven en su espacio personal en /{username}/{slug}. Después, el autor puede pedir un lugar en el feed principal /news. Ring puntúa el artículo, pide al autor que pague un precio basado en esa puntuación y lo envía a los administradores de la plataforma en Telegram para que den el sí o el no definitivo.
Cada solicitud de promoción pasa por un único campo del artículo, mainPageStatus:
| Etapa | Qué ocurre | mainPageStatus |
|---|---|---|
| Envío | El autor pide aparecer en la página principal | submitted |
| Puntuación | La IA o una heurística puntúa ética, spam, duplicados y mérito | ai_scored |
| Bloqueo estricto | Ética demasiado baja, o riesgo de spam o de duplicado demasiado alto | published_blog_only |
| Pago | Se fija el precio y se abre un checkout de PaymentConductor | payment_pending |
| Pagado | El webhook confirma el pago y los administradores reciben una tarjeta en Telegram | awaiting_admin_approval |
| Aprobado | El artículo pasa al feed principal de todo el sitio | published_main |
| Rechazado | El administrador lo rechaza. El artículo se queda en el blog del autor | rejected |
Mismo flujo: dónde vive el artículo antes y después de solicitar la promoción.
Requisito previo: el módulo de noticias, el editor y el feed principal al que promociona News Kingdom.
Depende de: cómo se enrutan el checkout news_promotion y sus webhooks.
Ver también: el bot de administración que lleva los botones Approve, Reject y Counter.
El checkout que cobra la tarifa de promoción con el procesador que hayas configurado.
Los precios se fijan en UAH con variables de entorno del servidor. Si no las defines, se aplican estos valores por defecto:
| Ajuste | Por defecto | Efecto |
|---|---|---|
| Precio base | 50 UAH | Precio mínimo para un artículo de mérito alto |
| Escala | 2000 UAH | Cuánto sube el precio a medida que baja el mérito |
| Máximo | 5000 UAH | Tope de precio |
| Umbral de mérito bajo | mérito inferior a 0.25 | El precio sube al menos a 4999 UAH |
| Contraoferta del administrador | +25% | El botón Counter de Telegram fija un nuevo importe que el autor debe pagar |
lib/telegram/admin-bot/news-callback-handler.tsapp/api/telegram/admin-bot/webhook/route.ts| Interfaz de promoción para miembros | features/news/components/news-promotion-panel.tsx en /my-news |
| Tipos de estado y de campos | features/news/types/index.ts (MainPageStatus, NewsContentType, NewsVisibility) |
| Mapeador de filas JSONB | lib/news/map-news-document.ts |
| Marca y URL absolutas | lib/site-branding.ts (localeBlogArticleUrl, absoluteSiteUrl) |
| Método y ruta | Autenticación | Función |
|---|---|---|
POST /api/news/promotion/submit | Sesión, solo el autor del artículo | Marca promoteToMainPage, puntúa y abre el checkout |
PATCH /api/news/promotion/submit | Cabecera x-news-promotion-secret | Dev o pruebas: marcar como pagado y avisar a los administradores |
POST /api/payments/{wayforpay,stripe,paypal}/webhook | Firma del procesador | Confirmación canónica del pago |
POST /api/news/promotion/wayforpay-webhook | Payload del procesador | Delegado obsoleto hacia el webhook canónico de WayForPay |
POST /api/mcp/v1/news/[id]/{score,approve,reject,publish} | Token de servicio (withMcpGuard) | Operaciones de agentes y MCP sobre el mismo flujo |
scoreNewsForMainPage() llama a OpenRouter cuando OPENROUTER_API_KEY está definida. Sin clave, mantiene los valores heurísticos por defecto (ethics 0.7, spam 0.2, merit 0.5) y registra model: 'heuristic'.
slug o siteWideSlug. 0.9 si un artículo publicado (entre los primeros 200) tiene el mismo título.ethics < NEWS_ETHICS_MIN o spamRisk > NEWS_SPAM_MAX o duplicateRisk > NEWS_DUPLICATE_MAX. Resultado: published_blog_only y sin checkout.clamp(base, max, base + (1 - merit) * scale). Un mérito inferior a NEWS_MERIT_SOFT_REJECT sube el precio al menos a 4999. El mérito bajo no cambia el estado.Ninguna de las claves NEWS_* está en env.local.template. El código las lee con estos valores por defecto.
| Variable | Por defecto | Se lee en |
|---|---|---|
NEWS_PROMO_BASE_UAH / NEWS_PROMO_SCALE_UAH / NEWS_PROMO_MAX_UAH | 50 / 2000 / 5000 | news-scoring-service.ts |
NEWS_ETHICS_MIN / NEWS_SPAM_MAX / NEWS_DUPLICATE_MAX | 0.35 / 0.85 / 0.9 | news-scoring-service.ts |
NEWS_MERIT_SOFT_REJECT | 0.25 | puntuación y flujo de promoción |
OPENROUTER_API_KEY, OPENROUTER_MODEL_PRIMARY, OPENROUTER_MODEL_FALLBACK | sin definir | news-scoring-service.ts |
PAYMENT_NEWS_PROCESSOR | recurre a PAYMENT_DEFAULT_PROCESSOR y luego a wayforpay | lib/payments/payment.config.ts |
NEWS_PROMOTION_WEBHOOK_SECRET | sin definir | PATCH /api/news/promotion/submit |
ADMIN_BOT_TOKEN | sin definir | Respuestas a callbacks de Telegram |
Las cuatro tablas usan el modelo de documentos JSONB (id, data jsonb, marcas de tiempo) en data/schema.sql (aplanado v4.1.0): news, news_categories, news_likes, news_submission_audit. Cada transición añade una entrada a data.mainPageStatusHistory y escribe una fila en news_submission_audit. data/migrations/002_news_content_schema.sql y 003_news_kingdom_upgrade.sql son históricos. Las instalaciones nuevas solo aplican schema.sql.
approveMainPagePublication() fija status: 'published' y visibility: 'site-wide'. En las historias escritas por usuarios, después pone en cola enqueueRewardCreditAddEvent({ trigger: 'newsStoryApproved' }) y lanza generateArticleTranslations(). Los destinatarios en Telegram son usuarios con un rol de administrador de la plataforma y un communication.telegramId.
Aplica el esquema y crea un artículo de miembro
Aplica data/schema.sql e inicia sesión como un usuario con rol member o superior. Crea un artículo en /news/create. Queda marcado con blogUsername y aparece en /{username}/{slug} una vez publicado.
Envíalo a promoción
La respuesta incluye status, aiScore y una redirección o los campos de pago para el checkout.
Simula el pago en dev
Aprueba
Pulsa Approve en la tarjeta de Telegram o llama a POST /api/mcp/v1/news/<id>/approve con un token de servicio. Comprueba que mainPageStatus es published_main y que existe una fila en news_submission_audit.
El checkout que cobra la tarifa de promoción con el procesador que hayas configurado.
Los precios se fijan en UAH con variables de entorno del servidor. Si no las defines, se aplican estos valores por defecto:
| Ajuste | Por defecto | Efecto |
|---|---|---|
| Precio base | 50 UAH | Precio mínimo para un artículo de mérito alto |
| Escala | 2000 UAH | Cuánto sube el precio a medida que baja el mérito |
| Máximo | 5000 UAH | Tope de precio |
| Umbral de mérito bajo | mérito inferior a 0.25 | El precio sube al menos a 4999 UAH |
| Contraoferta del administrador | +25% | El botón Counter de Telegram fija un nuevo importe que el autor debe pagar |
lib/telegram/admin-bot/news-callback-handler.tsapp/api/telegram/admin-bot/webhook/route.ts| Interfaz de promoción para miembros | features/news/components/news-promotion-panel.tsx en /my-news |
| Tipos de estado y de campos | features/news/types/index.ts (MainPageStatus, NewsContentType, NewsVisibility) |
| Mapeador de filas JSONB | lib/news/map-news-document.ts |
| Marca y URL absolutas | lib/site-branding.ts (localeBlogArticleUrl, absoluteSiteUrl) |
| Método y ruta | Autenticación | Función |
|---|---|---|
POST /api/news/promotion/submit | Sesión, solo el autor del artículo | Marca promoteToMainPage, puntúa y abre el checkout |
PATCH /api/news/promotion/submit | Cabecera x-news-promotion-secret | Dev o pruebas: marcar como pagado y avisar a los administradores |
POST /api/payments/{wayforpay,stripe,paypal}/webhook | Firma del procesador | Confirmación canónica del pago |
POST /api/news/promotion/wayforpay-webhook | Payload del procesador | Delegado obsoleto hacia el webhook canónico de WayForPay |
POST /api/mcp/v1/news/[id]/{score,approve,reject,publish} | Token de servicio (withMcpGuard) | Operaciones de agentes y MCP sobre el mismo flujo |
scoreNewsForMainPage() llama a OpenRouter cuando OPENROUTER_API_KEY está definida. Sin clave, mantiene los valores heurísticos por defecto (ethics 0.7, spam 0.2, merit 0.5) y registra model: 'heuristic'.
slug o siteWideSlug. 0.9 si un artículo publicado (entre los primeros 200) tiene el mismo título.ethics < NEWS_ETHICS_MIN o spamRisk > NEWS_SPAM_MAX o duplicateRisk > NEWS_DUPLICATE_MAX. Resultado: published_blog_only y sin checkout.clamp(base, max, base + (1 - merit) * scale). Un mérito inferior a NEWS_MERIT_SOFT_REJECT sube el precio al menos a 4999. El mérito bajo no cambia el estado.Ninguna de las claves NEWS_* está en env.local.template. El código las lee con estos valores por defecto.
| Variable | Por defecto | Se lee en |
|---|---|---|
NEWS_PROMO_BASE_UAH / NEWS_PROMO_SCALE_UAH / NEWS_PROMO_MAX_UAH | 50 / 2000 / 5000 | news-scoring-service.ts |
NEWS_ETHICS_MIN / NEWS_SPAM_MAX / NEWS_DUPLICATE_MAX | 0.35 / 0.85 / 0.9 | news-scoring-service.ts |
NEWS_MERIT_SOFT_REJECT | 0.25 | puntuación y flujo de promoción |
OPENROUTER_API_KEY, OPENROUTER_MODEL_PRIMARY, OPENROUTER_MODEL_FALLBACK | sin definir | news-scoring-service.ts |
PAYMENT_NEWS_PROCESSOR | recurre a PAYMENT_DEFAULT_PROCESSOR y luego a wayforpay | lib/payments/payment.config.ts |
NEWS_PROMOTION_WEBHOOK_SECRET | sin definir | PATCH /api/news/promotion/submit |
ADMIN_BOT_TOKEN | sin definir | Respuestas a callbacks de Telegram |
Las cuatro tablas usan el modelo de documentos JSONB (id, data jsonb, marcas de tiempo) en data/schema.sql (aplanado v4.1.0): news, news_categories, news_likes, news_submission_audit. Cada transición añade una entrada a data.mainPageStatusHistory y escribe una fila en news_submission_audit. data/migrations/002_news_content_schema.sql y 003_news_kingdom_upgrade.sql son históricos. Las instalaciones nuevas solo aplican schema.sql.
approveMainPagePublication() fija status: 'published' y visibility: 'site-wide'. En las historias escritas por usuarios, después pone en cola enqueueRewardCreditAddEvent({ trigger: 'newsStoryApproved' }) y lanza generateArticleTranslations(). Los destinatarios en Telegram son usuarios con un rol de administrador de la plataforma y un communication.telegramId.
Aplica el esquema y crea un artículo de miembro
Aplica data/schema.sql e inicia sesión como un usuario con rol member o superior. Crea un artículo en /news/create. Queda marcado con blogUsername y aparece en /{username}/{slug} una vez publicado.
Envíalo a promoción
La respuesta incluye status, aiScore y una redirección o los campos de pago para el checkout.
Simula el pago en dev
Aprueba
Pulsa Approve en la tarjeta de Telegram o llama a POST /api/mcp/v1/news/<id>/approve con un token de servicio. Comprueba que mainPageStatus es published_main y que existe una fila en news_submission_audit.
El checkout que cobra la tarifa de promoción con el procesador que hayas configurado.
Los precios se fijan en UAH con variables de entorno del servidor. Si no las defines, se aplican estos valores por defecto:
| Ajuste | Por defecto | Efecto |
|---|---|---|
| Precio base | 50 UAH | Precio mínimo para un artículo de mérito alto |
| Escala | 2000 UAH | Cuánto sube el precio a medida que baja el mérito |
| Máximo | 5000 UAH | Tope de precio |
| Umbral de mérito bajo | mérito inferior a 0.25 | El precio sube al menos a 4999 UAH |
| Contraoferta del administrador | +25% | El botón Counter de Telegram fija un nuevo importe que el autor debe pagar |
lib/telegram/admin-bot/news-callback-handler.tsapp/api/telegram/admin-bot/webhook/route.ts| Interfaz de promoción para miembros | features/news/components/news-promotion-panel.tsx en /my-news |
| Tipos de estado y de campos | features/news/types/index.ts (MainPageStatus, NewsContentType, NewsVisibility) |
| Mapeador de filas JSONB | lib/news/map-news-document.ts |
| Marca y URL absolutas | lib/site-branding.ts (localeBlogArticleUrl, absoluteSiteUrl) |
| Método y ruta | Autenticación | Función |
|---|---|---|
POST /api/news/promotion/submit | Sesión, solo el autor del artículo | Marca promoteToMainPage, puntúa y abre el checkout |
PATCH /api/news/promotion/submit | Cabecera x-news-promotion-secret | Dev o pruebas: marcar como pagado y avisar a los administradores |
POST /api/payments/{wayforpay,stripe,paypal}/webhook | Firma del procesador | Confirmación canónica del pago |
POST /api/news/promotion/wayforpay-webhook | Payload del procesador | Delegado obsoleto hacia el webhook canónico de WayForPay |
POST /api/mcp/v1/news/[id]/{score,approve,reject,publish} | Token de servicio (withMcpGuard) | Operaciones de agentes y MCP sobre el mismo flujo |
scoreNewsForMainPage() llama a OpenRouter cuando OPENROUTER_API_KEY está definida. Sin clave, mantiene los valores heurísticos por defecto (ethics 0.7, spam 0.2, merit 0.5) y registra model: 'heuristic'.
slug o siteWideSlug. 0.9 si un artículo publicado (entre los primeros 200) tiene el mismo título.ethics < NEWS_ETHICS_MIN o spamRisk > NEWS_SPAM_MAX o duplicateRisk > NEWS_DUPLICATE_MAX. Resultado: published_blog_only y sin checkout.clamp(base, max, base + (1 - merit) * scale). Un mérito inferior a NEWS_MERIT_SOFT_REJECT sube el precio al menos a 4999. El mérito bajo no cambia el estado.Ninguna de las claves NEWS_* está en env.local.template. El código las lee con estos valores por defecto.
| Variable | Por defecto | Se lee en |
|---|---|---|
NEWS_PROMO_BASE_UAH / NEWS_PROMO_SCALE_UAH / NEWS_PROMO_MAX_UAH | 50 / 2000 / 5000 | news-scoring-service.ts |
NEWS_ETHICS_MIN / NEWS_SPAM_MAX / NEWS_DUPLICATE_MAX | 0.35 / 0.85 / 0.9 | news-scoring-service.ts |
NEWS_MERIT_SOFT_REJECT | 0.25 | puntuación y flujo de promoción |
OPENROUTER_API_KEY, OPENROUTER_MODEL_PRIMARY, OPENROUTER_MODEL_FALLBACK | sin definir | news-scoring-service.ts |
PAYMENT_NEWS_PROCESSOR | recurre a PAYMENT_DEFAULT_PROCESSOR y luego a wayforpay | lib/payments/payment.config.ts |
NEWS_PROMOTION_WEBHOOK_SECRET | sin definir | PATCH /api/news/promotion/submit |
ADMIN_BOT_TOKEN | sin definir | Respuestas a callbacks de Telegram |
Las cuatro tablas usan el modelo de documentos JSONB (id, data jsonb, marcas de tiempo) en data/schema.sql (aplanado v4.1.0): news, news_categories, news_likes, news_submission_audit. Cada transición añade una entrada a data.mainPageStatusHistory y escribe una fila en news_submission_audit. data/migrations/002_news_content_schema.sql y 003_news_kingdom_upgrade.sql son históricos. Las instalaciones nuevas solo aplican schema.sql.
approveMainPagePublication() fija status: 'published' y visibility: 'site-wide'. En las historias escritas por usuarios, después pone en cola enqueueRewardCreditAddEvent({ trigger: 'newsStoryApproved' }) y lanza generateArticleTranslations(). Los destinatarios en Telegram son usuarios con un rol de administrador de la plataforma y un communication.telegramId.
Aplica el esquema y crea un artículo de miembro
Aplica data/schema.sql e inicia sesión como un usuario con rol member o superior. Crea un artículo en /news/create. Queda marcado con blogUsername y aparece en /{username}/{slug} una vez publicado.
Envíalo a promoción
La respuesta incluye status, aiScore y una redirección o los campos de pago para el checkout.
Simula el pago en dev
Aprueba
Pulsa Approve en la tarjeta de Telegram o llama a POST /api/mcp/v1/news/<id>/approve con un token de servicio. Comprueba que mainPageStatus es published_main y que existe una fila en news_submission_audit.