A mock social network built for Inner Circle Rol's TTRPG campaigns. Players interact in-character through a Twitter/X-style platform, and the GM can create and "possess" NPC profiles to drive the narrative. Spanish-language UI.
- Framework: Next.js 16 (App Router, TypeScript)
- UI: React 19, Tailwind CSS 4 + shadcn/ui (New York style)
- Backend: Supabase (Postgres, Auth, Realtime, Storage)
- Auth: Google OAuth + Email/Password
- State: TanStack React Query 5
- Testing: Vitest + React Testing Library + happy-dom
- Icons: Lucide React
- PWA: Installable via web manifest + service worker
- Post creation (280 char limit) with up to 4 image uploads
- Infinite scroll feeds (Home, Explore)
- Threaded replies with vertical connector lines and chronological ordering
- Likes, replies, reposts, bookmarks
- Follow/unfollow users
- User profiles with avatar/banner
- Trigram-based search for posts and profiles
- Onboarding flow for new users (username + display name setup)
- NPC profiles: GM-created characters that admins can "possess" to post, like, and follow as — bringing the campaign world to life on the timeline
- Admin role (GM): edit/delete any post, manage user roles, create and control NPCs
- Dark/light theme (dark by default)
- PWA: installable via web manifest
- Responsive: desktop 3-column layout, mobile bottom nav
pnpm installGo to supabase.com and create a new project.
Run each migration file in order in the Supabase Dashboard SQL Editor:
supabase/migrations/001_initial_schema.sql— profiles, posts, likes, follows, bookmarks, notifications, storage buckets, RLSsupabase/migrations/002_search_indexes.sql— trigram search indexessupabase/migrations/003_onboarding_flag.sql— onboarding flow supportsupabase/migrations/004_npc_profiles.sql— NPC profiles and possession system
Or, if using the Supabase CLI locally:
pnpm run db:start
pnpm run db:resetIn Supabase Dashboard > Authentication > Providers > Google:
- Enable Google provider
- Add your Google OAuth client ID and secret
- Set redirect URL to
http://localhost:3000/auth/callback
Copy .env.local.example to .env.local and fill in your Supabase credentials:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-publishable-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-keypnpm run devOpen http://localhost:3000.
After creating your account, run this SQL in the Supabase Dashboard to grant GM privileges:
UPDATE profiles SET role = 'admin' WHERE username = 'your_username';This gives you access to the admin dashboard where you can manage NPCs, moderate posts, and control user roles.
| Script | Command | Description |
|---|---|---|
dev |
next dev |
Start dev server |
build |
next build |
Production build |
start |
next start |
Serve production build |
lint |
eslint |
Run linter |
typecheck |
tsc --noEmit |
Type checking |
format |
prettier --write . |
Format code |
db:start |
supabase start |
Start local Supabase |
db:stop |
supabase stop |
Stop local Supabase |
db:reset |
supabase db reset |
Reset DB and run all migrations |
db:status |
supabase status |
Show Supabase status |
test |
vitest run |
Run tests |
test:watch |
vitest |
Run tests in watch mode |
test:coverage |
vitest run --coverage |
Run tests with coverage |
src/
├── app/
│ ├── (auth)/ # Login, register
│ ├── (main)/ # Authenticated pages
│ │ ├── admin/ # GM dashboard + NPC management
│ │ ├── bookmarks/ # Bookmarked posts
│ │ ├── explore/ # Search + all posts feed
│ │ ├── settings/ # User settings
│ │ └── [username]/ # Profile + post thread
│ ├── (onboarding)/ # Username setup for new users
│ └── auth/callback/ # OAuth callback
├── components/
│ ├── auth/ # Login/register forms
│ ├── layout/ # Sidebar, mobile nav, right panel
│ ├── post/ # PostCard, PostComposer, PostFeed, PostThread
│ ├── profile/ # ProfileHeader, ProfileTabs, FollowButton
│ ├── providers/ # Auth, Query, Theme, SW providers
│ ├── shared/ # EmptyState, LoadingSkeleton
│ └── ui/ # shadcn/ui components
├── hooks/ # Custom React hooks (posts, likes, follows, search, NPCs)
├── lib/ # Utilities, types, Supabase clients
├── test/ # Shared test utilities (mocks, wrappers, fixtures)
└── proxy.ts # Auth proxy (session refresh, route protection)
pnpm run build
pnpm start