Skip to content

Latest commit

 

History

History
447 lines (406 loc) · 18.5 KB

File metadata and controls

447 lines (406 loc) · 18.5 KB

GitHub Integration Architecture

System Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         User Interface                          │
│                     (StatusPageNew.jsx)                         │
│                                                                 │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐      │
│  │  Stats   │  │  Search  │  │ Filters  │  │   Sync   │      │
│  │  Cards   │  │   Bar    │  │  Tabs    │  │  Button  │      │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘      │
│                                                                 │
│  ┌───────────────────────────────────────────────────────┐    │
│  │         Contribution Cards (with PR status)           │    │
│  └───────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                      React Hook Layer                           │
│                    (useGitHubSync.js)                           │
│                                                                 │
│  • Auto-sync on mount (if > 5 min)                             │
│  • Manual sync trigger                                         │
│  • State management (loading, error, data)                     │
│  • Statistics calculation                                      │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                     Service Layer                               │
│                   (githubSync.js)                               │
│                                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐        │
│  │   Fetch      │  │   Parse      │  │   Transform  │        │
│  │  GitHub      │→ │   GitHub     │→ │     Data     │        │
│  │   Data       │  │    URLs      │  │              │        │
│  └──────────────┘  └──────────────┘  └──────────────┘        │
│                                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐        │
│  │   Detect     │  │    Link      │  │   Upsert     │        │
│  │   Status     │→ │  PRs to      │→ │     to       │        │
│  │              │  │   Issues     │  │   Database   │        │
│  └──────────────┘  └──────────────┘  └──────────────┘        │
└─────────────────────────────────────────────────────────────────┘
                              │
                    ┌─────────┴─────────┐
                    ↓                   ↓
┌──────────────────────────┐  ┌──────────────────────────┐
│     GitHub REST API      │  │   Supabase Database      │
│                          │  │                          │
│  • GET /user             │  │  ┌──────────────────┐   │
│  • GET /search/issues    │  │  │  contributions   │   │
│  • GET /repos/.../pulls  │  │  │     table        │   │
│  • GET /repos/.../issues │  │  └──────────────────┘   │
│                          │  │                          │
│  Rate Limit: 5000/hour   │  │  RLS Policies Enabled   │
└──────────────────────────┘  └──────────────────────────┘

Data Flow Diagram

┌──────────┐
│  User    │
│  Logs In │
│  (GitHub)│
└────┬─────┘
     │
     ↓
┌────────────────┐
│  Supabase Auth │
│  Stores Token  │
└────┬───────────┘
     │
     ↓
┌────────────────────┐
│  Navigate to       │
│  Status Page       │
└────┬───────────────┘
     │
     ↓
┌────────────────────┐
│  useGitHubSync     │
│  Hook Initializes  │
└────┬───────────────┘
     │
     ↓
┌────────────────────┐      No
│  Last Sync         │─────────→ Display Cached Data
│  > 5 minutes?      │
└────┬───────────────┘
     │ Yes
     ↓
┌────────────────────┐
│  Trigger Sync      │
└────┬───────────────┘
     │
     ↓
┌────────────────────────────────────────┐
│  Fetch from GitHub API (Parallel)      │
│  ┌──────────────┐  ┌──────────────┐   │
│  │   Assigned   │  │    User's    │   │
│  │    Issues    │  │     PRs      │   │
│  └──────────────┘  └──────────────┘   │
└────┬───────────────────────────────────┘
     │
     ↓
┌────────────────────┐
│  Parse & Transform │
│  • Extract repo    │
│  • Link PRs        │
│  • Detect status   │
└────┬───────────────┘
     │
     ↓
┌────────────────────┐
│  Upsert to DB      │
│  (contributions)   │
└────┬───────────────┘
     │
     ↓
┌────────────────────┐
│  Update UI         │
│  • Show cards      │
│  • Update stats    │
│  • Show success    │
└────────────────────┘

Component Hierarchy

StatusPage
├── Header
│   ├── SearchBar
│   └── UserProfile
│
├── SyncStatusBar
│   ├── LastSyncTime
│   └── SyncButton
│
├── ProgressCard
│   ├── SuccessRate
│   └── ProgressBar
│
├── StatsRow
│   ├── SavedCard
│   ├── AppliedCard
│   ├── InProgressCard
│   ├── MergedCard
│   └── ClosedCard
│
├── FilterTabs
│   └── StatusFilter[]
│
└── ContributionsList
    └── ContributionCard[]
        ├── RepoInfo
        ├── IssueTitle
        ├── StatusBadge
        ├── ActivityInfo
        └── ActionButtons

Database Schema Relationships

┌─────────────────┐
│   auth.users    │
│                 │
│  • id (PK)      │
│  • email        │
│  • metadata     │
└────────┬────────┘
         │
         │ 1:N
         │
         ↓
┌─────────────────────────────┐
│      contributions          │
│                             │
│  • id (PK)                  │
│  • user_id (FK) ────────────┘
│  • github_issue_number      │
│  • github_repo_owner        │
│  • github_repo_name         │
│  • issue_url                │
│  • pr_url                   │
│  • pr_status                │
│  • is_assigned              │
│  • last_synced_at           │
│                             │
│  UNIQUE(user_id, owner,     │
│         repo, issue_number) │
└─────────────────────────────┘
         │
         │ N:1 (optional)
         │
         ↓
┌─────────────────┐
│    bookmarks    │
│                 │
│  • id (PK)      │
│  • user_id      │
│  • issue_url    │
│  • status       │
└─────────────────┘

Status Detection Flow

