CleanFrame
삼성 The Frame용 개인 홈 화면, 포크와 맞춤을 위한 시작점
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Red social white-label multi-tenant para comunidades latinas en EE. UU. Cada tenant es un dominio propio con su marca (logo, color, módulos), sobre una única base de código y una única base de datos con aislamiento por RLS. Tenant piloto: dominicanos (Queens, NY).
El corazón del producto es el wedge de vivienda verificada anti-estafa: avisos de alquiler con Trust Score, Escudo Anti-Estafa (verificador + reportes comunitarios), mensajería con contacto protegido y guías SEO para recién llegados.
| Capa | Tecnología |
|---|---|
| Framework | Next.js 16 (App Router, src/, TypeScript estricto) |
| Estilos | Tailwind CSS v4 (tokens en globals.css vía @theme) |
| DB / Auth / Storage / Realtime | Supabase (Postgres 17, RLS FORCE en 23+ tablas) |
| Pagos | Stripe (Checkout + Identity + webhooks) |
| Resend | |
| IA | OpenAI (moderación omni-moderation + RAG con embeddings) |
| Observabilidad | Sentry |
| PWA | Serwist (service worker, offline) |
| Tests | Vitest + Testing Library |
Documentos rectores: docs/ARQUITECTURA.md (contrato técnico), docs/PLAN_MAESTRO.md (estrategia), docs/PROGRESS.md (estado), docs/investigacion/13-diseno-ux-premium.md (design system — rige tal cual).
npm install
cp .env.example .env.local # completar BLOQUE A como mínimo (ver docs/SETUP-ENV.md)
npm run dev # http://localhost:3000 (?t=<slug> para cambiar de tenant)
| Script | Qué hace |
|---|---|
npm run dev | Servidor de desarrollo (Turbopack; service worker deshabilitado en dev) |
npm run build | Build de producción — next build --webpack (Serwist necesita webpack para emitir public/sw.js) |
npm run start | Sirve el build de producción |
npm run test | Tests con Vitest |
npm run lint / npm run typecheck | ESLint / tsc --noEmit |
npm run check:rls | Enumerador RLS: verifica que ninguna tabla quede sin políticas (correr tras cada migración) |
npm run db:migrate | Aplica migraciones de supabase/migrations/ |
npm run db:seed | Siembra tenants demo + contenido de ejemplo |
npm run rag:embed | Genera embeddings del contenido para el asistente RAG (requiere OPENAI_API_KEY; lo agrega el módulo de IA) |
src/
├─ middleware.ts # Resolución de tenant por dominio + refresh de sesión Supabase
├─ app/
│ ├─ (marketing)/ # Landing pública + guías SEO
│ ├─ (auth)/ # Entrar, registro, onboarding
│ ├─ (app)/ # App autenticada: feed, propiedades, escudo, mensajes, perfil…
│ ├─ admin/ # Paneles global / dominio / moderación
│ └─ api/ # Webhooks (Stripe) + crons (protegidos con CRON_SECRET)
├─ components/ # ui/ (design system), trust/, listings/, feed/, shell/…
├─ lib/ # supabase/, tenant/, config/services.ts (degradación), rate-limit/, i18n/…
supabase/migrations/ # SQL versionado (RLS FORCE, triggers, RPCs)
scripts/ # rls-enumerator, seed, apply-migrations, generate-icons
Todo está documentado en .env.example (por bloques: A = imprescindible, B = antes del primer usuario real, C = puede esperar) y en docs/SETUP-ENV.md con el paso a paso de cada servicio.
Reglas de oro:
NEXT_PUBLIC_* se expone al navegador → jamás un secreto ahí.SUPABASE_SERVICE_ROLE_KEY, STRIPE_SECRET_KEY, OPENAI_API_KEY viven solo en el servidor.src/lib/config/services.ts): la feature muestra un estado premium "muy pronto", nunca un error crudo.tenant_id del JWT es la frontera real de aislamiento. npm run check:rls lo verifica.src/lib/rate-limit/, in-memory; migrar a Upstash con multi-instancia).next.config.ts: HSTS, X-Frame-Options: DENY, CSP (hoy en Report-Only; pasa a enforcing tras validar en staging).Según Plan Maestro §5.2 / §14.4 — el repo llega "listo para este gate", pero el gate lo cruza un humano:
package.json → next build --webpack, no lo pises)..env.example (Production + Preview).dominicanos.com) al proyecto — el middleware resuelve el tenant por Host.https://<dominio>/api/webhooks/stripe y cargar STRIPE_WEBHOOK_SECRET.api/cron/* exigen Authorization: Bearer ${CRON_SECRET}.| Slug | Dominio prod | Uso |
|---|---|---|
dominicanos | dominicanos.com | Tenant piloto (default en dev) |
comunidadlatina | comunidadlatina.com | Segundo tenant para probar white-label |
En dev: http://localhost:3000?t=comunidadlatina (queda en cookie cl-tenant).