A searchable knowledge-sharing platform for software development fellowship cohorts.
Fellows ask questions in class group chats where answers get buried, the same questions are asked repeatedly across cohorts, and good answers disappear into chat history. Some fellows are uncomfortable asking questions publicly in large groups.
We surveyed 7 fellows across the Web Development and Data Analytics tracks (mix of 3–6 month and 6+ month/alumni tenure). Key findings:
- The pain is real, not assumed. All 7 respondents currently get help through class group chat, DMing a mentor, or asking a peer privately — and 66.7% said they've asked a question they later realized had already been answered in the group.
- Chat history doesn't work as a knowledge base. 57% of respondents said they "often" or "almost always" struggle to find a past answer in chat history, and named questions like "difference between const and let" and "how is software developer think" as things asked more than once.
- Fear, not laziness, keeps people from asking. 71.4% have held back from asking a question publicly at least once. Of those, the top reasons were fear of looking "stupid" (50%), the chat moving too fast (33.3%), and a preference for privacy (33.3%).
- Demand for the actual solution is strong. 85.7% said they'd be "likely" or "very likely" to search a knowledge base before asking in chat, and every single respondent (100%) picked "search by keyword/topic" as a must-have feature, followed by mentor-verified answers (71.4%) and answer notifications (42.9%).
- There's a starting pool of content. 2 fellows volunteered to contribute seed questions this week, most estimating they could realistically write 1–3 starter questions each — useful for seeding the knowledge base before demo day.
- Fellows most want existing answers for frontend topics (HTML/CSS/JS/React), soft skills/career/interview prep, and fellowship process questions — each named by 50% of respondents.
| Survey | Charts |
|---|---|
| Communication Channels & Repetitive Questions | ![]() |
| Question Hesitation & Barriers | ![]() |
| Chat History Search Struggles | ![]() |
Study Circle provides a searchable knowledge base where fellows can:
- Ask questions with titles, detailed bodies, and tags
- Search existing questions and answers
- Comment on posts
- Upvote helpful content
study-circle/
├── public/
│ └── screenshots/ # Survey dashboard images
├── src/
│ ├── app/
│ │ ├── (auth)/ # Sign in / Sign up pages
│ │ ├── (dash)/ # Protected pages (dashboard, discussions, profile, settings)
│ │ ├── coming-soon/ # Placeholder page
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Landing page
│ ├── components/
│ │ ├── Dashboard/ # Dashboard KPIs and charts
│ │ ├── Discussions/ # Post creation, cards, search and filtering
│ │ ├── LandingPage/ # Public landing page sections
│ │ ├── auth/ # Authentication layouts
│ │ ├── layout/ # Navbar and Sidebar components
│ │ ├── providers/ # TanStack Query provider
│ │ └── ui/ # Reusable UI components
│ ├── hooks/
│ │ ├── useDebounce.ts
│ │ ├── useLocalStorage.ts
│ │ └── usePagination.ts
│ ├── lib/
│ │ ├── dashboard-data.ts
│ │ ├── env.ts
│ │ ├── utils.ts
│ │ └── supabase/
│ │ ├── client.ts # Browser client
│ │ ├── middleware.ts # Auth middleware helpers
│ │ └── server.ts # Server client
│ ├── services/ # Data fetching and mutations
│ │ ├── comments.ts
│ │ ├── dashboard.ts
│ │ ├── postDetail.ts
│ │ ├── posts.ts
│ │ └── profile.ts
│ └── types/
│ ├── auth.ts
│ ├── database.types.ts # Generated Supabase types
│ ├── post.ts
│ └── profile.ts
├── supabase/
│ ├── README.md # Migration file guide
│ └── migrations/
├── .env.example # Environment variable template
├── eslint.config.mjs
├── next.config.ts
├── package.json
├── postcss.config.mjs
├── README.md
├── tailwind.config.ts
└── tsconfig.json
- Framework: Next.js 15 with App Router
- Language: TypeScript
- Styling: Tailwind CSS with custom design tokens
- Backend: Supabase (PostgreSQL, Auth, Realtime)
- Validation: React Hook Form + Zod
- profiles — Public user data linked to auth.users (with role and bio)
- posts — Knowledge base entries with full-text search
- comments — Threaded discussions on posts
- votes — Upvotes on posts and comments (XOR constraint)
- notifications — User notifications for role requests and approvals
- bookmarks — Saved posts per user
- reports — User reports for moderation
- UUIDs for all primary keys (security, distribution)
- Full-text search with tsvector/GIN index (not ILIKE)
- Partial unique indexes for one-vote-per-user-per-target
- RLS on all tables (never disabled)
Study Circle supports three user roles:
| Role | Description |
|---|---|
| Fellow | Default role. Can create posts, comment, and vote. |
| Mentor | Approved contributors with mentor badge on posts/comments. |
| Admin | Manages user roles from Admin Panel. |
Fellows can request mentor status from Settings. Admins approve from Admin Panel.
Supabase Auth with email/password. Profiles auto-created via trigger on auth.users insert.
Authentication credentials (email, hashed password) are stored exclusively in Supabase's managed auth.users table, not in our application schema. Our profiles table only stores non-sensitive public information. This separation ensures we never handle or store passwords in our application code.
- User signs up via
supabase.auth.signUp()→ row created inauth.users - Database trigger automatically creates matching row in
public.profiles - User logs in → Supabase returns JWT containing user UUID
- JWT stored in secure HTTP-only cookie
- Every API request includes JWT →
auth.uid()extracts user UUID - RLS policies use
auth.uid()to enforce ownership rules
PostgreSQL full-text search using:
tsvectorgenerated from title (weight A), body (weight B), tags (weight C)- GIN index for performance
ts_rank()for relevance ordering- Combined with tag filtering via
ANY(tags)
Row Level Security enabled on all tables:
- Public read access for posts and comments
- Authenticated users can only modify their own content
- Vote uniqueness enforced at database level
- Post authors can moderate comments on their posts
Study Circle includes tools for content and user management:
- Report User — Fellows can report inappropriate behavior from Settings
- Suspend User — Admins can suspend accounts from Admin Panel
- Content Moderation — Admins can delete any post or comment
- Role Management — Admins can promote fellows to mentors
git clone https://github.com/iotb-tech/study-circle.git
cd study-circlenpm installNEXT_PUBLIC_SUPABASE_URL=your-supabase-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-keynpm run devStudy Circle uses TanStack Query for server-state management and data fetching.
- Automatic caching for improved performance
- Background refetching when data changes
- Built-in loading and error handling states
- Query invalidation after mutations (posts, comments, votes, profile updates)
- Reduced duplicate API requests across pages
The QueryProvider is configured at the application level so all pages and components can access query state consistently.
mainbranch is protected and all development go throughdevbranch- Feature branches for all work
- PRs require review before merge
- Conventional commits (
feat:,chore:,fix:,docs:)
Database migrations live in supabase/migrations/. Apply them via Supabase SQL Editor in order.
01_first_schema.sql02_seed_data.sql03_avatars_bucket04_user_roles_and_bio.sql05_fix_notifications_rls.sql06_admin_update_policy.sql07_bookmarks.sql08_add_email_to_profiles.sql09_delete_user_function.sql10_admin_content_moderation.sql11_user_reports.sql12_suspend_user.sql
Before running seed-data.sql:
- Create 3 test users via the signup page
- Get their UUIDs from Supabase → Authentication → Users
- Replace
USER_1_ID,USER_2_ID,USER_3_IDin the seed file with your actual UUIDs - Replace
'Person A','Person B','Person C'with your actual display names - Run in Supabase SQL Editor
See supabase/migrations/README.md for detailed instructions.