┌─────────────────┐
│  Contribution   │
│     Data        │
└────────┬────────┘
         │
         ↓
    ┌────────────┐
    │ Has PR?    │
    └─┬────────┬─┘
      │ No     │ Yes
      │        │
      ↓        ↓
  ┌────────┐  ┌──────────────┐
  │Assigned│  │ PR Status?   │
  │   or   │  └─┬──────────┬─┘
  │Comment?│    │          │
  └─┬────┬─┘    │          │
    │Yes │No    │          │
    │    │      ↓          ↓
    ↓    ↓   ┌────┐    ┌────┐
  ┌────┐ ┌──┐│Open│    │Mer-│
  │App-│ │Sa││Dra-│    │ged │
  │lied│ │ve││ft  │    └─┬──┘
  └────┘ └──┘└─┬──┘      │
              │          │
              ↓          ↓
         ┌─────────┐  ┌────────┐
         │   In    │  │Merged  │
         │Progress │  │  ✅    │
         │   🔨    │  └────────┘
         └─────────┘
              │
              ↓
         ┌─────────┐
         │ Closed  │
         │ (no     │
         │ merge)  │
         │   ❌    │
         └─────────┘

API Call Sequence

User Triggers Sync
       │
       ↓
┌──────────────────┐
│ 1. Get User Info │
│ GET /user        │
└────────┬─────────┘
         │
         ↓
┌──────────────────────────────┐
│ 2. Fetch Assigned Issues     │
│ GET /search/issues?          │
│     q=assignee:{user}        │
└────────┬─────────────────────┘
         │
         ↓
┌──────────────────────────────┐
│ 3. Fetch User PRs            │
│ GET /search/issues?          │
│     q=author:{user}+is:pr    │
└────────┬─────────────────────┘
         │
         ↓
┌──────────────────────────────┐
│ 4. For Each PR:              │
│ GET /repos/{owner}/{repo}/   │
│     pulls/{number}           │
└────────┬─────────────────────┘
         │
         ↓
┌──────────────────────────────┐
│ 5. Link PRs to Issues        │
│ (Match by repo + number)     │
└────────┬─────────────────────┘
         │
         ↓
┌──────────────────────────────┐
│ 6. Upsert to Database        │
│ INSERT ... ON CONFLICT       │
│ UPDATE                       │
└──────────────────────────────┘

Security Architecture

┌─────────────────────────────────────────┐
│           Frontend (React)              │
│                                         │
│  • No direct GitHub token access        │
│  • Uses Supabase client                 │
│  • RLS enforced automatically           │
└────────────┬────────────────────────────┘
             │
             ↓
┌─────────────────────────────────────────┐
│        Supabase Auth Layer              │
│                                         │
│  • Manages GitHub OAuth                 │
│  • Stores provider_token securely       │
│  • Issues JWT for database access       │
└────────────┬────────────────────────────┘
             │
             ↓
┌─────────────────────────────────────────┐
│      Supabase Database (Postgres)       │
│                                         │
│  RLS Policies:                          │
│  • SELECT: auth.uid() = user_id         │
│  • INSERT: auth.uid() = user_id         │
│  • UPDATE: auth.uid() = user_id         │
│  • DELETE: auth.uid() = user_id         │
└─────────────────────────────────────────┘

Performance Optimization

┌─────────────────────────────────────────┐
│         Optimization Layers             │
└─────────────────────────────────────────┘

1. Frontend Caching
   ├── React State (in-memory)
   ├── Auto-sync throttling (5 min)
   └── Debounced search

2. API Optimization
   ├── Parallel requests (Promise.all)
   ├── Batch operations
   └── Rate limit handling

3. Database Optimization
   ├── Indexes on user_id, pr_status
   ├── Upsert instead of insert/update
   └── Efficient queries with filters

4. Network Optimization
   ├── Minimal payload
   ├── Compression
   └── CDN for static assets

Error Handling Flow

┌─────────────────┐
│  API Call       │
└────────┬────────┘
         │
         ↓
    ┌────────────┐
    │  Success?  │
    └─┬────────┬─┘
      │ Yes    │ No
      │        │
      ↓        ↓
  ┌────────┐  ┌──────────────┐
  │Process │  │ Error Type?  │
  │  Data  │  └─┬──────────┬─┘
  └────────┘    │          │
                ↓          ↓
           ┌────────┐  ┌────────┐
           │Network │  │  API   │
           │ Error  │  │ Error  │
           └───┬────┘  └───┬────┘
               │           │
               ↓           ↓
           ┌────────────────────┐
           │  Show Error        │
           │  Message to User   │
           └────────────────────┘
                    │
                    ↓
           ┌────────────────────┐
           │  Log to Console    │
           │  (for debugging)   │
           └────────────────────┘

Key Design Decisions

1. Separate Contributions Table

Why: Keep bookmarks (manual) separate from contributions (automatic)

  • Better separation of concerns
  • Can have contributions without bookmarks
  • Easier to query and analyze

2. Upsert Strategy

Why: Handle updates efficiently

  • Prevents duplicates
  • Updates existing records
  • Single operation instead of check + insert/update

3. Auto-sync Throttling

Why: Balance freshness with performance

  • Reduces unnecessary API calls
  • Respects rate limits
  • Still feels real-time (5 min is acceptable)

4. Parallel API Calls

Why: Improve sync speed

  • Fetch issues and PRs simultaneously
  • Reduces total sync time
  • Better user experience

5. Client-side Status Detection

Why: Flexibility and performance

  • No server-side logic needed
  • Easy to update rules
  • Fast computation

Last Updated: January 28, 2026 Version: 1.0.0