Guía de pruebas

Última actualización

16 de julio de 2026

Esta guía cubre los conjuntos de pruebas automatizadas, la infraestructura de pruebas local y las rutas de verificación manual. La recuperación sintética semanal, los simulacros de vista previa protegida y la verificación posterior a la restauración están documentados en BACKUP_RESTORE.md.

Referencia rápida

npm run test:unit          # Unit tests (Vitest) — ~700ms
npm run test:unit:watch    # Watch mode
npm run test:unit:coverage # With coverage report
npm run test:i18n          # Supported locale catalog completeness check
npm run test:seo           # Generated-site SEO/crawl audit; build _site first
npm run test:crawl-endpoints -- --base=https://site.example.com  # Live sitemap/robots/URL fetch audit
npm run test:performance:budgets  # Generated JS/CSS release ceilings
npm run test:performance:lighthouse # Core-route Lighthouse evidence in Podman
npm run test:performance:runtime # Authenticated/redacted Worker p95 evidence; requires input or token
npm run test:cache-policy  # Deployed public/private cache-header evidence
npm run test:secrets       # Secret exposure audit for local env files
npm run test:premerge      # Merge-readiness checks for changed Worker logic
npm run release:smoke -- --evidence-file /tmp/pool-release-smoke.md  # Release sign-off wrapper
npm run release:a11y-evidence   # Focused campaign/cart accessibility evidence
npm run release:i18n-seo-evidence  # Rendered i18n/SEO evidence over built _site
npm run release:pledge-evidence # Worker-backed pledge/report evidence
npm run release:providers -- --no-dev-vars  # Read-only external provider readiness
npm run release:payment-smoke -- --no-dev-vars  # Payment contract and no-send smoke evidence
npm run test:e2e           # E2E tests (Playwright) — fully automated browser coverage
npm run test:e2e:headless  # CI mode
npm run test:e2e:headless:podman  # Automated browser suite with Playwright in Podman
npm run test:e2e:parity    # First-party critical-path browser flows
npx playwright test tests/e2e/admin-dashboard.spec.ts --project=chromium  # Focused admin dashboard browser suite
npm run test:e2e:headless:podman -- tests/e2e/admin-dashboard.spec.ts --project=chromium  # Podman-backed admin create/preview/browser suite
npm run podman:doctor      # Cross-platform Podman readiness check
npm run test:security      # Security pen tests (Worker must be running)
npm run test:security:podman  # Security pen tests with a one-shot Podman-backed stack
npm run test:security:staging  # Security tests against a staging worker, if you maintain one
npm run media:optimize:check   # Check dashboard-uploaded media for pending optimization/responsive variants/derivatives
npm run media:optimize:check:podman  # Same media check inside the Podman toolchain
./scripts/test-checkout.sh --podman  # Manual checkout helper against the Podman stack
./scripts/test-e2e.sh --podman       # Automated browser helper against the Podman stack
npm run test:usps          # Live USPS credential + quote sanity check
npm test                   # Run all tests

./scripts/test-e2e.sh --podman es ahora la ruta del navegador totalmente automatizada. Utilice ./scripts/test-checkout.sh --podman cuando desee específicamente realizar el pago manualmente en un navegador real.

La ruta de prueba del trabajador local ahora prefiere el nodo 24, que coincide con las acciones de GitHub. Los scripts del host recurren al Nodo 22 si una bifurcación lo tiene instalado, pero ya no fuerzan el Nodo 20 porque Wrangler 4 requiere el Nodo 22 o posterior.

Para la sección del navegador centrada en la accesibilidad, utilice:

./scripts/podman-playwright-run.sh npx playwright test \
  tests/e2e/accessibility-public-pages.spec.ts \
  tests/e2e/manage-flows.spec.ts \
  tests/e2e/community-flows.spec.ts \
  tests/e2e/public-page-controls.spec.ts \
  tests/e2e/campaign-checkout.spec.ts \
  --project=chromium \
  --grep "Public Page Accessibility|keyboard-only|Community Flows|Public Page Keyboard Controls"

Si desea solo el barrido de regresión de accesibilidad pública y no desea depender del host Ruby/Bundler, prefiera la ruta respaldada por Podman:

npm run test:e2e:headless:podman -- tests/e2e/accessibility-public-pages.spec.ts --project=chromium

Liberar evidencia

Utilice el envoltorio de lanzamiento antes de la aprobación de producción:

npm run release:smoke -- --evidence-file /tmp/pool-release-smoke.md

El contenedor ejecuta la puerta de fusión, el ensayo de preparación para la producción de configuración/implementación, E2E sin cabeza de Podman cuando Podman está disponible, evidencia de accesibilidad enfocada, evidencia i18n/SEO renderizada, evidencia de informes/aportes respaldadas por los trabajadores, verificaciones de proveedores de solo lectura y preparación para el humo de pagos. La evidencia de transcripción del lector de pantalla opcional está disponible con --screen-reader-evidence cuando se prepara la captura local de VoiceOver/Whisper.

Los comandos enfocados son útiles cuando es necesario volver a ejecutar un segmento:

npm run release:a11y-evidence
npm run release:i18n-seo-evidence
npm run release:pledge-evidence
npm run release:providers -- --no-dev-vars
npm run release:payment-smoke -- --no-dev-vars
npm run test:performance:budgets
npm run test:performance:lighthouse
npm run test:performance:runtime -- --input=/path/to/redacted-performance-observability.json
npm run test:cache-policy

Las comprobaciones de tiempo de Lighthouse, de política de caché implementada y de Worker autenticadas siguen el modelo de evidencia de lanzamiento de Store y no son necesarias en todas las solicitudes de extracción. Sus evaluadores puros permanecen cubiertos por el conjunto de unidades, mientras que los límites de preparación, pestañas y tablas del panel los ejerce el conjunto de navegadores de administración. Human VoiceOver, NVDA y revisiones en español nativo son pruebas de divulgación opcionales; La accesibilidad automatizada, la integridad de i18n y las comprobaciones SEO renderizadas siguen siendo necesarias.

Las comprobaciones del proveedor son de solo lectura y utilizan primero las credenciales del shell. En CI, el flujo de trabajo de publicación de pruebas del proveedor ejecuta npm run release:providers -- --cloudflare-dns-only --strict --no-dev-vars con CLOUDFLARE_DNS_API_TOKEN, CLOUDFLARE_ZONE_ID y CLOUDFLARE_ZONE.

Configure POOL_EMAIL_DRY_RUN=true o RESEND_EMAIL_DRY_RUN=true para evidencia de no envío de correo electrónico durante el humo de mutación local. El humo de pago mantiene la aceptación de evidencia de mutación de aporte a través de --local-mutation / PAYMENT_SMOKE_ALLOW_MUTATION=1 y rechaza los hosts de producción a menos que se anule explícitamente.

Revisión de riesgos éticos

Las pruebas automatizadas no pueden demostrar que un cambio de producto sea éticamente seguro. Para funciones relacionadas con dinero, datos de patrocinadores, mensajes, análisis, automatización, uso compartido público o poder administrativo, incluya una breve revisión de riesgos éticos en las notas de publicación o de relaciones públicas.

La evidencia útil incluye:

  • Comportamiento de consentimiento y exclusión voluntaria para recordatorios, Blast, vistas previas y comunicaciones con los patrocinadores.
  • prueba de prueba/no envío antes de enviar correos electrónicos masivos o informes
  • comprobaciones de noindex, mapa del sitio, vista previa social y captación previa para superficies privadas/tokenizadas
  • Worker: comprobaciones totales canónicas del progreso de la campaña, complementos, propinas, impuestos, envío, inventario y liquidación
  • Comprobaciones de accesibilidad y i18n para flujos de cara al usuario afectados.
  • una nota sobre la ruta de abuso sobre cómo la función podría usarse para spam, acoso, fraude, doxxing, afirmaciones engañosas o presión de participación excesiva

Trate el nuevo seguimiento oculto, las notificaciones ilimitadas, los metadatos públicos engañosos, la lógica monetaria confiable del navegador o la exposición pública del estado privado/tokenizado como bloqueadores de liberación hasta que se mitiguen.


Pruebas unitarias (Vitest)

Pruebas rápidas y aisladas para funciones JS en tests/unit/.

Cobertura

Módulo Funciones probadas
live-stats.js formatMoney, updateProgressBar, updateMarkerState, checkTierUnlocks, checkLateSupport, updateSupportItems, updateTierInventory
platform-tip Desinfección de propinas, derivación del porcentaje de propinas, cálculo del monto de la propina
pledge-management Cumplimiento de plazos según el horario de verano a través de la zona horaria configurada de la plataforma, cancelación/modificación/validación del método de pago, transiciones de estado de aporte, independencia de múltiples campañas, envío en registros de aporte, forma de respuesta API
settlement / stripe-client Agregación de cargos, liquidación determinista, versión de API Stripe/idempotencia/normalización de errores, éxito/fracaso de pago, flujo de reintento, envío por lotes, estado obsoleto/reanudado, índice de aporte de campaña y latido cron
email-broadcasts Extracción de extractos del diario (con truncamiento de puntos suspensivos), ayudas de seguimiento del diario/hitos, lógica de verificación de hitos, limitación de velocidad
email-tip Desgloses de correos electrónicos de soporte conscientes de sugerencias en correos electrónicos de confirmación/modificados/cancelados/fallidos/cargados, además de recordatorio de lanzamiento y enrutamiento de correos electrónicos de pago abandonado a través del remitente de actualizaciones compartido
email-outbox Deduplicación duradera en cola, carga útil congelada/idempotencia, tiempo de reintento del proveedor, supresión global/de campaña, verificación de firma de webhook Resend y evidencia de entrega
votes Almacenamiento/descopia de votos basado en correo electrónico, recuperación del estado de los votos, resultados de campaña, agregación de resultados
admin-dashboard Seguimiento del estado sucio del panel, serialización de configuraciones, normalización de contenido/editor, cargas de medios por etapas/selector de medios, análisis/relleno de tarifas reales de Stripe, informes de atribución de análisis, borradores compartidos de marketing, salud/supresión de pagos abandonados, ayudas de URL de referencia, utilidades de soporte responsivas/i18n
i18n-completeness Los catálogos locales admitidos permanecen alineados con la superficie de claves anidadas en inglés
campaign-page Construcción de URL de enlaces compartidos, preservación segura de consultas, texto compartido con reconocimiento de estado, envío de formularios de recordatorio de lanzamiento, controles de campañas públicas y comportamiento de la página de campaña sensible a SEO
page-prefetch Listas permitidas de rutas públicas del mismo origen, exclusiones de consultas confidenciales, protecciones de red, manejo de demoras/límites y creación de sugerencias de captación previa de documentos
cart-runtime-loader Arranque diferido en tiempo de ejecución del carrito, detección de carrito persistente/de recuperación, carga idempotente y activadores de intención del usuario
site-asset-minification Comportamiento de minificación CSS/JS generado _site y casos de falla del modo de verificación
media-optimization-script Selección de archivos modificados, clasificación de origen/derivado, manifiestos deterministas, presupuestos de ubicación, decisiones de optimización de imágenes sin pérdidas, denominación de derivados de vídeo y reescrituras de referencias de origen a WebM

Correr

npm run test:unit          # Run once
npm run test:unit:watch    # Watch mode for development
npm run test:unit:coverage # Generate coverage report

Runbook de regresión previo a la fusión

Úselo antes de fusionar ramas que toquen el pago, la lógica empresarial del trabajador, el cumplimiento o los flujos de transmisión.

Puerta automatizada

npm run test:premerge

Esto se ejecuta:

  • npm run test:secrets para verificar que los archivos env locales permanezcan ignorados y sus valores secretos no aparezcan en los archivos rastreados o en el historial de git
  • node --check para los puntos de entrada de los trabajadores modificados
  • Comprobaciones de idoneidad del comando de evidencia de publicación: sintaxis del script de publicación, release:smoke -- --help, release:providers -- --help y release:payment-smoke -- --no-dev-vars
  • Suites de regresión enfocadas:
    • tests/unit/worker-business-logic.test.ts
    • tests/unit/worker-ops-integrity.test.ts
    • tests/unit/stats-pagination.test.ts
    • tests/unit/setup-deploy-script.test.ts
  • Las suites de trabajo cubren la validación del registro de recordatorio de lanzamiento, la aceptación, el envío y la supresión de pago abandonado, enlaces de reanudación de pago firmado, supresión en el ámbito de la campaña, contadores de estado agregados, supresión de cancelación de suscripción, idempotencia de envío en cola y la ruta de envío compartida Resend.
  • Las pruebas del asistente de configuración ejecutan la CLI de implementación en copias de repositorio temporales con comandos falsos npm, npx/Wrangler, gh, stripe y ruby. Cubren ayuda/manejo de errores, comportamiento de ejecución en seco sin escritura, reutilización/creación de espacios de nombres KV, generación de secretos locales no interactivos, secretos de trabajadores de producción generados y sondas de preparación de solo lectura sin mutaciones de proveedores en vivo.
  • Regresiones del filtro de seguridad de contenido en tests/unit/content-safety-filter.test.ts, incluidos esquemas de enlaces Markdown inseguros, espaciado de énfasis creado por el panel y validación estricta de URL incrustadas estructuradas
  • Cobertura de auditoría de contenido de campaña en tests/unit/campaign-content-security.test.ts, incluido el subconjunto HTML en línea permitido y el rechazo de etiquetas sin procesar no permitidas.
  • Cobertura de serialización de inventario de niveles de objetos duraderos en tests/unit/tier-inventory-do.test.ts
  • Guiones de humo locales contra la campaña mutable de solo prueba:
    • scripts/test-worker.sh para verificaciones de contrato de sitio/trabajador y verificación de /checkout-intent/start con formato incorrecto
    • scripts/smoke-pledge-management.sh para una cobertura de modificación/cancelación exitosa en la campaña mutable solo local, utilizando las respuestas de reconstrucción del administrador más verificaciones de deriva de proyección de solo lectura como fuente autorizada de estadísticas/inventario durante el humo. El script ahora rota sus IP de solicitud de administrador sintéticas durante esas llamadas de reconstrucción/verificación para que el limitador de velocidad de administrador real no cree un falso negativo en la activación de combinación local.
  • Suite de unidad completa a través de npm run test:unit
  • Paquete de seguridad a través de npm run test:security contra un trabajador local iniciado automáticamente
  • Suite de seguridad respaldada por Podman a través de npm run test:security:podman cuando desea que el sitio/pila de trabajo se inicie y se ejerza en la misma invocación.
  • Verificaciones de artefactos de compilación propios que ejecutan Jekyll, minimizan los activos CSS/JS _site generados, verifican que la salida minimizada no tiene ahorros restantes y ejecutan npm run test:seo contra la salida de rastreo/metadatos generada.
  • Rendimiento de páginas públicas y regresiones de uso compartido a través de cobertura de unidades para captación previa de intenciones, carga diferida en tiempo de ejecución del carrito, minificación de activos generados y comportamiento de enlaces compartidos de campañas.
  • Dramaturgo sin cabeza E2E vía npm run test:e2e:headless

El script previo a la fusión ahora inicia automáticamente Jekyll con _config.yml,_config.local.yml cuando es necesario, de modo que la campaña smoke-editable solo local esté disponible durante la activación de la fusión y el arnés Playwright use la misma configuración combinada localmente. Esa puerta ahora intenta primero la ruta del host Bundler/Jekyll, incluido un intento único de bundle install cuando Bundler está presente pero faltan gemas. Mantiene el humo del trabajador del host más ligero, pero ejecuta el humo de aporte mutable a través de la pila respaldada por Podman para que la ruta de modificación/cancelación con estado utilice un estado de servicio local aislado incluso cuando la ruta de compilación del host tiene éxito. Si la ruta Ruby del host aún no puede compilarse limpiamente, recurre a una compilación Jekyll respaldada por Podman más los asistentes de navegador/humo compatibles con Podman restantes en lugar de fallar solo en la configuración del host. Ambos ayudantes de Jekyll fallan inmediatamente cuando falla su comando de compilación, por lo que la minificación y la validación de artefactos no pueden reutilizar accidentalmente la salida obsoleta de _site. Para ejecuciones de navegadores sin cabeza, Playwright ahora construye un _site estático y sirve esa salida con un servidor HTTP liviano en lugar de usar jekyll serve, lo que mantiene las comprobaciones automatizadas del navegador más cercanas al diseño real de los activos publicados.

Esta rama ahora tiene como valor predeterminado la ruta de tiempo de ejecución/carro propio tanto en _config.yml como en _config.local.yml, y la ruta del navegador ya no admite el antiguo tiempo de ejecución del carro alojado.

El reciente refuerzo de seguridad que ahora cubre la puerta incluye:

  • comportamiento de cierre fallido de GET /pledge cuando existe un token de enlace mágico pero la fila de aporte no
  • Neutralización del esquema de enlaces de Markdown en contenido de formato largo
  • Validación de origen exacto para incrustaciones estructuradas (spotify, youtube, vimeo)
  • reservas serializadas de inventario de nivel limitado al inicio del pago y confirmación en el momento de persistencia exitosa
  • recordatorio de lanzamiento Verificación de torniquete, almacenamiento de registro deduplicado, supresión de cancelación de suscripción con alcance y envío idempotente

La optimización de medios está intencionalmente separada de la puerta previa a la fusión porque depende de herramientas nativas como FFmpeg y optimizadores de imágenes. Las cargas de imágenes/videos del panel solicitan el optimizador después de la confirmación, pero cuando una rama incluye medios agregados manualmente o necesita verificar las variantes generadas antes de fusionar, ejecute:

npm run media:optimize:check
npm run media:optimize:check:podman # use when host-native media tools are missing

Los valores predeterminados del trabajador local en worker/wrangler.toml ahora coinciden con la configuración propia. ./scripts/dev.sh --podman ahora genera automáticamente un CHECKOUT_INTENT_SECRET local en worker/.dev.vars si falta, por lo que los nuevos inicios de pago local no fallan al cerrarse en un secreto de desarrollo no inicializado.

Cuando la puerta de fusión o el paquete de seguridad local utilizan el marcador de posición STRIPE_SECRET_KEY=sk_test_smoke, /test/setup genera ID de clientes de Stripe sintéticos deterministas en lugar de llamar a Stripe. Utilice una clave de prueba de Stripe real solo cuando necesite específicamente cobertura de humo de actualización de métodos de pago contra la API de Stripe.

Para trabajo local, prefiera ./scripts/dev.sh --podman. Inicia a Jekyll y al Trabajador en contenedores Podman desarraigados, preservando al mismo tiempo los mismos puertos y el estado local de Wrangler.

_config.local.yml ahora es una capa de solo anulación, no una segunda configuración base. Cuando cambie o agregue configuraciones de orientación hacia la bifurcación, prefiera _config.yml a menos que el valor realmente difiera solo en su máquina local.

Los scripts de ayuda del navegador admiten el mismo modo:

./scripts/test-checkout.sh --podman
./scripts/test-e2e.sh --podman
./scripts/test-worker.sh --podman
./scripts/smoke-pledge-management.sh --podman
./scripts/pledge-report.sh --podman --local
./scripts/fulfillment-report.sh --podman --local

Esos ayudantes todavía ejecutan Playwright y shell smoke logic en el host por ahora, pero primero inician el sitio y el Worker a través de la pila local compartida respaldada por Podman. Los scripts de informes ahora también se pueden ejecutar directamente a través del contenedor de trabajadores. Esto mantiene las pruebas y exportaciones locales más cerca de los límites del servicio similar a la producción sin forzar la configuración del host Ruby o Wrangler.

Para los comandos del lado del host que necesitan la pila respaldada por Podman pero que no deben depender de la persistencia de la pila separada en shells separados, use scripts/podman-stack-run.sh. npm run test:security:podman usa ese contenedor.

Para una ruta de navegador mayoritariamente independiente del host, npm run test:e2e:headless:podman ahora ejecuta la suite Playwright automatizada dentro de un contenedor Podman dedicado en la misma red de pod local que el sitio y el Worker.

La cobertura reciente del navegador también incluye aserciones de ventanas gráficas móviles dedicadas para:

  • páginas de campaña y controles públicos secundarios
  • Cajones de carrito/caja en tamaños de teléfono pequeños
  • Administre la accesibilidad de la tarjeta de aporte y actualización en ventanas gráficas móviles cortas
  • controles sin desbordamiento horizontal en las principales vías públicas y de gestión de aportes

La cobertura reciente de páginas públicas ahora también protege el Chrome de campaña más localizado, que incluye:

  • Estados de carga/reproducción de vídeo heroico
  • copia teaser de la comunidad de patrocinadores
  • etiquetas de pestañas del diario y estados vacíos
  • etiquetas de la fase de producción y copia de CTA
  • etiquetas de accesibilidad de la galería

El conjunto de filtros de seguridad de contenido en tests/unit/content-safety-filter.test.ts también recurre a Podman cuando las gemas del host Bundler/Jekyll no están disponibles. En macOS, puede iniciar la máquina Podman como parte de ese respaldo.

El alcance actual de Podman es intencionalmente limitado:

  • incluido: Jekyll, Worker, worker/.dev.vars local, estado de Wrangler local, reenvío CLI de Stripe de host opcional, test-checkout.sh, test-e2e.sh, test-worker.sh, smoke-pledge-management.sh, pledge-report.sh y fulfillment-report.sh compatibles con Podman
  • También se incluye: Playwright sin cabeza en contenedores para el conjunto de navegadores automatizados.
  • aún no incluido: un paso del navegador de pago manual interactivo en contenedores

Utilice docs/PODMAN.md para conocer la configuración exacta y las limitaciones actuales.

