Finalize Universify: fix breakages, wire recommendations, full theming, bot persistence, CI - #12
Merged
Merged
Conversation
- Remove the root 'install' lifecycle script that recursively re-invoked pnpm install (fork bomb on every fresh setup) - Replace removed 'expo export:web' with 'expo export --platform web' in build/vercel-build (SDK 54 dropped the webpack command) - Add outputDirectory and frozen lockfile to vercel.json - Guard the Supabase client so a missing .env no longer crashes bundling; export isSupabaseConfigured for offline demo mode - Fix duplicate 'private' key in discord bot package.json; add typecheck scripts and @types/node-fetch Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011nrgpkJbvZ9JCf2VA2kKvJ
RSVPs were written by updating events.rsvp_counts/attendees directly, but the events UPDATE policy only allows the organizer — every other user's RSVP silently matched zero rows and vanished on reload. - Migration 003: event_rsvps table (own-row RLS) with a SECURITY DEFINER trigger that keeps the denormalized aggregates on events in sync - Client: setRSVPAPI/fetchEventAPI; updateRSVP now writes the user's own row, refreshes authoritative aggregates, reverts on failure, and keeps local-only state in offline demo mode - addExternalEvents drops cross-source duplicates (title similarity + 2h window) via new utils/dedupe.ts Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011nrgpkJbvZ9JCf2VA2kKvJ
- Extract the recommendation engine into utils/recommendationEngine.ts (React-free, unit-testable); hooks re-export and wrap it - Add rankEventsForUser (interest profile + explicit categories + popularity ranking) and fix title normalization to be per-token so 'Late Night Chess' matches the mined 'chess' interest - Add utils/recurringEvents.ts: expand daily/weekly/monthly patterns into display occurrences with range clipping and month-length clamping - Add useEventReminders: browser notifications ~30min before scheduled events (web, opt-in preference) - FilterContext now exposes all six filter axes (date range, location, time of day, availability were implemented but unreachable) - 21 unit tests over dedupe, recurrence, layout, and the engine Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011nrgpkJbvZ9JCf2VA2kKvJ
- Real theming via useAppTheme + semantic palettes (light/dark/system, high-contrast variants, font-size scaling, reduced-motion) applied across every screen and component; removes ~70 hardcoded chrome colors - Home tab now shows engine-ranked recommendations (was random 20); calendar drag-selection shows top-5 suggestions for the time window - New /event/[id] detail page with RSVP; fixes dead My Activity links - FilterDrawer implements the Date Range / Time of Day / Location / Availability sections that previously said 'Coming soon' - Create form: recurring pattern (frequency/interval/end date) and flyer image URL; calendar renders recurring occurrences; cards and detail views show images and recurrence - Persist the Universify->Google Calendar event map so unschedule can delete the Google copy after a reload - Remove remaining committed debug telemetry from GoogleAuthContext and the OAuth callback; drop the misleading password-change UI (auth is Google-only); zero tsc errors and zero lint warnings Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011nrgpkJbvZ9JCf2VA2kKvJ
- Slack bot now persists parsed events to the shared events table (service-role client, graceful no-op without credentials); optional SLACK_REVIEW_CHANNEL posts Approve/Reject buttons before storing - Cross-source duplicate detection in both bots: title-token Jaccard similarity within a 2-hour start window, checked against nearby DB events before insert; Slack can escalate borderline pairs to an LLM via OPENROUTER_API_KEY - Add slack-bot .env.example and README; update Discord docs (submission is real now, pnpm not npm); drop unused moment-timezone dependency Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011nrgpkJbvZ9JCf2VA2kKvJ
- GitHub Actions: typecheck, lint, unit tests, and a credential-free web bundle build for the client; typecheck/syntax checks for both bots - README: status section now reflects what is really implemented, setup covers migration 003 and the new Slack env vars, structure/data-flow updated for dedupe + persistence + review flows - Client README: pnpm-based setup, real scripts, removed fabricated password demo accounts (auth is Google-only) - Mark the five stale summary documents as historical snapshots Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011nrgpkJbvZ9JCf2VA2kKvJ
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.
Brings the project to a finished, verified state across six commits.
Fixes
pnpm installfork bomb — the root"install": "pnpm install"lifecycle script recursively re-invoked itself on every fresh setup. Removed.expo export:webno longer exists on SDK 54;build/vercel-buildnow useexpo export --platform web, andvercel.jsonsetsoutputDirectory: dist.eventsrow, which RLS only allows for the organizer, so every non-organizer RSVP silently vanished on reload. Newevent_rsvpstable (own-row RLS) with aSECURITY DEFINERtrigger maintaining the aggregates onevents; client writes optimistically and reverts on failure. Requires runningsupabase/migrations/003_event_rsvps.sql.fetch()calls to a local debug ingest endpoint (one posted the OAuth callback URL)..envcrashed bundling — the Supabase client is now guarded; without credentials the app runs in offline demo mode on bundled data./event/:idlinks from Profile, misleading password-change UI (auth is Google-only), Google Calendar unschedule breaking after reload, Expo starter scaffold and other dead code.Features completed
useAppTheme(~70 hardcoded chrome colors removed)./event/:id) with RSVP, recurring events (daily/weekly/monthly with interval/end date, expanded into calendar occurrences), and URL-based flyer images.eventstable (service-role), with an optionalSLACK_REVIEW_CHANNELApprove/Reject flow mirroring Discord's review workflow.Infrastructure & docs
Verification
tsc --noEmit: 0 errors (client + slack-bot) ·expo lint: 0 errors, 0 warnings · unit tests: 21/21 · web export succeeds without credentials · Discord bot files passnode --check.Not implemented (needs external infrastructure, documented in README): email delivery, native push, Instagram scraping.
🤖 Generated with Claude Code
https://claude.ai/code/session_011nrgpkJbvZ9JCf2VA2kKvJ
Generated by Claude Code