Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DavidCevallos15/inforario-IA-null/llms.txt

Use this file to discover all available pages before exploring further.

Inforario relies on Supabase for user authentication, cloud schedule persistence, and serverless AI extraction. This guide walks through every step needed to bring a fresh Supabase project to the point where all features — including AI-powered PDF parsing and Google Calendar sync — work end-to-end.
1
Create a Supabase Project
2
Go to supabase.com and create a new project. Choose a region close to your users and set a strong database password (you won’t need it regularly, but keep it safe).
3
Once the project is provisioned, navigate to Settings → API and copy two values:
4
  • Project URL — looks like https://abcdefgh.supabase.co
  • anon public key — the eyJ... JWT token under Project API keys
  • 5
    Add these to your frontend/.env.local:
    6
    VITE_SUPABASE_URL=https://abcdefgh.supabase.co
    VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
    
    7
    Create the Database Tables
    8
    Open the SQL Editor in the Supabase dashboard and run the following statements to create the three tables Inforario requires.
    9
    profiles table — stores additional user metadata synced from auth.users:
    10
    create table public.profiles (
      id         uuid references auth.users on delete cascade primary key,
      email      text,
      full_name  text,
      avatar_url text,
      career     text,
      updated_at timestamptz default now()
    );
    
    11
    schedules table — the core data store; each row holds a full parsed schedule as JSONB:
    12
    create table public.schedules (
      id              uuid primary key default gen_random_uuid(),
      user_id         uuid references auth.users on delete cascade not null,
      title           text,
      academic_period text,
      faculty         text,
      schedule_data   jsonb,
      last_updated    timestamptz default now()
    );
    
    create index schedules_user_id_idx on public.schedules (user_id);
    
    13
    user_calendar_tokens table — stores OAuth tokens for Google Calendar sync:
    14
    create table public.user_calendar_tokens (
      user_id       uuid primary key references auth.users on delete cascade,
      access_token  text not null,
      refresh_token text,
      expiry_date   timestamptz
    );
    
    15
    Enable Row Level Security
    16
    After creating the tables, turn on Row Level Security (RLS) so that each user can only read and write their own rows. Run the following SQL in the editor:
    17
    -- Enable RLS on both tables
    alter table public.schedules enable row level security;
    alter table public.user_calendar_tokens enable row level security;
    
    -- Schedules: users can manage only their own rows
    create policy "Users can view their own schedules"
      on public.schedules for select
      using ( auth.uid() = user_id );
    
    create policy "Users can insert their own schedules"
      on public.schedules for insert
      with check ( auth.uid() = user_id );
    
    create policy "Users can update their own schedules"
      on public.schedules for update
      using ( auth.uid() = user_id );
    
    create policy "Users can delete their own schedules"
      on public.schedules for delete
      using ( auth.uid() = user_id );
    
    -- Calendar tokens: users can manage only their own token row
    create policy "Users can view their own calendar tokens"
      on public.user_calendar_tokens for select
      using ( auth.uid() = user_id );
    
    create policy "Users can upsert their own calendar tokens"
      on public.user_calendar_tokens for insert
      with check ( auth.uid() = user_id );
    
    create policy "Users can update their own calendar tokens"
      on public.user_calendar_tokens for update
      using ( auth.uid() = user_id );
    
    18
    The profiles table does not require RLS for basic operation since profile data is populated server-side via a database trigger on auth.users. If you store sensitive fields there, add equivalent policies following the same pattern.
    19
    Configure Authentication Providers
    20
    In the Supabase dashboard, go to Authentication → Providers.
    21
    Email / Password Enable the Email provider. For development, you may disable Confirm email (under Auth → Settings → Email confirmations) to simplify testing, but re-enable it for production. The local config.toml has enable_confirmations = false by default for this reason.
    22
    Google OAuth
    23
  • In Google Cloud Console, create (or select) a project and navigate to APIs & Services → Credentials.
  • Create an OAuth 2.0 Client ID of type Web application.
  • Under Authorized redirect URIs, add:
    • https://<your-project-ref>.supabase.co/auth/v1/callback
    • http://localhost:3000 (for local development — the Vite dev server runs on port 3000)
  • Copy the Client ID and Client Secret back into Supabase dashboard → Authentication → Providers → Google and save.
  • In supabaseClient.ts, signInWithGoogle() sets redirectTo: window.location.origin, so no additional redirect URL configuration is needed on the frontend.
  • 24
    Set Edge Function Secrets
    25
    From inside the backend/ directory (where supabase/config.toml lives), push your secrets to the Supabase project:
    26
    cd backend
    
    supabase secrets set GROQ_API_KEY=your_groq_api_key_here
    supabase secrets set GROQ_MODEL=llama-3.3-70b-versatile
    supabase secrets set GOOGLE_CLIENT_ID=your_oauth_client_id
    supabase secrets set GOOGLE_CLIENT_SECRET=your_oauth_client_secret
    
    27
    SUPABASE_URL and SUPABASE_ANON_KEY are injected automatically by the Edge Functions runtime — you do not need to set them manually.
    28
    You can verify which secrets are currently set by running supabase secrets list from the backend/ directory.
    29
    Deploy Edge Functions
    30
    With secrets in place, deploy both Edge Functions:
    31
    cd backend
    
    supabase functions deploy extract-schedule
    supabase functions deploy google-calendar-sync
    
    32
    The extract-schedule function is configured with verify_jwt = false in config.toml, meaning it accepts unauthenticated requests. The google-calendar-sync function requires a valid Supabase JWT passed in the Authorization header — it calls supabase.auth.getUser() to verify the caller before touching any token rows.

    Understanding config.toml

    The file at backend/supabase/config.toml drives the local Supabase stack configuration. The most important field is:
    project_id = "inforario-IA-null"
    
    This string uniquely identifies the local project on your machine. It is used as a namespace prefix for Docker container names and local data directories. If you clone the repository on a machine that already has another Supabase project running with the same project_id, rename this value to avoid conflicts. Key sections relevant to Inforario development:
    The local PostgREST API runs on port 54321. The schemas array exposes public and graphql_public. max_rows = 1000 limits payload size for safety — adjust if you need to retrieve more than 1,000 schedule rows in a single query.
    [api]
    enabled = true
    port = 54321
    schemas = ["public", "graphql_public"]
    max_rows = 1000
    
    Local PostgreSQL major version is set to 17, matching the remote Supabase project. The shadow database for db diff runs on port 54320. Seeds are loaded from ./seed.sql on supabase db reset.
    [db]
    port = 54322
    major_version = 17
    
    The site_url is set to http://127.0.0.1:3000, aligning with the Vite dev server port defined in vite.config.ts. Email OTPs expire after 1 hour (otp_expiry = 3600). Anonymous sign-ins are disabled (enable_anonymous_sign_ins = false).
    [auth]
    site_url = "http://127.0.0.1:3000"
    additional_redirect_urls = ["https://127.0.0.1:3000"]
    jwt_expiry = 3600
    enable_anonymous_sign_ins = false
    
    Edge Functions run with Deno version 2 and the per_worker policy, which enables hot-reload during local development. The Chrome inspector for debugging is available on port 8083. The extract-schedule function overrides JWT verification at the function level.
    [edge_runtime]
    policy = "per_worker"
    inspector_port = 8083
    deno_version = 2
    
    [functions.extract-schedule]
    verify_jwt = false
    
    Emails sent during local auth flows (confirmations, password resets) are captured by Inbucket and viewable at http://localhost:54324 — no real emails are sent.
    [inbucket]
    enabled = true
    port = 54324
    

    Build docs developers (and LLMs) love