Si cambia pricing.sales_tax_rate o shipping.fallback_flat_rate en la configuración de Jekyll, el repositorio ahora sincroniza automáticamente los valores de Worker reflejados en worker/wrangler.toml a través de las rutas principales de desarrollo/prueba. Reinicie ./scripts/dev.sh --podman antes de probar las matemáticas de pago para que ambos servicios recojan los nuevos valores.

Si ajusta el comportamiento de lectura del plan gratuito, manténgalos sincronizados también:

  • cache.live_stats_ttl_seconds
  • cache.live_inventory_ttl_seconds
  • performance.intent_prefetch_enabled
  • performance.intent_prefetch_delay_ms
  • performance.intent_prefetch_limit

Después de cambiar esos controles de rendimiento o caché localmente, reinicie ./scripts/dev.sh --podman y vuelva a ejecutar:

npx vitest run tests/unit/live-stats.test.ts tests/unit/manage-page.test.ts tests/unit/config-boot.test.ts

Esas suites protegen la ruta de lectura combinada /live/:slug, el comportamiento de la caché del navegador y el cableado de arranque de configuración del que dependen las bifurcaciones.

Para las superficies públicas de captación previa, enlace compartido y tiempo de ejecución de carrito diferido, utilice:

npx vitest run \
  tests/unit/page-prefetch.test.ts \
  tests/unit/cart-runtime-loader.test.ts \
  tests/unit/campaign-page.test.ts \
  tests/unit/seo-layouts.test.ts \
  tests/unit/site-asset-minification.test.ts

Para el rastreo generado y la salida de metadatos estructurados, primero cree y minimice el sitio y luego ejecute:

SKIP_TESTS=1 bundle exec jekyll build --config _config.yml,_config.local.yml --quiet
npm run assets:minify
npm run test:seo

La auditoría SEO verifica las páginas creadas, robots.txt, sitemap.xml, el diagnóstico coincidente de una URL por línea sitemap.txt, las URL canónicas, las sugerencias de actualización escritas, las alternativas de hreflang, los metadatos de Open Graph/Twitter y JSON-LD. Se pueden crear campañas locales de prueba únicamente para la cobertura del humo, pero permanecen intencionalmente ausentes de cualquiera de los formatos de mapa del sitio.

Después de una implementación de producción, verifique la superficie de rastreo real orientada al origen:

npm run test:crawl-endpoints -- --base=https://site.example.com --attempts=6 --retry-delay-ms=5000

Es seguro ejecutar esta auditoría libre de dependencias en el trabajo de implementación una vez que desaparezcan las dependencias de compilación raíz. Compara los organismos de inspección ordinarios y de Google para los mapas de sitio XML y de texto, requiere que sus listas de URL públicas ordenadas coincidan, aplica los tipos MIME XML/texto/robots, verifica el anuncio canónico del mapa de sitio XML y recupera cada página enviada. Se permite una inyección normal de detección de JavaScript Cloudflare en una página HTML completa; un intersticial sin el enlace canónico de la página y el contenido principal falla. Los reintentos limitados cubren la propagación normal sin convertir un defecto de rastreo persistente en una advertencia.

En GitHub, la misma puerta se ejecuta automáticamente en el flujo de trabajo Merge Smoke para solicitudes de extracción dirigidas a main.

La puerta de fusión ahora escribe un archivo de registro por fase e imprime un resumen final de PASA/FALLA con las rutas de registro. Si falla una fase tardía respaldada por Podman, comience con el directorio de registro impreso al final de la ejecución en lugar de desplazarse por toda la transcripción.

Auditoría secreta

Ejecute esto antes de presionar cuando los secretos locales hayan cambiado, o deje que npm run test:premerge lo ejecute automáticamente:

npm run test:secrets

La auditoría comprueba:

  • worker/.dev.vars permanece ignorado y sin seguimiento
  • Los valores secretos no permitidos de los archivos env locales no aparecen en los archivos de repositorio con o sin seguimiento.
  • esos valores no aparecen en el historial de git

CI permanece seguro cuando worker/.dev.vars no existe; en ese caso, la auditoría aún verifica las reglas de ignorar y omite el escaneo de valores locales.

Comparación de sucursales principales

Ejecute la misma puerta automatizada en main en un árbol de trabajo limpio para que la línea base y la rama del parche sean directamente comparables. Si main es anterior a test:premerge, ejecute manualmente allí los comandos de sintaxis, unidad, seguridad y E2E equivalentes.

git worktree add ../pool-main-check main
ln -s "$(pwd)/node_modules" ../pool-main-check/node_modules
cd ../pool-main-check
npm run test:premerge

Si crea el árbol de trabajo temporal, elimínelo después de la comparación:

cd -
git worktree remove ../pool-main-check

Lista de verificación manual de humo

Ejecútelos contra la preparación antes de fusionarlos cuando exista un entorno de preparación. Si no existe un entorno de prueba para The Pool, ejecute la misma lista de verificación localmente con ./scripts/dev.sh --podman y registre esa excepción en las notas de la versión/PR.

  1. Inicie un nuevo pago en una campaña de prueba en vivo y confirme que /checkout-intent/start devuelve un arranque de sesión personalizado cuando se configura la clave publicable de Stripe coincidente, o una URL alojada cuando se utiliza intencionalmente el respaldo alojado.
  2. Complete un aporte y verifique que el webhook almacene el aporte, la actualización de estadísticas y la ruta del correo electrónico de confirmación se mantenga en buen estado.
  3. Modifique un aporte con cambios de nivel/soporte/cantidad personalizada y verifique los totales, el historial y la actualización del inventario correctamente.
  4. Cancele un aporte no cargada y verifique que las estadísticas y el inventario se publiquen correctamente.
  5. Realice ensayos de liquidación y ejecución real de los aportes iniciales, confirmando que las campañas solo marcan el acuerdo cuando nada necesita atención.
  6. Active transmisiones de diarios, anuncios e hitos en una campaña lo suficientemente grande como para cruzar los límites de paginación.
  7. Active un informe de cumplimiento en una campaña con elementos de campaña y de plataforma, confirmando que los destinatarios del corredor reciben solo filas de campaña y support_email recibe el archivo adjunto solo de plataforma.

Para cambios en la lógica empresarial de pago o de trabajador, aún se requiere un pase de humo antes de fusionar:

  • Prefiere la puesta en escena cuando esté disponible.
  • Si no existe ninguna preparación, utilice la ruta local más segura:
    • ./scripts/dev.sh --podman
    • ./scripts/smoke-pledge-management.sh
    • la lista de verificación del operador en docs/MERGE_SMOKE_CHECKLIST.md
    • una nota de relaciones públicas que indique explícitamente que no existe un entorno de prueba

Para obtener una versión lista para el operador con comandos exactos y resultados esperados, use docs/MERGE_SMOKE_CHECKLIST.md.

Para un ensayo local de gestión de aportes, prefiera la campaña smoke-editable. Es solo local a través de test_only: true, permanece activo mucho más allá de la ventana de humo normal y le brinda a /test/setup un objetivo estable para la cobertura de modificación/cancelación.

Puedes ejercitar ese camino de principio a fin con:

./scripts/smoke-pledge-management.sh

Cuando ADMIN_SECRET está disponible, esa ruta de humo ahora también verifica que la campaña permanezca limpia en la proyección después de la configuración, modificación y cancelación llamando al punto final de solo lectura POST /stats/:slug/check entre fases de mutación.

