Marketplace marca ↔ creator con pago protegido. Next.js + Supabase + S3.
68
Marketplace gestionado marca ↔ creator con pago protegido.
Contrata creadores de contenido con alcance, precio y plazo claros. El dinero queda en escrow hasta que la entrega es aprobada.
| Capa | Tecnología |
|---|---|
| Framework | Next.js 16 (App Router, standalone) |
| Auth / DB | Supabase (Postgres + Auth + Realtime) |
| Archivos | AWS S3 (portfolios, briefs, entregables) |
| Resend (OTP + notificaciones) | |
| Pagos | ManualEscrowProvider (escrow simulado, listo para Stripe) |
| Runtime | Node.js 22 Alpine — usuario no-root nextjs:nodejs |
La imagen no incluye base de datos. Postgres, Auth y Realtime viven en tu proyecto Supabase. Los archivos van a tu bucket S3. El contenedor es completamente stateless.
Antes de arrancar necesitás:
Proyecto Supabase → supabase.com · gratis en el plan Free
Anotá: Project URL, anon key y service_role key
Bucket AWS S3 → IAM user con permisos s3:PutObject, s3:GetObject
Anotá: región, bucket name, AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY
Migraciones SQL aplicadas al proyecto Supabase
Cloná el repo y ejecutá desde Supabase Dashboard → SQL Editor (o CLI):
git clone https://github.com/neogeeks/phainder.git
cd phainder
# Aplicar migraciones en orden:
# supabase/migrations/0001_*.sql → 0008_*.sql
.env# App
NEXT_PUBLIC_APP_URL=https://tu-dominio.com
NEXT_PUBLIC_SITE_URL=https://tu-dominio.com
NODE_ENV=production
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://XXXX.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
# AWS S3
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
AWS_S3_BUCKET=nombre-del-bucket
AWS_S3_SIGNED_URL_EXPIRES_IN=900
# Email (Resend)
RESEND_API_KEY=re_...
[email protected]
# Seguridad
PAYOUT_ENCRYPTION_KEY=genera-con-openssl-rand-base64-32
CRON_SECRET=genera-con-openssl-rand-hex-24
# Pagos (default: escrow simulado)
PAYMENT_PROVIDER=manual
NEXT_PUBLIC_PAYMENT_PROVIDER=manual
Generadores rápidos:
openssl rand -base64 32 # PAYOUT_ENCRYPTION_KEY
openssl rand -hex 24 # CRON_SECRET
docker-compose.ymlservices:
web:
image: neogeeks/phainder:latest
env_file:
- .env
environment:
NODE_ENV: production
ports:
- "0.0.0.0:3000:3000"
volumes:
- phainder_logs:/app/logs
- phainder_data:/app/data
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/"]
interval: 30s
timeout: 5s
retries: 3
start_period: 40s
volumes:
phainder_logs:
name: phainder_logs
phainder_data:
name: phainder_data
docker compose up -d
docker compose logs -f web
La app responde en http://localhost:3000 (o el dominio que configuraste).
| Variable | Requerida | Descripción |
|---|---|---|
NEXT_PUBLIC_APP_URL | ✅ | URL pública de la app (incluir https://) |
NEXT_PUBLIC_SITE_URL | ✅ | Igual a APP_URL (Supabase Auth redirect) |
NEXT_PUBLIC_SUPABASE_URL | ✅ | URL del proyecto Supabase |
NEXT_PUBLIC_SUPABASE_ANON_KEY | ✅ | Clave anon (pública) de Supabase |
SUPABASE_SERVICE_ROLE_KEY | ✅ | Clave service_role (nunca exponer al cliente) |
AWS_REGION | ✅ | Región del bucket S3 (ej. us-east-1) |
AWS_ACCESS_KEY_ID | ✅ | Access key IAM con permisos S3 |
AWS_SECRET_ACCESS_KEY | ✅ | Secret key IAM |
AWS_S3_BUCKET | ✅ | Nombre del bucket |
PAYOUT_ENCRYPTION_KEY | ✅ | Clave AES-256 para cifrar datos bancarios (≥32 chars) |
CRON_SECRET | ✅ | Secreto para autenticar cron jobs vía header Bearer |
RESEND_API_KEY | Recomendada | API Key de Resend para email transaccional |
RESEND_FROM_EMAIL | Recomendada | Dirección remitente verificada en Resend |
PAYMENT_PROVIDER | Opcional | manual (default) o stripe (PoC sandbox) |
STRIPE_SECRET_KEY | Solo si Stripe | sk_live_... o sk_test_... |
STRIPE_WEBHOOK_SECRET | Solo si Stripe | whsec_... del endpoint de Stripe |
AWS_S3_SIGNED_URL_EXPIRES_IN | Opcional | Expiración URLs firmadas en segundos (default: 900) |
WEB_PORT | Opcional | Puerto del host (default: 3000) |
Para que el login funcione con correo real (OTP de 6 dígitos):
Supabase Dashboard → Authentication → Email Templates → Magic Link
{{ .ConfirmationURL }} por {{ .Token }}Tu código de accesoAuth → Settings
https://tu-dominio.comhttps://tu-dominio.com/**SMTP personalizado (Resend) para evitar el rate limit (~2 emails/hora) del plan gratuito:
Authentication → SMTP Settings:
smtp.resend.com · Port: 465 · User: resend · Password: tu RESEND_API_KEYLa app expone 4 endpoints de cron que deben llamarse periódicamente. Autenticar con Authorization: Bearer $CRON_SECRET.
| Endpoint | Frecuencia recomendada | Función |
|---|---|---|
POST /api/cron/auto-approve | Cada hora | Auto-aprueba entregas vencidas |
POST /api/cron/order-reminders | Cada hora | Avisos 48h/24h antes del auto-approve |
POST /api/cron/publish-reviews | Diaria | Publica reseñas doble ciego |
POST /api/cron/reconcile-payments | Diaria | Concilia ledger vs pedidos |
Ejemplo con curl:
curl -X POST https://tu-dominio.com/api/cron/auto-approve \
-H "Authorization: Bearer $CRON_SECRET"
En VPS: agregar al crontab del sistema o usar un servicio como EasyCron / GitHub Actions schedule.
Ejemplo con Caddy (recomendado, TLS automático):
tu-dominio.com {
reverse_proxy localhost:3000
}
Ejemplo con nginx:
server {
listen 443 ssl;
server_name tu-dominio.com;
# ... certificados SSL ...
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}
}
| Volumen | Ruta en contenedor | Contenido |
|---|---|---|
phainder_logs | /app/logs | Logs de la aplicación |
phainder_data | /app/data | Datos locales del contenedor |
Los datos de negocio (usuarios, pedidos, ledger) nunca están en el contenedor: viven en Supabase. Los archivos (portafolios, briefs, entregables) van a S3.
docker compose pull
docker compose up -d
O forzar rebuild desde código fuente:
git pull
./actualiza-docker.sh
| Tag | Descripción |
|---|---|
latest | Última versión estable |
YYYYMMDD | Snapshot por fecha de build (ej. 20260817) |
Repositorio privado — ponteGEEK 2026.
Para reportar issues o solicitar acceso: contactar al equipo en pontegeek.com.
Content type
Image
Digest
sha256:64385d69a…
Size
69.8 MB
Last updated
about 1 month ago
docker pull neogeeks/phainder