Sign inSign up

neogeeks/phainder

By neogeeks

Updated about 1 month ago

Marketplace marca ↔ creator con pago protegido. Next.js + Supabase + S3.

Image
0

68

neogeeks/phainder repository overview

Phainder

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.


Stack

CapaTecnología
FrameworkNext.js 16 (App Router, standalone)
Auth / DBSupabase (Postgres + Auth + Realtime)
ArchivosAWS S3 (portfolios, briefs, entregables)
EmailResend (OTP + notificaciones)
PagosManualEscrowProvider (escrow simulado, listo para Stripe)
RuntimeNode.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.


Requisitos previos

Antes de arrancar necesitás:

  1. Proyecto Supabasesupabase.com · gratis en el plan Free
    Anotá: Project URL, anon key y service_role key

  2. 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

  3. 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
    

Inicio rápido

1. Crear el archivo .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
2. docker-compose.yml
services:
  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
3. Arrancar
docker compose up -d
docker compose logs -f web

La app responde en http://localhost:3000 (o el dominio que configuraste).


Variables de entorno — referencia completa

VariableRequeridaDescripción
NEXT_PUBLIC_APP_URLURL pública de la app (incluir https://)
NEXT_PUBLIC_SITE_URLIgual a APP_URL (Supabase Auth redirect)
NEXT_PUBLIC_SUPABASE_URLURL del proyecto Supabase
NEXT_PUBLIC_SUPABASE_ANON_KEYClave anon (pública) de Supabase
SUPABASE_SERVICE_ROLE_KEYClave service_role (nunca exponer al cliente)
AWS_REGIONRegión del bucket S3 (ej. us-east-1)
AWS_ACCESS_KEY_IDAccess key IAM con permisos S3
AWS_SECRET_ACCESS_KEYSecret key IAM
AWS_S3_BUCKETNombre del bucket
PAYOUT_ENCRYPTION_KEYClave AES-256 para cifrar datos bancarios (≥32 chars)
CRON_SECRETSecreto para autenticar cron jobs vía header Bearer
RESEND_API_KEYRecomendadaAPI Key de Resend para email transaccional
RESEND_FROM_EMAILRecomendadaDirección remitente verificada en Resend
PAYMENT_PROVIDEROpcionalmanual (default) o stripe (PoC sandbox)
STRIPE_SECRET_KEYSolo si Stripesk_live_... o sk_test_...
STRIPE_WEBHOOK_SECRETSolo si Stripewhsec_... del endpoint de Stripe
AWS_S3_SIGNED_URL_EXPIRES_INOpcionalExpiración URLs firmadas en segundos (default: 900)
WEB_PORTOpcionalPuerto del host (default: 3000)

Configuración Supabase Auth (OTP)

Para que el login funcione con correo real (OTP de 6 dígitos):

  1. Supabase Dashboard → Authentication → Email Templates → Magic Link

    • Cambiar {{ .ConfirmationURL }} por {{ .Token }}
    • Subject: Tu código de acceso
  2. Auth → Settings

    • Site URL: https://tu-dominio.com
    • Redirect URLs: https://tu-dominio.com/**
  3. SMTP personalizado (Resend) para evitar el rate limit (~2 emails/hora) del plan gratuito:
    Authentication → SMTP Settings:

    • Host: smtp.resend.com · Port: 465 · User: resend · Password: tu RESEND_API_KEY

Cron jobs

La app expone 4 endpoints de cron que deben llamarse periódicamente. Autenticar con Authorization: Bearer $CRON_SECRET.

EndpointFrecuencia recomendadaFunción
POST /api/cron/auto-approveCada horaAuto-aprueba entregas vencidas
POST /api/cron/order-remindersCada horaAvisos 48h/24h antes del auto-approve
POST /api/cron/publish-reviewsDiariaPublica reseñas doble ciego
POST /api/cron/reconcile-paymentsDiariaConcilia 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.


Detrás de un proxy (HTTPS)

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;
    }
}

Volúmenes

VolumenRuta en contenedorContenido
phainder_logs/app/logsLogs de la aplicación
phainder_data/app/dataDatos 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.


Actualizar a la última versión

docker compose pull
docker compose up -d

O forzar rebuild desde código fuente:

git pull
./actualiza-docker.sh

Tags disponibles

TagDescripción
latestÚltima versión estable
YYYYMMDDSnapshot por fecha de build (ej. 20260817)

Código fuente y licencia

Repositorio privado — ponteGEEK 2026.
Para reportar issues o solicitar acceso: contactar al equipo en pontegeek.com.

Tag summary

Content type

Image

Digest

sha256:64385d69a

Size

69.8 MB

Last updated

about 1 month ago

docker pull neogeeks/phainder