Para la verificación CSV local con respecto a su estado de trabajador local real, utilice:

./scripts/pledge-report.sh --local
./scripts/fulfillment-report.sh --local

Utilice pledge-report.sh cuando desee el libro mayor completo, incluidas las deltas de modificación/cancelación y las anotaciones de cambio de propinas. Utilice fulfillment-report.sh cuando desee fusionar el estado actual de un patrocinador dentro de una campaña.

Si la vista de cumplimiento fusionada y el sitio público alguna vez no están de acuerdo para una campaña, trátelo primero como un problema probable de estadísticas obsoletas/proyección de inventario, no como un error de notificación de forma predeterminada. Las estadísticas de administración y los puntos finales de recálculo de inventario ahora reparan índices campaign-pledges:{slug} obsoletos mientras reconstruyen el estado de proyección de la campaña.

Antes de reparar una proyección, ahora puede comprobar explícitamente la desviación:

./scripts/check-projections.sh                 # Check all campaigns
./scripts/check-projections.sh hand-relations  # Check one campaign
./scripts/check-projections.sh --podman        # Reuse/start the Podman dev stack first

Ese script llama a los puntos finales de verificación de deriva del administrador de solo lectura y sale de un valor distinto de cero cuando las proyecciones almacenadas campaign-pledges:{slug}, stats:{slug} o tier-inventory:{slug} ya no coinciden con la verdad del aporte activo.

Cambios de comportamiento intencionales

Al revisar los resultados, no los marque como regresiones:

  • Los enlaces mágicos ahora tienen un alcance de pedido en lugar de un alcance de correo electrónico.
  • /checkout-intent/start ahora reserva un inventario limitado y escaso antes de la confirmación del pago, y la persistencia exitosa confirma esa reserva.
  • El GET /checkout heredado está deshabilitado intencionalmente.

Agregar pruebas

Cree archivos en tests/unit/ con la extensión .test.ts:

import { describe, it, expect } from 'vitest';

describe('myFunction', () => {
  it('does something', () => {
    expect(myFunction()).toBe(expected);
  });
});

Pruebas E2E (Dramaturgo)

Pruebas basadas en navegador para flujos de usuarios completos en tests/e2e/.

Cobertura

Estructura de la página de campaña:

  • Elementos de página requeridos (héroe, barra lateral, barra de progreso)
  • Atributos de datos de la barra de progreso para live-stats.js
  • Marcadores de hitos (1/3, 2/3, meta)
  • Marcadores de meta estirados

Tarjetas de nivel:

  • Atributos y ganchos de artículos de carrito propios
  • Visualización de inventario para niveles limitados
  • Estado de bloqueo de nivel cerrado e insignia de desbloqueo
  • Estados deshabilitados en campañas no activas

Productos físicos y envío:

  • Campo personalizado _category (físico/digital) en botones de nivel
  • Los niveles físicos activan el estado de expectativa de envío propio antes de la recolección de Stripe
  • Las campañas solo digitales no tienen niveles de categorías físicas

Artículos de soporte:

  • Estructura (cantidad, progreso, entrada, botón)
  • Entrada → sincronización de precios del carrito propio
  • Atributos de datos de soporte tardío

Cantidad personalizada:

  • Atributos de estructura y datos
  • Entrada → sincronización de precios del carrito propio
  • Atributos de soporte tardío

Tarjetas de página de inicio y campaña:

  • Visualización de tarjetas y elementos requeridos.
  • Enlaces de campaña válidos
  • Atributos del botón de nivel destacado

Integración en tiempo de ejecución del carrito:

  • Arranque en tiempo de ejecución y raíz de carrito neutral
  • POOL_CONFIG para live-stats.js
  • Funciones globales (refreshLiveStats, getTierInventory)

Flujo del carrito:

  • Navegación y añadir al carrito
  • Estado del carrito a través de PoolCartProvider
  • Autocompletar de facturación/estado de pago controlado por el proveedor
  • El control deslizante de propinas actualiza los totales del carrito inmediatamente
  • Las campañas de un solo nivel reemplazan el nivel anterior inmediatamente cuando se selecciona un nuevo nivel.
  • La vista previa del pago propio publica cargas útiles canónicas en /checkout-intent/start
  • Las páginas de resultados canceladas o exitosas de origen restauran o hidratan el estado del aporte guardado

Administrar flujo:

  • Carga de aportes respaldadas por tokens en /manage/
  • Inicio de actualización del método de pago para aportes activos y payment_failed
  • Cancelar publicaciones de confirmación en /pledge/cancel
  • Modificar publicaciones de confirmación a /pledge/modify

Accesibilidad:

  • Saltar enlace
  • Hito de contenido principal
  • Etiquetas de botones accesibles
  • Etiquetas de entrada de formulario

Temporizadores de cuenta regresiva:

  • Valores pre-renderizados (sin flash “00 00 00 00”)
  • El temporizador se actualiza cada segundo.

Estados de la campaña:

  • Niveles habilitados para campañas en vivo
  • Próximos niveles de campaña inhabilitados
  • Indicadores estatales en progreso meta

Aspectos destacados de la cobertura de pago:

  • Flujo completo del aporte: tiempo de ejecución del carrito → revisión del aporte → paso de pago de Stripe en el sitio → página de éxito
  • Verifique que la vista previa del resumen del pedido de pago aparezca inmediatamente y se resuelva en totales que tengan en cuenta las propinas
  • Cobertura de prueba de integración de API de trabajador para estadísticas en vivo y arranque de pago

Aspectos destacados de la cobertura del panel de administración:

  • Inicio de sesión con enlace mágico, pestañas con alcance de función y restricciones de acceso de usuarios de campaña
  • Configuración, complementos, campañas, análisis, informes, patrocinadores y comportamiento de la pestaña Marketing
  • Superadministrador Cree un nuevo flujo de campaña, incluidos varios usuarios de campaña nuevos o existentes y el comportamiento del correo electrónico de asignación.
  • Flujo de publicación de vista previa protegida, incluida la creación de vínculos al panel de control del usuario actual, UX de entrada de correo electrónico del revisor opcional, manejo de conflictos de revisión base, vínculos del revisor las 24 horas y cero persistencia del correo electrónico del revisor en la campaña Markdown
  • Flujo de campaña de archivo de superadministrador, que incluye visibilidad no en vivo, rechazo de campaña en vivo, rechazo de usuario de campaña, movimientos de archivo local, cuerpo de envío de GitHub Action y presupuesto de redacción de eventos de auditoría
  • Configuración -> Carga automática del uso del plan, texto de ayuda del proveedor, enlaces de proveedores localizados y presupuesto de lectura sin escritura
  • Ingresos brutos de campaña/plataforma, ingresos netos de campaña/plataforma después de las tarifas de procesador asignadas y presentación de análisis de centavos exactos
  • Editor de contenido Edición de bloques WYSIWYG, configuración de enlaces/medios, reutilización del editor de diario, estado de borrador, estado de publicación y vista previa móvil
  • Códigos de referencia de marketing guardados, creador de URL de campaña, comportamiento de descarga de QR, flujos de ejecución en seco/prueba/envío en vivo de Blast, historial de Blast enviado, exportaciones CSV, clasificación y flujos de lectura sin escritura
  • Capacidad de respuesta de escritorio/tableta/móvil, incluidos menús compactos de tableta en español
  • Ax comprueba el shell del panel autenticado

