bayan-api / docs /architecture /07-database-schema.md
youssefreda9's picture
docs: Complete Architecture Documentation (12 files) - 01-system-overview: High-level architecture diagram - 02-class-diagram: UML class diagram (Frontend + Backend) - 03-component-diagram: All modules and connections - 04-sequence-diagrams: 5 flows (Analysis, AutoComplete, Summarize, Save, Offline) - 05-dataflow-diagram: DFD Level 0 + Level 1 - 06-deployment-diagram: Docker + HF Spaces + CI/CD - 07-database-schema: ERD + RLS policies + triggers - 08-nlp-pipeline-diagram: Final NLP pipeline with all 5 models - 09-sync-engine-diagram: State machine + conflict resolution - 10-project-dependency-map: Full dependency graph - 11-production-architecture: Final production system diagram - 12-architecture-audit-report: Stats, risks, future expansion
9641a79
|
Raw
History Blame Contribute Delete
5.2 kB

07 — Database Schema Diagram

Overview

BAYAN uses Supabase (PostgreSQL) with Row-Level Security (RLS). All tables enforce per-user data isolation via auth.uid().

Entity Relationship Diagram

erDiagram
    AUTH_USERS {
        uuid id PK
        text email
        boolean is_anonymous
        jsonb raw_user_meta_data
        jsonb raw_app_meta_data
        timestamptz created_at
        timestamptz updated_at
    }

    PROFILES {
        uuid id PK "FK → auth.users(id)"
        text display_name
        text avatar_url
        text auth_provider "anonymous | google"
        timestamptz created_at
        timestamptz updated_at
    }

    DOCUMENTS {
        uuid id PK "gen_random_uuid()"
        uuid user_id FK "→ auth.users(id)"
        text title "Default: مستند جديد"
        text content "HTML content"
        timestamptz created_at
        timestamptz updated_at
    }

    SUMMARIES {
        uuid id PK "gen_random_uuid()"
        uuid document_id FK "→ documents(id)"
        uuid user_id FK "→ auth.users(id)"
        text original_text
        text summary_text
        integer word_count
        real compression_ratio
        timestamptz created_at
    }

    SETTINGS {
        uuid id PK "gen_random_uuid()"
        uuid user_id FK "→ auth.users(id)"
        jsonb preferences "theme, font, size, etc."
        timestamptz created_at
        timestamptz updated_at
    }

    AUTH_USERS ||--|| PROFILES : "auto-created on signup"
    AUTH_USERS ||--o{ DOCUMENTS : "owns"
    AUTH_USERS ||--o| SETTINGS : "has"
    DOCUMENTS ||--o{ SUMMARIES : "has"
    AUTH_USERS ||--o{ SUMMARIES : "owns"

Table Details

profiles

Column Type Constraints Description
id uuid PK, FK → auth.users User ID from Supabase Auth
display_name text nullable Display name (from Google or "ضيف")
avatar_url text nullable Google profile picture URL
auth_provider text NOT NULL, default 'anonymous' anonymous or google
created_at timestamptz NOT NULL, default now() Account creation time
updated_at timestamptz NOT NULL, default now() Last profile update

documents

Column Type Constraints Description
id uuid PK, default gen_random_uuid() Document unique ID
user_id uuid FK → auth.users, NOT NULL Owner
title text default 'مستند جديد' Document title
content text nullable HTML content from editor
created_at timestamptz NOT NULL, default now() Creation time
updated_at timestamptz NOT NULL, default now() Last save time

summaries

Column Type Constraints Description
id uuid PK, default gen_random_uuid() Summary unique ID
document_id uuid FK → documents(id) Parent document
user_id uuid FK → auth.users, NOT NULL Owner
original_text text NOT NULL Source text that was summarized
summary_text text NOT NULL Generated summary
word_count integer nullable Summary word count
compression_ratio real nullable Compression percentage
created_at timestamptz NOT NULL, default now() Generation time

settings

Column Type Constraints Description
id uuid PK, default gen_random_uuid() Setting record ID
user_id uuid FK → auth.users, UNIQUE Owner (one per user)
preferences jsonb NOT NULL, default '{}' All user preferences
created_at timestamptz NOT NULL, default now() Creation time
updated_at timestamptz NOT NULL, default now() Last update time

Row Level Security (RLS) Policies

All tables have RLS enabled. Policies follow the pattern:

-- SELECT: Users can only read their own data
CREATE POLICY "select_own" ON table
  FOR SELECT USING (auth.uid() = user_id);

-- INSERT: Users can only insert their own data  
CREATE POLICY "insert_own" ON table
  FOR INSERT WITH CHECK (auth.uid() = user_id);

-- UPDATE: Users can only update their own data
CREATE POLICY "update_own" ON table
  FOR UPDATE USING (auth.uid() = user_id);

-- DELETE: Users can only delete their own data
CREATE POLICY "delete_own" ON table
  FOR DELETE USING (auth.uid() = user_id);

Database Triggers

Trigger Event Function Purpose
on_auth_user_created AFTER INSERT ON auth.users handle_new_user() Auto-create profile on signup
on_auth_user_updated AFTER UPDATE ON auth.users handle_user_updated() Update profile when linking Google

Client-Side Storage (localStorage)

Key Type Purpose
bayan_editor_draft string (HTML) Unsaved editor content
bayan_dismissed_words JSON array Words marked "keep as-is"
bayan_word_goal number Word count target
bayan_theme string "dark" or "light"