Open-Source Cold Email & Warmup Platform
Warmbly is the open-source platform for cold email: warm your mailboxes, send campaigns, and triage every reply. Run it on our cloud or self-host the whole thing.
AMO — Advertising Market Optimization. Marketplace de pauta en medios hiperlocales.
Translation pending
MarketingTypeScript · PLpgSQLGitHub @AMO-Media-TeamOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Plataforma web que conecta anunciantes con medios hiperlocales de Colombia para contratar, ejecutar, medir y liquidar pauta digital de forma estandarizada. Este repositorio contiene el front-end (Next.js) y el esquema de la base de datos (Supabase).
Si vas a desarrollar con un agente de IA, empieza por
AGENTS.md.
supabase login) para regenerar tipos y aplicar migracionespnpm install
cp .env.example .env.local # completa las variables (cada una está documentada en el archivo)
pnpm dev # http://localhost:3000
| Variable | Uso |
|---|---|
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Conexión pública a Supabase |
SUPABASE_SECRET_KEY | Clave secreta (solo servidor): gestión de usuarios y procedimientos privilegiados |
NEXT_PUBLIC_MAPBOX_TOKEN, NEXT_PUBLIC_MAPBOX_STYLE | Mapas (restringe el token por URL) |
NEXT_PUBLIC_SITE_URL | URL pública del sitio (enlaces de invitación y recuperación) |
AMO_SERVIDOR_SECRET | Secreto compartido servidor ↔ base de datos (también guardado en Supabase Vault) |
AMO_CIFRADO_KEY | Clave de cifrado de datos sensibles (k1:<base64 de 32 bytes>) |
SUPERADMIN_EMAIL | Correo del primer superadministrador |
AMO_SMTP_CONFIGURADO | true cuando Supabase Auth tenga SMTP propio |
AMO_CSP_MODO | enforce (por defecto) o report |
El build falla con un mensaje claro si falta una variable obligatoria.
| Entorno | Supabase | Variables | Datos |
|---|---|---|---|
| Producción | oriuuuaczpncmtglfgpv (ca-central-1) | .env.produccion | Solo los reales (nació vacío) |
| Develop | depbmnlpfnrcsbqlwxxd (us-east-1) | .env.develop, .env.db.develop | Banco de pruebas antes de producción |
| Local | supabase start (Docker) | .env.local | 15 meses de demo y cuentas de prueba (pnpm db:local) |
.env.produccion (ignorado por git; Next no lo carga en local) contiene las variables que se importan
en Vercel. Los scripts de arranque apuntan a otro entorno con AMO_ARCHIVO_ENTORNO, p. ej.
AMO_ARCHIVO_ENTORNO=.env.produccion pnpm bootstrap:superadmin. Lo que crea datos de prueba (E2E,
cuentas de pista, demo, carrera de cupos) se niega a correr contra producción.
Las migraciones están en supabase/migrations/ y son inmutables. Para un proyecto nuevo (así se
montó producción):
postgres.<ref>, puerto 5432;
contraseña alfanumérica o codificada) en un archivo .env.db (git lo ignora). Con --linked no sirve: el CLI entra como
cli_login_* y las migraciones de roles y tarifas exigen session_user = 'postgres'.supabase db push --db-url "$SUPABASE_DB_URL" --skip-vault — las 45 migraciones, con catálogos,
permisos, geografía, buckets y procesos programados. Sin --include-seed: supabase/seed/demo
nunca va a producción.amo_servidor_secret con el mismo valor que AMO_SERVIDOR_SECRET (como
postgres: select vault.create_secret('<valor>', 'amo_servidor_secret')).supabase/tests/*.sql (todas en begin … rollback) antes de la purga: algunas usan el
anunciante de pruebas. humo_roles_permisos_aplicables exige un superadministrador activo y se corre
tras el primer ingreso; en una base recién montada, a02 de humo_bitacora_indice falla por
volumen, no por esquema (ver su cabecera).negocio_actores crea el anunciante de pruebas e2e00000-0000-4000-8000-00000000a001
(lo usan las suites SQL y E2E). En producción se purga como postgres en una transacción:
set local amo.modo_carga='on'; set local amo.purga='on'; select private.purgar_demo(); y se borra
su fila de la bitácora (entidad='anunciantes', entidad_id = ese id).pnpm db:types (o MCP generate_typescript_types).Un proyecto nuevo nace con registro abierto, enlaces de 1 h y Site URL en localhost: hazlos antes
de desplegar. Ruta base: https://supabase.com/dashboard/project/<ref>/….
<sitio>/auth/callback, <sitio>/auth/confirm y <sitio>/**.private.acceso_valido()).vercel.app como https://front-*-<equipo>.vercel.app
(el de las vistas previas de Vercel): cualquiera puede crear en Vercel un proyecto cuyo dominio
encaje con el patrón y recibir allí los enlaces de sesión. Las vistas previas no usan producción.AMO_ARCHIVO_ENTORNO=.env.produccion pnpm bootstrap:superadmin # en desarrollo, sin la variable
Imprime un enlace de un solo uso (vigente lo que diga «Email OTP Expiration»; vuelve a ejecutarlo si venció). Al abrirlo defines tu contraseña y configuras la verificación en dos pasos con una app autenticadora. Desde Administración → Usuarios se invita al resto de superadministradores.
Un superadministrador puede restablecer la verificación en dos pasos de cualquier persona desde Administración → Usuarios. Si quien la perdió es el único superadministrador, quien administra el servidor ejecuta:
AMO_ARCHIVO_ENTORNO=.env.produccion pnpm bootstrap:restablecer-mfa [correo] # en desarrollo, sin la variable
Sin correo usa SUPERADMIN_EMAIL. Antes de usar el enlace, comprueba que la primera línea nombre el
proyecto oriuuuaczpncmtglfgpv (producción). Borra los factores de esa cuenta, lo registra en la
bitácora e imprime un enlace de un solo uso para definir una contraseña nueva y configurar el nuevo
dispositivo.
La base incluye 15 meses de operación simulada (40 anunciantes, 300 medios, 5.396 asignaciones,
liquidaciones, facturas y accesos desde 15 países), toda marcada como es_demo, y una cuenta por rol
(demo.admin, demo.operaciones, demo.finanzas, demo.anunciante, demo.medio, todas
@amo.test; credenciales DEMO_* en .env.local).
Se genera en dos partes porque los interruptores de carga solo funcionan como propietario de la base
de datos: las cuentas con pnpm demo:generar usuarios y los datos ejecutando en orden los SQL de
supabase/seed/demo/. El detalle, y cómo purgarlos con pnpm demo:purgar, está en
supabase/seed/demo/README.md.
| Comando | Qué hace |
|---|---|
pnpm dev / pnpm build / pnpm start | Desarrollo, compilación y servidor de producción |
pnpm typecheck · pnpm lint · pnpm format | Tipos, ESLint y Prettier |
pnpm test · pnpm test:e2e | Pruebas unitarias (Vitest) y de extremo a extremo (Playwright) |
pnpm geo:build | Regenera GeoJSON optimizados, diccionarios y semilla geográfica |
pnpm brand:build | Regenera logos e iconos |
pnpm db:types · pnpm db:permisos | Tipos de la base de datos · semilla del catálogo de permisos |
pnpm bootstrap:superadmin · pnpm bootstrap:e2e | Superadministrador · cuentas de prueba |
pnpm test:e2e:navegadores | Matriz de navegadores: Firefox, Safari, Safari iOS y Chrome Android |
pnpm db:local · pnpm db:suites local | Base local (Docker) reconstruida con demo y cuentas E2E · suites SQL |
pnpm db:push <entorno> · pnpm db:respaldo <entorno> | Aplica migraciones (develop, luego producción) · respaldo previo |
pnpm prod:config-pruebas · pnpm prod:limpiar-pruebas | Configuración de prueba del cliente · limpieza final (simula por defecto; ejecutar solo por orden expresa) |
pnpm pruebas:rendimiento-geo local | p95 del explorador geográfico (< 300 ms) |
src/app/ Rutas: (auth) acceso · (app) secciones privadas · api
src/components/ ui (shadcn/Base UI), layout, data-table, charts, kpi, maps, brand, motion, feedback
src/features/ Un directorio por dominio: acciones, consultas, esquemas, componentes y pruebas
src/lib/ auth (DAL, permisos, navegación), supabase, geo, export, utilidades
scripts/ geo, brand, db, bootstrap, demo, pruebas
supabase/ migrations, seed, tests
e2e/ Playwright
docs/ Guía de desarrollo, modelo de datos, KPIs, geodatos, marca
public/data/geo/ GeoJSON optimizados (países, departamentos y municipios por departamento)
docs/guia-desarrollo.md — convenciones, stack y flujo de trabajodocs/chuleta-apis.md — patrones verificados del códigodocs/modelo-datos.md — tablas, seguridad, funciones, estados y permisosdocs/kpis.md — indicadores e insightsdocs/geodatos.md — mapas y diccionarios geográficosdocs/marca.md — identidad visualcontext/ (documentos del cliente) y .env.local no se versionan..env.produccion, solo para Production (marca como sensibles las secretas).
ENABLE_EXPERIMENTAL_COREPACK=1 hace que el build use [email protected] (packageManager). En
Preview no publiques la SUPABASE_SECRET_KEY de producción: o sin variables o con las de
desarrollo.vercel.json fija la región yul1 (Montreal), junto a la base de datos (ca-central-1).https://front-amo.vercel.app (sin quitar
http://localhost:3000). Sin esto el explorador del mapa recibe 403 en producción.https://front-amo.vercel.app. Si Vercel asigna otro, cámbialo en
NEXT_PUBLIC_SITE_URL (y vuelve a desplegar: se incrusta al compilar), en la Site URL y las
Redirect URLs de Supabase y en las restricciones del token de Mapbox.main despliega (a producción): las vistas previas están apagadas en el proyecto
(previewDeploymentsDisabled, Settings → Git). Sin los secretos de producción el build de
develop o feature/* fallaría a propósito en la validación de variables. Si un merge a main
no genera despliegue, créalo desde Deployments → Create Deployment con la rama main.AMO_SMTP_CONFIGURADO=true.AMO_CIFRADO_KEY y AMO_SERVIDOR_SECRET de producción en un gestor de contraseñas: sin
la clave de cifrado, los datos bancarios cifrados no se recuperan.Hecho al montar producción: base sin datos demo ni cuentas de prueba, secretos propios (distintos de los de desarrollo) y región junto a la base. Mientras siga en plan gratuito: el proyecto se pausa tras 7 días sin uso (se reactiva desde el panel) y no hay copias descargables.