Correr

npm run test:e2e           # Full suite (auto-starts Jekyll)
npm run test:e2e:quick     # Headed mode (requires running server)
npm run test:e2e:headless  # CI mode (headless)
npm run test:e2e:parity    # Critical cart/manage browser regressions
npm run test:e2e:ui        # Interactive UI mode
npx playwright test tests/e2e/admin-dashboard.spec.ts --project=chromium

Agregar pruebas

Cree archivos en tests/e2e/ con la extensión .spec.ts:

import { test, expect } from '@playwright/test';

test('user can do something', async ({ page }) => {
  await page.goto('/');
  await expect(page.locator('.element')).toBeVisible();
});

Pruebas de seguridad (Vitest)

Pruebas de penetración para la API Worker. Ubicado en tests/security/.

Cobertura

Categoría Pruebas
Omisión de autenticación Omisión de token de desarrollo, validación de token, caducidad, manipulación
Seguridad del webhook Verificación de firma de franja, manejo de eventos duplicados, inyección de dirección de envío, manejo de webhooks heredados eliminados
Autorización Puntos finales de administración, acceso entre usuarios, protecciones de puntos finales de prueba
Validación de entrada XSS, inyección, desbordamiento, entrada con formato incorrecto, normalización de campos del panel de control, abuso de indicadores físicos, manipulación de tarifas de envío, niveles adicionales/inyección de artículos de soporte
Limitación de tasa Solicitudes de ráfaga, resistencia DoS

Correr

# Start local Worker first
cd worker && wrangler dev

# In another terminal:
npm run test:security                # Against localhost:8787

# Against staging, if you maintain one:
npm run test:security:staging

# Against production (read-only tests):
WORKER_URL=https://worker.example.com PROD_MODE=true npm run test:security

Requisitos previos

  • Trabajador que se ejecuta localmente (wrangler dev) o URL de preparación/producción accesible
  • Para una cobertura de prueba completa, establezca las variables de entorno:
    • WORKER_URL: URL base (predeterminada: http://localhost:8787)
    • PROD_MODE: omitir pruebas destructivas (predeterminado: false)
    • ADMIN_SECRET: para pruebas de autenticación de administrador
    • ADMIN_SETTLEMENT_SECRET: secreto de alcance opcional para pruebas de autenticación de liquidación o comprobaciones de preparación
    • ADMIN_BROADCAST_SECRET: secreto de alcance opcional para pruebas de autenticación de transmisión/diario o comprobaciones de preparación
    • TEST_TOKEN — Token de enlace mágico válido

Consulte tests/security/README.md para obtener más detalles.


Requisitos previos de las pruebas manuales

  • Wrangler CLI (npm install -g wrangler)
  • Stripe CLI para pruebas de webhook
  • Cuenta Stripe (modo de prueba)
  • Cuenta Resend (nivel gratuito: 3000 correos electrónicos/mes)

1. Configuración del trabajador de Cloudflare

Crear espacios de nombres KV

wrangler login
wrangler kv:namespace create "VOTES"
wrangler kv:namespace create "VOTES" --preview
wrangler kv:namespace create "PLEDGES"
wrangler kv:namespace create "PLEDGES" --preview

Establecer secretos

cd worker
openssl rand -base64 32

wrangler secret put STRIPE_SECRET_KEY
wrangler secret put MAGIC_LINK_SECRET
wrangler secret put CHECKOUT_INTENT_SECRET
wrangler secret put RESEND_API_KEY
wrangler secret put ADMIN_SECRET
wrangler secret put ADMIN_SETTLEMENT_SECRET
wrangler secret put ADMIN_BROADCAST_SECRET

Ejecutar trabajador localmente

Privilegiado:

./scripts/dev.sh --podman

Respaldo manual:

cd worker
npx wrangler dev --env dev --port 8787

2. Configuración de Resend

Utilice EMAIL.md como referencia completa de configuración e integración del correo electrónico. Esta sección es la ruta corta de prueba manual.

Crear cuenta y clave API

  1. Regístrese en resend.com
  2. Vaya a Claves APICrear clave API
  3. Nombre: “Desarrollador de proyectos”
  4. Permiso: “Enviando acceso”
  5. Copie la clave (comienza con re_)

Verificar dominio (para producción)

  1. Vaya a DominiosAgregar dominio
  2. Agregue el dominio de remitente exacto utilizado por PLEDGES_EMAIL_FROM/UPDATES_EMAIL_FROM (para esta implementación, site.example.com)
  3. Agregue los registros DNS que proporciona Resend
  4. Esperar verificación

Modo de prueba (no se necesita dominio)

Para realizar pruebas, puede enviar a su propio correo electrónico sin verificación de dominio:

  • Resend permite enviar desde [email protected] en modo de prueba
  • O utilice su correo electrónico personal verificado

Envío de correo electrónico de prueba

curl -X POST 'https://api.resend.com/emails' \
  -H 'Authorization: Bearer re_YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "from": "[email protected]",
    "to": "[email protected]",
    "subject": "Test from your deployment",
    "html": "<p>Magic link test!</p>"
  }'

Para obtener evidencia de entrega de producción, cree también https://worker.example.com/webhooks/resend, suscríbase a eventos entregados/rebotados/quejados/fallidos/suprimidos y almacene su secreto de firma como RESEND_WEBHOOK_SECRET. Las pruebas unitarias sintetizan eventos firmados; no llaman en vivo Resend.


3. Configuración de Stripe (modo de prueba)

Utilice PAYMENT_PROCESSOR.md como referencia completa de configuración, webhook, liquidación y conciliación de Stripe. Esta sección es la ruta corta del modo de prueba local.

Obtener claves de prueba

  1. Inicie sesión en dashboard.stripe.com
  2. Cambiar a Modo de prueba (arriba a la derecha)
  3. Vaya a DesarrolladoresClaves API
  4. Copiar Clave secreta (sk_test_...)

Instalar CLI de banda

# macOS
brew install stripe/stripe-cli/stripe

# Login
stripe login

Reenviar webhooks al trabajador local

Opción preferida para pruebas locales de un extremo a otro:

./scripts/dev.sh --podman

Esto inicia el reenvío Jekyll, the Worker, Stripe CLI y escribe el STRIPE_WEBHOOK_SECRET coincidente en worker/.dev.vars. También borra los procesos obsoletos en los puertos 4000, 8787 y 4040 para que la pila local coincida con el arnés de prueba/humo automatizado.

Respaldo manual:

# Forward Stripe webhooks to your local Worker
stripe listen --forward-to 127.0.0.1:8787/webhooks/stripe
# Note the webhook signing secret it outputs (whsec_...)

Agregue el secreto del webhook a su configuración de trabajador local:

printf '\nSTRIPE_WEBHOOK_SECRET=whsec_...\n' >> worker/.dev.vars
# Or edit worker/.dev.vars and replace the existing STRIPE_WEBHOOK_SECRET value

4. Prueba completa de un extremo a otro

Iniciar todos los servicios

Privilegiado:

./scripts/dev.sh --podman

Respaldo manual:

Terminal 1 - Jekyll:

bundle exec jekyll serve --config _config.yml,_config.local.yml --port 4000
# Site at http://127.0.0.1:4000

Terminal 2 - Trabajador:

cd worker
npx wrangler dev --env dev --port 8787
# Worker at http://127.0.0.1:8787

Terminal 3 - CLI de banda:

