Claude/cpp ceti social system rq8c98 eod4ds - #11
Merged
Conversation
…grafo social canónico Fase 1: - AcademicCampus/Program/Offering + catálogo CETI seedeado idempotente - Perfil académico (offering/semester/group) con invariantes CHECK en Postgres - Username OAuth provisional de alta entropía (no derivado del email) + confirmOAuthUsername one-shot + bypass puntual de cookie cache - Helper safeInternalRedirect + redirectTo preservado en login/registro - Fix del bug de actividad: getUserLessonActivity(actorId) separado de getFriendsActivityFeed(viewerId) — el perfil de A ya no muestra amigos de A - Privacidad: perfiles con usernameSetupRequired=true ocultos a terceros Fase 2: - Friendship.pairKey canónico + FriendshipPeriod (historia) + índice único parcial para "un solo período abierto por par" - FriendRequestSource + InviteAttribution (cookie firmada first-touch, 30 días, consumida en alta nueva vía databaseHooks.user.create.after) - Discovery: 5 buckets exactos vía SQL parametrizado con CTEs, keyset pagination firmada, context token firmado por candidato - Mutual friends normalizado en SQL (sin N+1) - Scripts de backfill (pairKey + legacy XP) validados contra PostgreSQL real, idempotentes Infraestructura de tests: - vitest.integration.config.ts + tests/integration/** contra Postgres real para invariantes que un fake no puede reproducir fielmente (índice único parcial, constraints) - XP ledger (XpAward) wireado en los tres call-sites de otorgamiento de XP existentes (completeStep, submitExercise, submitPracticeExercise); UserStreak.totalXp queda como contador materializado Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018XQFppGcovvjRoHZyQa6GF
- SocialEvent + Kudos: hitos (unit_completed, course_completed, streak_milestone) emitidos idempotentemente dentro de la misma transacción del hecho de dominio (completeStep/submitExercise, awardXpAndUpdateStreak) - checkUnitAndCourseCompletion: detecta primera vez que se completa una unidad/curso sin N+1 (una sola lectura de las lecciones publicadas del curso) - Feed fanout-on-read (self + amigos accepted actuales) — un unfriend/block hace desaparecer los eventos de esa persona de inmediato, sin borrar nada - Kudos: no propio, duplicado no-op, sólo remove propio - UI: pestañas "Descubrir" y "Actividad" en /app/amigos, reutilizando componentes existentes (FriendAvatar, Tabs) - Invite attribution consumida vía databaseHooks.user.create.after (sólo alta nueva, nunca login) + cookie first-touch capturada desde /invitar/[username] - ProductEvent nuevos (discovery_impression, discovery_profile_open) con props validados por Zod, sin username/id de candidato ni datos académicos - Tests de integración contra Postgres real: dedupe de milestones, desaparición inmediata del feed tras unfriend, doble-click de kudos Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018XQFppGcovvjRoHZyQa6GF
Fase 4: - Ranking semanal de amigos (self + accepted, TODOS incluidos aunque tengan 0 XP) y standings de liga por división, ambos sobre XpAward competitivo (legacy_balance excluido) - League rollover: Serializable + advisory lock global, claim atómico open→closing (dos workers concurrentes → sólo uno rueda), formación de divisiones balanceadas (divisionCount=max(1,round(N/20))), promoción top5/bottom5 (N<10: floor(N/2)), Bronze floor / Diamond ceiling, frontera exacta de earnedAt, entrantes midweek, finalXp=0 no se pre-asigna - Bootstrap de la primera season en el PRÓXIMO lunes (nunca a mitad de semana) — ninguna season cubre una semana parcial Fase 5 — Friend Streak: - createFriendStreakRequest/acceptFriendStreakRequest con pg_advisory_xact_lock por usuario (orden canónico) — capacidad ≤3 activas / ≤3 pendientes salientes revalidada de ambos lados - refreshFriendStreakDay: actividad server-authoritative (lección completada O intento calificado de reto/práctica), updateMany condicionado por lastEvaluatedDay (sin locks explícitos, idempotente ante reintento/doble refresh), breakOnMiss distingue refresh en vivo de HOY vs. el job evaluando AYER - endFriendStreakForPair: unfriend/block cierra en la misma operación, current=0, longest se conserva; reamistad reutiliza el par canónico - StreakReminder: elegibilidad estricta (sender estudió, recipient no), límites (1/día/streak, 3/día/sender, rate limit de endpoint) - UI: pestaña "Rachas" en /app/amigos (streak cards + banners de recordatorio), botón "Iniciar racha" en el perfil de un amigo 26 tests de integración contra PostgreSQL real (constraints, locks, concurrencia genuina) + 475 tests unitarios, todos verdes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018XQFppGcovvjRoHZyQa6GF
Fase 6 — Friend Quests: - Matching semanal: candidatos con actividad significativa en 14d Y >=1 lección la semana previa; edges ordenados por diferencia de ritmo, no-repetir-pareja, pairKey; greedy — nunca empareja inactivo con activo - 1 quest/usuario/semana vía UNIQUE(userId, weekStart); progreso cuenta lecciones de AMBOS aunque sean de cursos distintos; target=12 fijo - Transición active→completed condicional (updateMany) — sólo la llamada ganadora emite friend_quest_completed, sin XP reward (v1) Jobs: - /api/jobs/social-maintenance — UNA superficie protegida por CRON_SECRET (Bearer, formato Vercel Cron), ejecución horaria (vercel.json). Corre rollover de liga + entrantes midweek + expiración de streaks pendientes + evaluación diaria de streaks + matching/expiración de quests. Cada sub-tarea es independiente e idempotente; un fallo no tumba las demás. UI: - /app/liga: tier, rank, top3, cercanos (±2), zonas de promoción/descenso, clasificación completa bajo demanda - Nav: Inicio/Práctica/Liga/Amigos/Perfil (mobile + desktop); Logros pasa a vivir dentro de Perfil; /app/logros queda como redirect permanente - Ranking semanal de amigos en /app/amigos - Identidad académica: editor cascada plantel→carrera→semestre→grupo en Perfil, visible en el perfil público (campus/carrera/semestre a cualquier autenticado, grupo exacto sólo self/amigo), prompt "Encuentra a tus compañeros" en Home (después del ContinuePanel, descartable) - Contexto social compacto en Home: liga, rachas activas, quest de la semana — nunca un dashboard 30 tests de integración + 475 unitarios, todos verdes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018XQFppGcovvjRoHZyQa6GF
…es deshabilitadas)
getPublicProfile ahora corta antes de construir el DTO cuando el viewer
está bloqueado por el dueño del perfil: devuelve null (→ 404), en vez de
un perfil completo con el botón de amistad deshabilitado. Esto es lo que
pide <privacy> del contrato ("Blocked-by-target: notFound y exclusión
total") — la versión anterior filtraba nombre/avatar/bio/stats al
bloqueado, sólo le escondía el botón de agregar.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XQFppGcovvjRoHZyQa6GF
Vercel's current plan doesn't support hourly cron frequency. Remove the crons entry from vercel.json and add a dedicated GitHub Actions workflow (schedule + workflow_dispatch) that makes an authenticated HTTPS request to /api/jobs/social-maintenance, which still owns all the maintenance logic. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013dA2QiVhmuKxQsAmyZwhbt
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
CesarManzoCode
deleted the
claude/cpp-ceti-social-system-rq8c98-eod4ds
branch
September 5, 2026 00:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.