Demand marketplace for production and installation of aluminum and glass systems.
AI translation
Marketplace de demanda para producción e instalación de sistemas de aluminio y vidrio.
CommerceTypeScript · CSSGitHub @DOUGLAS292OnlineOwner 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
Demand marketplace for production and installation of aluminum and glass systems — pilot v1
AI translation
Marketplace de demanda para producción e instalación de sistemas de aluminio y vidrio — piloto v1
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Marketplace de demanda para producción e instalación de sistemas de aluminio y vidrio — piloto v1 (Cali, lanzando a nivel nacional desde el día uno). Especificación completa del producto en docs/SPEC.md. Este no es el primer intento: DOUGLAS292/Backend_app y DOUGLAS292/frontend-conect fueron un prototipo previo (FastAPI + Supabase, HTML/Bootstrap plano, oct. 2025) sobre la misma idea. Se revisaron antes de arrancar este repo y se rescató lo reutilizable:Read the full README ↗
Marketplace de demanda para producción e instalación de sistemas de aluminio y vidrio — piloto v1 (Cali, lanzando a nivel nacional desde el día uno).
Especificación completa del producto en docs/SPEC.md.
Este no es el primer intento: DOUGLAS292/Backend_app y DOUGLAS292/frontend-conect
fueron un prototipo previo (FastAPI + Supabase, HTML/Bootstrap plano, oct. 2025)
sobre la misma idea. Se revisaron antes de arrancar este repo y se rescató lo
reutilizable:
lib/constants/proyectos.ts, reorganizadas
por nivel de complejidad.docs/SPEC.md §3, porque el modelo de datos de Enganche
(8 tablas, máquina de estados, comisión, garantías, geolocalización) es
bastante más amplio que el prototipo original.usuarios, publicaciones, postulaciones, mensajes,
calificaciones, comisiones, garantias
(ciudades_piloto existió hasta sept-2026, eliminada al cambiar el
periodo de gracia de "por ciudad" a "por usuario" — ver Fase 4)ST_DWithin / ST_Distanceelegida activo por publicación (índice único parcial)
- rating_promedio y trabajos_completados recalculados por triggernpm run migrate), sin dependencias pesadas/api/health para verificar la conexión a PostGIS/entrar
(celular → código de 6 dígitos) y /registro (perfil, solo para
celulares nuevos)AUTH_SECRET como pepper),
expiran a los 5 minutos, máximo 5 intentos, 60s de espera entre reenvíos
(tabla otps, migración 0012)usuarios.celular nunca se confía del cliente al crear la cuenta: sale
de una cookie firmada (JWT, 15 min) que solo existe tras pasar el OTPlib/auth/session.tslib/auth/whatsapp.ts.
Mientras no configures WHATSAPP_ACCESS_TOKEN, el código se imprime
en la consola del servidor y viaja en la respuesta de
/api/auth/otp/solicitar, para poder probar todo el flujo hoy mismo sin
esperar la aprobación de Meta.Pendiente de tu lado, no bloquea seguir con Fase 2: dar de alta un WhatsApp
Business Account en Meta Business Manager,
activar la Cloud API para un número, y crear + hacer aprobar una plantilla de
mensaje categoría "Authentication" (ej. enganche_otp, en español, con un
parámetro de cuerpo para el código). Ese proceso lo controla Meta y puede
tardar de horas a un par de días — no es algo que yo pueda hacer por ti. Con
WHATSAPP_ACCESS_TOKEN / WHATSAPP_PHONE_NUMBER_ID / WHATSAPP_OTP_TEMPLATE
puestos en .env (o en Vercel al desplegar), el envío real se activa solo,
sin tocar código.
/publicar — formulario de oferta (tipo de trabajo, nivel del sistema
con sugerencias de proyecto, cantidad, valor libre, entrega, ciudad) con
captura opcional de ubicación exacta (Geolocation API del navegador)/feed — pide tu ubicación al abrir y consulta con ST_DWithin /
ST_Distance (radio ajustable 2–50 km, default 10 km); si no hay
ubicación, cae a filtrar por ciudad escrita a mano — nunca deja al
usuario sin poder ver ofertas/publicaciones/[id] — detalle con reputación del autor (rating,
trabajos completados, verificado); postularse queda para Fase 3sa-east-1),
probado de punta a punta por Douglas: login, registro, publicar y ver
ofertas funcionando en enganche.vercel.appen_proceso y las demás postulaciones quedan
pendiente, no rechazadaselegida a la vez por publicación
(índice único parcial) — probado forzando el error contra la base realabierta, el elegido pasa a rechazada, y los demás
postulantes siguen disponibles sin tener que volver a postularse —
probado contra la base real, coincide exactamente con el spec/postulaciones — "Mis postulaciones" con el estado de cada unaPendiente para más adelante (no bloquea Fase 4): las notificaciones reales (push / WhatsApp) de "fuiste elegido" y "se reabrió la oferta" que pide el spec — hoy el cambio de estado ocurre correctamente en la base, pero avisar al usuario fuera de la app depende del mismo WhatsApp Business API que Fase 1 dejó pendiente de aprobación por Meta.
en_proceso) — genera la
comisión automáticamente, sin depender de que nadie califiquedocs/SPEC.md): el primer trabajo
completado de cada usuario le arranca 30 días sin comisión en toda la
plataforma, sin importar la ciudad; pasado ese plazo personal cobra el
3% normal — probado contra la base real: mismo usuario gratis en su
primer trabajo y cobrando en el segundo, en ciudades distintascompletada_en nuevo en publicaciones (migración 0013, ya aplicada
en producción) para poder contar los 30 días de garantíarating_promedio de Fase 0,
confirmado con datos reales (5 ★ → rating_promedio recalculado solo)trabajos_completados también se incrementa solo al completar
(trigger de Fase 0), sin código nuevo — confirmado con datos realesresponsable_pago_id) se marca "pagada" desde la
app; la confirmación final queda para el admin en Fase 5Pendiente para más adelante: notificaciones reales de "comisión pendiente
48h" y de reportes de garantía (mismo bloqueo de WhatsApp Business API de Fase 1); y el criterio exacto de cómo un
no_atendidoreduce reputación más allá de quedar registrado como dato — el spec lo deja como "insumo", sin fórmula, así que se define cuando haya casos reales.
usuarios.es_admin (migración 0014, ya aplicada en producción) —
marca a Douglas como el único admin del piloto/admin — vista de solo lectura de todas las comisiones (pendiente,
marcada pagada, confirmada), con totales por estado, ciudad, sistema
y el responsable de pago (nombre + celular)marcada_pagada → confirmada, con confirmada_en; probado contra
la base real (transición correcta, y no confirma dos veces la misma
comisión)usuario.es_admin;
/admin redirige a / si el usuario no es admin (o no hay sesión)Con esto cierra el plan de 5 fases del spec. Lo que queda pendiente es externo a la app: la aprobación de Meta para WhatsApp Business API (Fase 1), y las notificaciones push/WhatsApp reales que dependen de esa misma aprobación (mencionadas en Fase 3 y Fase 4).
Siguiente: por definir con Douglas — candidatos naturales son pulir UI/UX, notificaciones, o abrir el piloto a más usuarios reales en Cali.
Recomendado para el piloto: Supabase (gratis para empezar, PostGIS viene preinstalado, connection string lista en Project Settings → Database → Connection string → URI). Railway es la alternativa si prefieres eso.
cp .env.example .env
# completa DATABASE_URL con la connection string de Supabase/Railway
# genera y pega un AUTH_SECRET:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Deja WHATSAPP_* vacío por ahora — sin esas variables, el login funciona
igual en modo desarrollo (el código OTP sale en pantalla). Ver Fase 1 arriba.
npm install
npm run migrate # crea las 8 tablas + triggers + extensión PostGIS
npm run dev
Abre http://localhost:3000 — el botón "Verificar conexión a PostGIS" confirma
que DATABASE_URL y la extensión quedaron bien configuradas.
db/migrations/ Migraciones SQL numeradas (tablas, índices, triggers)
scripts/migrate.mjs Runner de migraciones (sin dependencias de ORM)
lib/db.ts Pool de conexión a Postgres (pg)
lib/auth/ OTP, sesión (JWT en cookie) y envío por WhatsApp
lib/validation/ Normalización de celular colombiano
lib/constants/ Listas de referencia para los formularios (Fase 2)
app/entrar/ Paso 1-2 del login: celular → código
app/registro/ Perfil, solo para celulares nuevos verificados
app/publicar/ Formulario de oferta (con ubicación opcional)
app/feed/ Feed por cercanía con filtros
app/publicaciones/[id] Detalle: postularse, elegir, reabrir, cancelar, cerrar
app/publicaciones/[id]/chat Chat 1-a-1 autor ↔ elegido
app/postulaciones/ "Mis postulaciones" del usuario
app/api/auth/ Rutas de login/registro/sesión
app/api/publicaciones/ Ofertas, postulación, cierre, comisión, garantías
app/admin/ Panel de comisiones, solo para usuarios.es_admin
app/api/admin/ Confirmar comisiones marcadas como pagadas
app/ Next.js App Router
docs/SPEC.md Especificación técnica completa del producto
npm run dev, abre http://localhost:3000/entrarWHATSAPP_ACCESS_TOKEN no está configurado, el código de 6 dígitos
aparece directo en la pantalla ("Modo desarrollo") — cópialo/registro a
completar el perfil; si ya existe, entra directo