stripe listen --forward-to 127.0.0.1:8787/webhooks/stripe

Pruebe el flujo

  1. Añadir al carrito: Ir a http://127.0.0.1:4000/campaigns/hand-relations/
    • Haga clic en “Prometer $5” en un nivel
    • El carrito se abre con el artículo.
  2. Pagar: haga clic en “Continuar con el aporte” en la revisión del carrito propio
    • Verifique que la reseña muestre el subtotal + propina + impuestos + envío inmediatamente
    • Utilice la tarjeta de prueba Stripe: 4242 4242 4242 4242
    • Cualquier vencimiento futuro, cualquier CVC
  3. Configuración de Stripe: el segundo sidecar de pago lo mantiene en el sitio y monta la interfaz de usuario de pago seguro de Stripe.
    • La tarjeta está guardada (no cargada)
    • El cliente espera la confirmación de persistencia del aporte antes de considerar el flujo como exitoso.
    • Luego serás enviado a la página de éxito.
  4. Consultar correo electrónico: Deberías recibir los correos electrónicos de los patrocinadores con enlaces mágicos.

  5. Pruebe el acceso a la comunidad:
    • Haga clic en el enlace de la comunidad en el correo electrónico.
    • O utilice: http://127.0.0.1:4000/community/hand-relations/?dev=1
  6. Votación de prueba:
    • Votar sobre una decisión
    • Actualizar página: tu voto debe persistir

Tarjetas de prueba de Stripe

Número de tarjeta Escenario
4242 4242 4242 4242 Guardado/configuración exitosos
4000 0000 0000 3220 Se requiere 3D Secure
4000 0000 0000 9995 Rechazado (fondos insuficientes)
4000 0000 0000 0002 Rechazado (genérico)

5. Prueba de componentes individuales

Prueba de ficha de enlace mágico

// In browser console on any page with the Worker running
const token = 'YOUR_TOKEN';
fetch(`http://localhost:8787/pledge?token=${token}`)
  .then(r => r.json())
  .then(console.log);

API de votación de prueba

# Get vote status
curl "http://localhost:8787/votes?token=YOUR_TOKEN&decisions=poster,festival"

# Cast vote
curl -X POST http://localhost:8787/votes \
  -H "Content-Type: application/json" \
  -d '{"token":"YOUR_TOKEN","decisionId":"poster","option":"A"}'

Pruebe KV localmente

# List keys
wrangler kv:key list --binding VOTES --preview

# Get a value
wrangler kv:key get "results:hand-relations:poster" --binding VOTES --preview

6. Solución de problemas

El inicio del proceso de pago falla y se cierra

  • Verifique que CHECKOUT_INTENT_SECRET exista en worker/.dev.vars
  • Confirme que la carga útil del carrito utilice ID de artículo propios válidos, como {campaignSlug}__{tierId}.

Webhook no recibido

  • Verifique que Stripe CLI se esté ejecutando y reenviando
  • Verificar registros de trabajadores: wrangler tail
  • Verificar que el secreto del webhook esté configurado

Correo electrónico no enviado

  • Verifique el panel de Resend para ver si hay errores
  • Verifique que la clave API sea correcta
  • Verifique que la dirección “de” esté verificada o use [email protected]

La página de la comunidad muestra “Acceso denegado”

  • Utilice ?dev=1 para pruebas locales sin trabajador
  • Verificar clave de almacenamiento de sesión: supporter_token_hand-relations

Los votos no persisten

  • Verifique el enlace KV en wrangler.toml
  • Utilice el espacio de nombres --preview para desarrolladores locales
  • Verifique los registros de trabajadores en busca de errores

7. Mejoras para los trabajadores de pruebas

Validación de campaña de prueba

  1. Construye Jekyll para generar campañas.json:
    bundle exec jekyll build
    cat _site/api/campaigns.json  # Verify it exists
    
  2. Prueba de inicio de pago propio con formato incorrecto:
    curl -X POST http://localhost:8787/checkout-intent/start \
      -H "Content-Type: application/json" \
      -d '{"campaignSlug":"hand-relations","items":[{"id":"bad-item","quantity":1}],"email":"[email protected]"}'
    

    Esperado: Devuelve un error de validación de cierre fallido como Invalid cart item id

Verificación de firma de Test Stripe Webhook

  1. Asegúrese de que Stripe CLI reenvíe webhooks:
    ./scripts/dev.sh --podman
    # Or, manually: stripe listen --forward-to localhost:8787/webhooks/stripe
    
  2. Establecer el secreto del webhook:
    # scripts/dev.sh --podman does this automatically for worker/.dev.vars
    # Manual setup only if you are not using the main Podman dev script
    
  3. Activar un webhook de prueba:
    stripe trigger checkout.session.completed
    

    Verifique los registros de trabajadores para ver el mensaje “Aporte confirmado”.

  4. Prueba de firma no válida (debe fallar):
    curl -X POST http://localhost:8787/webhooks/stripe \
      -H "stripe-signature: invalid" \
      -d '{"type":"test"}'
    

    Esperado: {"error":"Invalid signature"}

Prueba de metadatos de aporte almacenados

Después de completar un flujo de contribución:

  1. Consulte los datos de los aportes respaldadas por los trabajadores a través de /pledge?token=...
  2. Verifique que los datos contengan:
    • stripeCustomerId
    • stripePaymentMethodId
    • pledgeStatus: "active"
    • charged: false

Puntos finales de gestión de aportes de prueba

  1. Obtenga detalles del aporte (requiere un token válido):
    # Use token from supporter email
    curl "http://localhost:8787/pledge?token=YOUR_TOKEN"
    

    Esperado: devuelve detalles del pedido con indicadores canModify, canCancel.

  2. Cancelar aporte:
    curl -X POST http://localhost:8787/pledge/cancel \
      -H "Content-Type: application/json" \
      -d '{"token":"YOUR_TOKEN"}'
    

    Esperado: {"success":true,"message":"Pledge cancelled"}

  3. Verificar cancelación:
    • Consulte el aporte ahora informa pledgeStatus: "cancelled"
    • Reintentar cancelar: debería obtener una respuesta de error limpia

Método de pago de actualización de prueba

curl -X POST http://localhost:8787/pledge/payment-method/start \
  -H "Content-Type: application/json" \
  -d '{"token":"YOUR_TOKEN"}'

Esperado: devuelve un arranque de sesión personalizado para Update Card en el sitio o una URL alojada en modo alternativo.

Pruebe el punto final de estadísticas en vivo

  1. Obtenga estadísticas en vivo para una campaña:
    curl http://localhost:8787/stats/hand-relations
    

    Esperado: Devuelve { pledgedAmount, pledgeCount, tierCounts, goalAmount, ... }

  2. Verificar la actualización de las estadísticas después del aporte:
    • Haz un aporte de prueba
    • Llamar al punto final de estadísticas nuevamente
    • Confirmar que pledgedAmount aumentó
  3. Recalcular estadísticas (admin):
    curl -X POST http://localhost:8787/stats/hand-relations/recalculate \
      -H "Authorization: Bearer YOUR_ADMIN_SECRET"
    

Activador de reconstrucción de administrador de prueba

curl -X POST http://localhost:8787/admin/rebuild \
  -H "Authorization: Bearer YOUR_ADMIN_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"reason":"test-rebuild"}'

Esperado: devuelve { success: true } y activa el flujo de trabajo de GitHub.


