OpenAthlete
AGPLv3 endurance training platform: EU-oriented hosting, transparent CTL/ATL/TSB logic in code, self-hosting, and full export. Built in Grenoble.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Racha de gimnasio a escala del universo. PWA en Next.js + Supabase + three.js. La especificación vive en CLAUDE.md (índice) y spec/ (por tema). CLAUDE.md es lo único que se lee siempre.查看完整 README ↗
Racha de gimnasio a escala del universo. PWA en Next.js + Supabase + three.js.
La especificación vive en CLAUDE.md (índice) y spec/ (por tema). CLAUDE.md es lo único que se lee siempre.
Supabase: crear un proyecto en supabase.com (región sa-east-1, São Paulo, es la más cercana).
En el SQL Editor del proyecto, pegar y ejecutar entero supabase/schema.sql. Eso crea tablas, triggers de racha, RLS y los buckets de storage.
En Authentication → Providers, activar Email y Google (para Google hay que cargar Client ID/Secret de Google Cloud Console).
En Authentication → URL Configuration:
http://localhost:3020 (cambiar a la URL de Vercel al deployar)http://localhost:3020/auth/callback — alta por correo y login con Googlehttp://localhost:3020/auth/recuperar — recuperar contraseñahttps://TU-APP.vercel.app cuando haya deploySi falta el de recuperar, el correo llega pero el enlace rebota al login.
Copiar .env.example a .env.local y completar con la URL y la anon key del proyecto (Settings → API).
npm install y npm run dev → http://localhost:3020
npx vercel link
npx vercel env add NEXT_PUBLIC_SUPABASE_URL
npx vercel env add NEXT_PUBLIC_SUPABASE_ANON_KEY
npx vercel --prod
npm run test:db
Corre supabase/schema.sql contra un Postgres real (PGlite, en WASM) con stubs
de lo que aporta Supabase, y verifica la matemática de racha, rangos, planeta del
día, pérdida (−10), días de descanso, permisos y políticas de RLS. No necesita
cuenta ni red. Correrlo después de tocar el schema.
npm run test:conexion
Chequeo de humo contra el Supabase real: confirma que .env.local está bien,
que el schema está aplicado y que nada queda abierto a usuarios sin sesión.
Solo lee; no crea ni modifica nada.
npm run test:e2e
Flujo completo contra el Supabase real con dos cuentas: alta, onboarding,
registrar días, escalera de rangos, fotos con visibilidad, amistad, reto,
pérdida de racha y el aislamiento del §4. Crea datos y los limpia al final.
Necesita E2E_EMAIL en .env.local y "Confirm email" apagado (ver abajo).
Cuando alguien manda una sugerencia, llega un mail. Usa Resend, el mismo servicio que después sirve de SMTP para Auth: se configura una sola vez.
Lo que hay que crear (todo en el navegador, no hace falta CLI):
[email protected], que solo entrega a tu
propia dirección — alcanza para las sugerencias, no para la beta.sugerencia-mail, y pegar el contenido de
supabase/functions/sugerencia-mail/index.ts.RESEND_API_KEY — la clave del paso 2MAIL_DESTINO — la casilla donde querés recibir las sugerenciasMAIL_REMITENTE — Ascent <[email protected]> (o el del dominio propio)WEBHOOK_SECRET — una cadena larga inventada, la que quierasfeedback, evento InsertPOSThttps://<proyecto>.functions.supabase.co/sugerencia-mail)x-ascent-secreto con el mismo valor del WEBHOOK_SECRETEse header es lo único que impide que cualquiera que descubra la URL nos haga mandar correos, así que no puede faltar.
Nada de esto está en el camino crítico hoy. El plan es terminar la web,
usarla el dueño solo una o dos semanas cazando bugs, pasarla a nativo con Expo,
y recién ahí marketing. Sin usuarios ajenos no hace falta ninguna de las cinco
cosas de abajo: el proyecto se queda en el plan Free, con "Confirm email"
apagado —que es lo que deja correr npm run test:e2e— y con las cuentas de
prueba como están.
Queda escrito acá porque el día que haya gente hay que hacerlo entero, y averiguarlo dos veces sale caro. Las primeras dos bloquean a las demás.
El SMTP de cortesía de Supabase da 2 correos por hora por destinatario y está pensado solo para probar. Con cinco testers se agota entre confirmaciones de alta y recuperaciones de contraseña, y la gente queda sin poder entrar.
Hace falta un dominio propio. Resend exige un dominio verificado para
mandar por SMTP; [email protected] solo entrega a la casilla del dueño de
la cuenta, así que sirve para las sugerencias y no para la beta. No se puede
verificar ascent-blush-seven.vercel.app: hay que tener un dominio y poder
tocarle el DNS. Sale ~10 USD/año y es lo único de toda la lista que cuesta
plata y depende de terceros (la propagación de DNS puede tardar horas).
Comprar el dominio y agregarlo en Resend → Domains → Add Domain.
Cargar en el DNS los registros que Resend muestra (DKIM y SPF, TXT y
MX), y esperar a que la fila quede en Verified.
En Supabase: Authentication → Emails → SMTP Settings → Enable Custom SMTP, y completar:
| Campo | Valor |
|---|---|
| Host | smtp.resend.com |
| Port | 465 |
| Username | resend |
| Password | la misma API key de Resend que usa la Edge Function |
| Sender email | una dirección del dominio verificado, p. ej. [email protected] |
| Sender name | Ascent |
El puerto 465 es TLS directo. Si el proveedor lo bloqueara, 587 también
sirve (ahí el cifrado se negocia con STARTTLS).
Guardar y probar con un "olvidé mi contraseña" a una casilla propia.
Está en Authentication → Sign In / Providers → Email → Confirm email. Se apagó para poder correr los tests.
Al prenderlo se rompe npm run test:e2e: crea cuentas con signUp y sigue
usándolas al toque, y con la confirmación activa esas cuentas no pueden entrar
hasta que alguien abra el correo. npm run capturas y npm run test:conexion
no se rompen: usan cuentas que ya existen y ya están confirmadas.
Orden correcto: primero el SMTP (paso 1), después esto. Al revés, las confirmaciones salen por el SMTP de cortesía y se cortan a los dos correos.
En el plan Free de Supabase NO hay backups automáticos. No es que estén apagados: no existen. Los backups diarios arrancan en el plan Pro (25 USD/mes), con 7 días de retención; el PITR es un add-on aparte y mucho más caro.
Dónde mirar el plan y los backups: Database → Backups en el panel. Si dice que no hay backups disponibles, el proyecto está en Free.
Desde el código no se puede comprobar: en .env.local solo hay la anon key, y
el estado del plan no se expone por PostgREST.
Las dos salidas, y hay que elegir una antes de que haya datos de otra
gente: pasar a Pro, o armar un dump periódico con supabase db dump (necesita
la contraseña de la base, que no está acá).
El JWT secret ya no se puede rotar. Supabase deshabilitó la rotación de las
llaves legacy (anon, service_role, JWT secret); el camino es migrar a las
llaves nuevas y desactivar las viejas, que deja la key expuesta sin efecto
igual. Conviene: es incremental en vez de un corte, y las legacy se deprecan a
fin de 2026 de todos modos.
Orden, en Settings → API Keys:
.env.local: NEXT_PUBLIC_SUPABASE_ANON_KEY pasa a la sb_publishable_….
Correr npm run test:conexion — el chequeo del rol de la clave hay que
ajustarlo, porque la nueva no es un JWT y no tiene role: anon adentro.sb_publishable_…, y
redesplegar. Las NEXT_PUBLIC_* se incrustan al compilar: sin deploy
nuevo, producción sigue con la vieja.sugerencia-mail: si lee SUPABASE_SERVICE_ROLE_KEY, pasarla
a la sb_secret_….feedback (Database → Webhooks): su definición
lleva la service_role key incrustada. Es el que filtró la llave; ver
spec/trampas.md.npm run test:conexion, npm run test:e2e y npm run capturas, que
son los tres que hablan con la base real.Ojo con un cambio de forma: las llaves nuevas van en el header apikey y no en
Authorization: Bearer. supabase-js lo maneja solo; cualquier curl a mano
que haya por ahí, no.
prueba_uno y prueba_dos. Conviene dejarlas, no borrarlas, porque las
usan tres cosas:
npm run capturas entra con prueba_uno (CONEXION_EMAIL en .env.local).
Sin ella no hay QA visual.npm run test:conexion le pide con esa cuenta el retrato de la base a
producción.npm run test:e2e no las usa: se crea las suyas y las borra.
Las claves ya se rotaron y viven solo en .env.local. Lo que falta es que se
noten como internas: ponerles un username que lo diga (ascent_qa_1) para
que ningún tester las encuentre en la búsqueda y les mande una solicitud.
Borrarlas recién cuando la beta termine.
test:e2e, es esperado).npm run test:e2e lo comprueba).supabase/schema.sql — todo el modelo de datos, triggers y políticas.src/motor/ — motor procedural de cuerpos celestes (shaders) + animación de subida de rango.src/app/ — pantallas: principal, social, álbum, datos, ajustes, login, onboarding.public/sw.js + manifest.webmanifest — PWA instalable.