Skip to content

Repository files navigation

StudyOS

A study dashboard for tracking subjects, tasks (with subtasks), notes, weekly planning, focus sessions, and analytics.

Stack

  • React 19 + TypeScript + Vite
  • Tailwind CSS
  • React Router 7
  • Supabase (auth + cloud data persistence)

Getting started

npm install
npm run dev

Scripts

Command Description
npm run dev Start the dev server
npm run build Typecheck + production build
npm run preview Serve the production build
npm run lint ESLint
npm run typecheck TypeScript check
npm test Build + Playwright smoke tests (Phase 1)

Two modes

StudyOS works without any backend:

  • Local-only mode — default. Set no env vars: everything is stored in localStorage via DataProvider, and auth screens are not enforced.
  • Authenticated mode — copy .env.example to .env and fill in your Supabase project URL and anon key. Sign in / sign up at /login and /signup; all app routes are then protected, the signed-in email shows in the sidebar, and sign out is available there.

Keep DataProvider as the storage layer. In local-only mode it stores data in localStorage; with Supabase configured and a signed-in user, the same data layer reads and writes the cloud tables (profiles, subjects, tasks, notes, focus_sessions), so data persists across devices.

Supabase database

The schema lives in two migrations under supabase/migrations/:

  • 20260810000000_studyos_schema.sql — core tables
  • 20260812000000_studyos_profile_phase.sql — adds full_name, class_year, and avatar_url to profiles (nullable, so existing rows are preserved)

Apply them to a fresh Supabase project with the Supabase CLI:

supabase link --project-ref <your-project-ref>
supabase db push

or open your project's SQL editor in the Supabase dashboard and paste the file contents.

Tables:

Table Purpose
profiles One profile per auth user; created automatically on sign-up
subjects Study subjects (labels for tasks and notes)
tasks Tasks with priority, due_date, completed, subtasks as JSONB
notes Markdown study notes
focus_sessions Completed pomodoro sessions

Security: every user-owned table has a user_id column referencing auth.users(id), Row Level Security is enabled, and the anon role has no table privileges. Policies allow SELECT/INSERT/UPDATE/DELETE only where auth.uid() = user_id, so users can never read or modify another user's rows. Profiles are only selectable/updatable by their owner and are inserted by a trigger (handle_new_user) when an auth account is created.

Profile & onboarding

After signing in, if the signed-in profile has no full_name or class_year yet, the app redirects to /profile-setup before the dashboard. Completing the form saves the profile to Supabase. The profile (name, class year, avatar) can be edited any time from /profile (avatar section in the sidebar / top bar). Avatars currently use a safe initials fallback; image upload via Supabase Storage is a later step, but profiles.avatar_url already exists for it. In local-only mode the same profile fields are stored in localStorage.

Tests

npm test builds the app and runs tests/phase1-smoke.mjs with Playwright. These tests assume local-only mode, so run them without a .env containing VITE_SUPABASE_* values (or temporarily rename .env).

About

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages