Easy-to-manage touch screens
무료 오픈소스 터치스크린으로 USB 설정 가이드, 드래그‑드롭 편집기, 로컬 제어를 제공하며 Home Assistant용으로 제작되었습니다
베네수엘라에서 정확한 거리와 실제 리뷰, 사장과 직접 채팅으로 가까운 가게를 찾는다
La distancia exacta a cada negocio, reseñas reales y chat directo con el dueño. Descubre negocios cerca de ti en Venezuela.
라이프스타일TypeScript · PLpgSQLGitHub @mantoniorodriguez94-cmyk온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Directorio de negocios locales de Venezuela. Las personas encuentran negocios cerca, ven reseñas reales y escriben directo al dueño; los negocios consiguen visibilidad, contacto y promociones. En producción: appencuentra.com — se despliega solo desde la rama main vía Vercel. El build es la red de seguridad real: npm run dev tolera errores de tipos que build rechaza, y Vercel construye con build.README 전문 보기 ↗
Directorio de negocios locales de Venezuela. Las personas encuentran negocios cerca, ven reseñas reales y escriben directo al dueño; los negocios consiguen visibilidad, contacto y promociones.
En producción: appencuentra.com — se despliega
solo desde la rama main vía Vercel.
| Framework | Next.js 15 (App Router) · React 18 · TypeScript |
| Estilos | Tailwind CSS · framer-motion para overlays |
| Datos y sesión | Supabase (Postgres + Auth + Storage), con RLS |
| Correo | Resend |
| Pagos | PayPal, Binance Pay, y comprobantes manuales revisados a mano |
| Instalable | PWA |
npm install
cp .env.example .env.local # y completar los valores
npm run dev # http://localhost:3000
Antes de subir cualquier cambio:
npm run lint
npx tsc --noEmit
npm run build
El build es la red de seguridad real: npm run dev tolera errores de tipos que
build rechaza, y Vercel construye con build.
Las imprescindibles para que arranque:
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY # SOLO servidor — salta RLS, nunca exponer al cliente
NEXT_PUBLIC_APP_URL
Según lo que necesites: RESEND_API_KEY y RESEND_FROM_* (correo),
PAYPAL_* y BINANCE_PAY_* (cobros), ADMIN_SETUP_SECRET,
ADMIN_MASTER_PIN y ADMIN_PANEL_PASSWORD (panel), CRON_SECRET (limpieza
programada). La lista completa está en .env.example.
SUPABASE_SERVICE_ROLE_KEYsalta todas las políticas RLS. Sólo puede usarse en rutas de servidor (src/app/api/**, server components). Si aparece en un componente"use client", es un incidente de seguridad.
El esquema vive en dos sitios, con reglas distintas:
supabase/migrations/ — lo nuevo. Va numerado y en orden, así que se
sabe qué sigue a qué. Para que además quede registrado —en
supabase_migrations.schema_migrations, que es lo que permite saber qué
corrió sin adivinar— hay que aplicarlo con el CLI, y para eso falta enlazar
el proyecto:
supabase init # crea supabase/config.toml
supabase link --project-ref <ref> # el ref está en la URL del panel
supabase db push
Mientras no se haga, pegar las migraciones a mano en el editor funciona igual pero no deja registro, que es justo lo que se venía a resolver.
scripts/ — lo anterior. Se pega a mano en el SQL Editor y no deja
registro de nada. Está escrito para ser idempotente: correrlo dos veces no
rompe nada.
Todo cambio de esquema nuevo va como migración. scripts/ no se amplía.
De scripts/, los que tienen que estar sí o sí para que la app funcione
completa:
| Script | Para qué |
|---|---|
support-table.sql | Formulario de soporte y su bandeja en el panel |
panel-admin-control.sql | Moderación de reseñas, suspensión, reversión de pagos y auditoría |
ocultar-negocio.sql | Ocultar un negocio del directorio sin eliminarlo |
create-storage-bucket.sql | Bucket payment_receipts — debe quedar privado |
Para saber qué falta en una base concreta:
scripts/verificar-scripts-aplicados.sql. Solo lee, y devuelve una fila por
script con lo que falta cuando falta.
El bucket
payment_receiptscontiene comprobantes de pago: capturas de transferencias con nombres y números de cuenta. Tiene que seguir siendo privado; el panel genera URLs firmadas de una hora para mostrarlos.El script lo crea privado y, si lo encuentra abierto, lo cierra: pone
public = falsetambién cuando el bucket ya existe, y borra la política de lectura pública. Hasta el 25/09 hacía lo contrario —lo creaba conpublic = true— pese a este mismo párrafo tres líneas más arriba. La base de producción estaba privada, así que no llegó a hacer daño, pero quedaba armado para quien rehiciera el bucket.Para comprobar el estado de una base concreta:
scripts/verificar-scripts-aplicados.sql.
profiles.is_admin es la única fuente de verdad. No se lee
user_metadata.is_admin en ninguna decisión de permiso: ese campo lo puede
escribir el propio usuario desde el navegador, así que aceptarlo era una
escalada de privilegios directa.
Para conceder el rol se actualiza la fila directamente en Supabase. Había una
ruta /api/admin/set-admin para esto, sin autenticación y protegida sólo por
un secreto de instalación; se eliminó porque ya hay administrador y una puerta
así no tiene por qué seguir abierta. De todos modos llevaba tiempo sin
funcionar: leía ADMIN_SETUP_SECRET y la variable configurada se llama
ADMIN_SETUP_KEY.
update public.profiles set is_admin = true where email = '[email protected]';
Para comprobarlo:
select id, email, is_admin from public.profiles where email = '[email protected]';
Toda acción del panel que modere, suspenda o revierta queda registrada en
admin_audit_log y se consulta en Registro → Auditoría.
src/
app/
(public)/ páginas públicas anidadas (soporte, términos, privacidad)
app/auth/ registro, acceso, recuperación
app/dashboard/ la app con sesión
app/admin/ panel interno
api/ rutas de servidor
components/ui/ primitivas compartidas — Overlay, SectionHeader, BottomNav
lib/ lógica de dominio (membresías, navegación, auditoría)
scripts/ SQL, se ejecuta a mano en Supabase
docs/ guías de configuración de servicios externos
Dos convenciones que conviene respetar, porque se rompieron antes:
tailwind.config.ts y globals.css, nunca por
pantalla. Los colores de marca salen del logo; purple está remapeado a
magenta (promociones) y el dorado (amber) es el nivel Patrocina.En docs/: configuración de Google OAuth, PWA, cron de limpieza, PayPal,
sistema de afiliados, reclamo de negocios y pagos manuales.
El historial de git es el registro de qué cambió y por qué. Los mensajes de commit explican el motivo, no sólo el qué — antes eso vivía en un centenar de archivos markdown sueltos en la raíz que nadie actualizaba y que terminaron contradiciendo al código.