8. Lista de verificación de producción

  • Cambiar Stripe a claves en vivo
  • [] Revise PAYMENT_PROCESSOR.md para obtener claves activas, secretos de webhooks, credenciales de liquidación y comprobaciones de conciliación de Stripe.
  • [] Verifique el dominio del remitente Resend utilizado por PLEDGES_EMAIL_FROM y UPDATES_EMAIL_FROM (para esta implementación, site.example.com); ver EMAIL.md
  • Si los recordatorios de inicio o los widgets de administración de Turnstile están habilitados, verifique que las claves públicas del sitio y los secretos coincidentes de Worker Turnstile estén configurados.
  • Implementar trabajador: wrangler deploy
  • Configurar el webhook de Stripe en el panel → https://worker.example.com/webhooks/stripe
  • [] Configure el webhook de entrega Resend → https://worker.example.com/webhooks/resend y configure RESEND_WEBHOOK_SECRET
  • Confirmar EMAIL_OUTBOX_ENABLED=true y PAYMENT_RECONCILIATION_ENABLED=true en el vivo Worker
  • [] Ejecute la verificación de optimización/manifiesto de medios e inspeccione las advertencias de referencias rotas del panel
  • Pruebe con una contribución real de $1

9. Referencia de secretos

Acciones de GitHub (Repositorio → Configuración → Secretos)

  • STRIPE_SECRET_KEY — Secreto en vivo de Stripe (sk_…)
  • CHECKOUT_INTENT_SECRET: secreto de HMAC para la firma de intención de pago
  • Utiliza GITHUB_TOKEN proporcionado automáticamente para confirmaciones

Trabajador de Cloudflare (wrangler o panel → Variables)

  • STRIPE_SECRET_KEY - igual que arriba
  • SITE_BASEhttps://site.example.com
  • WORKER_BASEhttps://worker.example.com
  • APP_MODElive o test
  • CHECKOUT_INTENT_SECRET: cadena aleatoria de más de 32 caracteres para firmar el pago
  • MAGIC_LINK_SECRET: cadena aleatoria de más de 32 caracteres para la firma de tokens HMAC
  • CAMPAIGN_PREVIEW_SECRET: secreto de firma de enlace de revisor de vista previa dedicado opcional; si se omite, el Trabajador recurre a los secretos de firma existentes
  • RESEND_API_KEY — Clave API Resend para correos electrónicos de soporte (re_…)
  • RESEND_WEBHOOK_SECRET — Secreto de firma Resend/Svix para eventos de entrega y supresión (whsec_…)
  • ADMIN_SECRET: cadena aleatoria para puntos finales de API de administración
  • ADMIN_SETTLEMENT_SECRET: secreto de administración de ámbito opcional para puntos finales de liquidación; use un valor solo local separado en worker/.dev.vars
  • ADMIN_BROADCAST_SECRET: secreto de administración de ámbito opcional para puntos finales de diario, hitos y anuncios; también agréguelo a los secretos del repositorio de GitHub para la verificación del diario posterior a la implementación cuando esté habilitado
  • CLOUDFLARE_API_TOKEN: para implementaciones de GitHub, use un token API de usuario de Cloudflare creado desde Mi perfil -> Tokens API con la plantilla Editar trabajadores de Cloudflare. Para exportaciones de informes locales, utilice un token KV de trabajadores de solo lectura cuando sea posible.
  • CLOUDFLARE_ACCOUNT_ID: ID de cuenta de Cloudflare para implementaciones de Wrangler, scripts de exportación/informe local no interactivo y configuración de tiempo de ejecución del trabajador -> Punto final de uso del plan
  • CLOUDFLARE_USAGE_API_TOKEN: token GraphQL Analytics de solo lectura opcional para la configuración del administrador -> Rastreador de uso del plan; agregue la detección automática del plan Billing Read for Workers y manténgalo separado de los tokens de implementación.
  • TURNSTILE_SECRET_KEY: Secreto compartido de Cloudflare Turnstile cuando el inicio de sesión de administrador o los widgets de recordatorio de inicio están habilitados
  • LAUNCH_REMINDER_TURNSTILE_SECRET_KEY — Secreto de torniquete específico de recordatorio opcional si no se utiliza el secreto compartido
  • LAUNCH_REMINDER_TOKEN_SECRET: secreto de token de cancelación de suscripción de recordatorio opcional; vuelve a MAGIC_LINK_SECRET
  • ABANDONED_CART_TOKEN_SECRET: token secreto opcional de recordatorio de pago abandonado para cancelar la suscripción y reanudar los enlaces; vuelve a MAGIC_LINK_SECRET
  • GITHUB_TOKEN: GitHub PAT con acceso a repositorio/flujo de trabajo para acciones de publicación del panel y activadores de reconstrucción; opcional solo cuando no estás probando la publicación respaldada por GitHub
  • ADMIN_BOOTSTRAP_EMAILS: lista de correo electrónico de superadministrador local/de recuperación opcional para iniciar sesión en el panel; El desarrollador local lee esto de worker/.dev.vars.
  • ADMIN_USERS_JSON: lista de usuarios administradores de inicialización/recuperación opcional reflejada desde _config.yml; Panel de control Las ediciones de los usuarios se guardan en KV en admin-users:v1.
  • CORS_ALLOWED_ORIGIN: debe coincidir con el origen del sitio para las solicitudes del panel del navegador; Podman local deriva esto para http://127.0.0.1:4000

Cloudflare KV

  • Espacio de nombres: PLEDGES: almacena datos de aportes y estadísticas agregadas.
    • Claves: pledge:{orderId} → aporte JSON
    • Claves: email:{email} → conjunto de ID de pedido
    • Teclas: stats:{campaignSlug}{ pledgedAmount, pledgeCount, tierCounts }
    • Claves: campaign-preview-reviewers:{campaignSlug} → Lista permitida de correo electrónico del revisor de vista previa protegida de 24 horas
  • Espacio de nombres: VOTES — Votos de la comunidad de tiendas
    • Claves: vote:{campaignSlug}:{decisionId}:{orderId} → cadena de opción
    • Claves: results:{campaignSlug}:{decisionId} → JSON {optionA: count, ...}

Panel de control de Stripe

  • Punto final del webhook = https://worker.example.com/webhooks/stripe
    • Eventos: checkout.session.completed
  • No se requiere catálogo de productos; los montos provienen de artículos del carrito propios canonizados por los trabajadores

Panel de control Resend

  • Dominio: Verifique la parte del dominio de las direcciones del remitente configuradas en _config.yml/Worker env. Para esta implementación, PLEDGES_EMAIL_FROM es The Pool <[email protected]>, por lo que Resend debe autorizar a site.example.com.
  • Clave API: Crear clave con permiso de “Acceso de envío”
  • Se utiliza para: todos los correos electrónicos de aporte dirigidos a los patrocinadores (confirmación, acceso a administración/comunidad, recordatorios de lanzamiento, recordatorios de pagos abandonados, actualizaciones del diario, correos electrónicos de Blast/anuncios, informes, éxito de los cargos, errores de pago, cancelaciones)
  • Nota del desarrollador local: incluso cuando SITE_BASE apunta a 127.0.0.1, las imágenes de correo electrónico incrustadas aún usan la base de recursos pública https://site.example.com, por lo que las vistas previas de la bandeja de entrada no muestran URL de imágenes de host local rotas.