# Git Integration Service - Complete Flow Documentation

## Overview
This document describes the complete flow of the git-integration service for attaching GitHub repositories.

## Configuration

### Environment Variables
- `GITHUB_CLIENT_ID`: OAuth App Client ID
- `GITHUB_CLIENT_SECRET`: OAuth App Client Secret
- `GITHUB_REDIRECT_URI`: OAuth callback URL (http://localhost:8000/api/github/auth/github/callback)
- `GITHUB_WEBHOOK_SECRET`: mywebhooksecret2025
- `PUBLIC_BASE_URL`: https://98fa7f21e2e9.ngrok-free.app (your ngrok URL)
- `ATTACHED_REPOS_DIR`: /app/git-repos
- `DIFF_STORAGE_DIR`: /app/git-repos/diffs
- `FRONTEND_URL`: http://localhost:3001

### Storage Location
- **Container Path**: `/app/git-repos`
- **Host Path**: `/home/tech4biz/Desktop/today work/git-repo`
- **Repository Format**: `owner__REPONAME__branch/`

## Complete User Flow

### 1. User Attaches Repository

**Endpoint**: `POST /api/github/attach-repository`

**Request Body**:
```json
{
  "repository_url": "https://github.com/owner/repo",
  "branch_name": "main"
}
```

**Headers**:
- `x-user-id`: User's unique ID

### 2. Public/Private Detection

The service automatically detects if the repository is public or private:

#### For Public Repositories:
1. ✅ Attempts unauthenticated access via GitHub API
2. ✅ If successful, proceeds to clone without OAuth
3. ✅ Clones repository using `git clone` (full clone with .git directory)
4. ✅ Stores all files including .git folder
5. ✅ Creates webhook automatically (if PUBLIC_BASE_URL is set)

#### For Private Repositories:
1. ❌ Unauthenticated access fails (404 error)
2. 🔐 Checks if user has GitHub OAuth token
3. **If NOT authenticated**:
   - Returns 401 with OAuth URL
   - User is redirected to GitHub for authentication
4. **If authenticated**:
   - Uses OAuth token to access repository
   - Proceeds to clone with authentication

### 3. GitHub OAuth Flow (Private Repos Only)

**Step 1: Initiate OAuth**
- Frontend receives auth_url from backend
- User clicks "Connect GitHub" button
- Redirects to: `http://localhost:8000/api/github/auth/github?redirect=1&user_id={userId}&state={state}`

**Step 2: GitHub Authorization**
- User authorizes the app on GitHub
- GitHub redirects to callback URL with authorization code

**Step 3: OAuth Callback**
- Endpoint: `GET /api/github/auth/github/callback`
- Exchanges code for access token
- Stores token in database (table: `github_user_tokens`)
- **Auto-attaches repository** if state contains repo context
- Redirects back to frontend: `{FRONTEND_URL}/project-builder?github_connected=1&repo_attached=1`

### 4. Repository Cloning

**Clone Method**: Full git clone (includes .git directory)

**For Public Repos**:
```bash
git clone -b {branch} https://github.com/{owner}/{repo}.git
```

**For Private Repos**:
```bash
git clone -b {branch} https://oauth2:{token}@github.com/{owner}/{repo}.git
```

**Storage Structure**:
```
/home/tech4biz/Desktop/today work/git-repo/
├── owner__REPONAME__branch/
│   ├── .git/              # ✅ Full git history included
│   ├── src/
│   ├── package.json
│   └── ... (all files)
└── diffs/                 # Diff storage for webhooks
```

### 5. File Storage in Database

Files are stored using the **optimized JSON schema** (migration 003):

**Table: `repository_files`**
- One row per directory
- All files in a directory stored as JSON array
- Unique constraint on `directory_id`

**Example**:
```json
{
  "directory_id": "uuid-123",
  "relative_path": "src/components",
  "files": [
    {
      "filename": "Header.tsx",
      "file_extension": ".tsx",
      "file_size_bytes": 1024,
      "is_binary": false,
      "mime_type": "text/plain"
    },
    {
      "filename": "Footer.tsx",
      "file_extension": ".tsx",
      "file_size_bytes": 512,
      "is_binary": false,
      "mime_type": "text/plain"
    }
  ]
}
```

### 6. Automatic Webhook Creation

After successful repository attachment, the service automatically creates a webhook:

**Webhook Configuration**:
- **URL**: `https://98fa7f21e2e9.ngrok-free.app/api/github/webhook`
- **Secret**: `mywebhooksecret2025`
- **Events**: `push`
- **Content Type**: `application/json`

**Webhook Endpoint**: `POST /api/github/webhook`

**What happens on push**:
1. GitHub sends webhook payload
2. Service verifies signature using webhook secret
3. Processes commit changes
4. Updates repository files in database
5. Stores diff information

### 7. Response to Frontend

**Success Response** (201):
```json
{
  "success": true,
  "message": "Repository attached and synced successfully",
  "data": {
    "repository_id": "uuid-456",
    "repository_name": "repo",
    "owner_name": "owner",
    "branch_name": "main",
    "is_public": true,
    "sync_status": "synced",
    "webhook_result": {
      "created": true,
      "hook_id": 12345
    },
    "storage_info": {
      "total_files": 150,
      "total_directories": 25,
      "total_size_bytes": 1048576
    }
  }
}
```

**Auth Required Response** (401):
```json
{
  "success": false,
  "message": "GitHub authentication required for private repository",
  "requires_auth": true,
  "auth_url": "http://localhost:8000/api/github/auth/github?redirect=1&state=...",
  "repository_info": {
    "owner": "owner",
    "repo": "repo",
    "repository_url": "https://github.com/owner/repo",
    "branch_name": "main"
  }
}
```

## Frontend Integration Guide

### Step 1: Attach Repository Request

```typescript
const attachRepository = async (repoUrl: string, branch: string, userId: string) => {
  const response = await fetch('http://localhost:8000/api/github/attach-repository', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-user-id': userId
    },
    body: JSON.stringify({
      repository_url: repoUrl,
      branch_name: branch
    })
  });

  const data = await response.json();
  
  if (response.status === 401 && data.requires_auth) {
    // Redirect to OAuth
    window.location.href = data.auth_url;
  } else if (response.status === 201) {
    // Success - repository attached
    console.log('Repository attached:', data.data);
  }
};
```

### Step 2: Handle OAuth Redirect

```typescript
// In your /project-builder page
useEffect(() => {
  const params = new URLSearchParams(window.location.search);
  
  if (params.get('github_connected') === '1') {
    // GitHub connected successfully
    const repoAttached = params.get('repo_attached') === '1';
    const repositoryId = params.get('repository_id');
    const syncStatus = params.get('sync_status');
    
    if (repoAttached) {
      // Repository was auto-attached after OAuth
      console.log('Repository attached:', repositoryId, syncStatus);
    }
  }
}, []);
```

### Step 3: Display Repository Data

```typescript
const getRepositoryFiles = async (repositoryId: string) => {
  const response = await fetch(
    `http://localhost:8000/api/github/repository/${repositoryId}/files`
  );
  
  const data = await response.json();
  return data.data; // File structure
};
```

## Database Schema

### Main Tables

1. **all_repositories**: Repository metadata
2. **repository_storage**: Storage tracking
3. **repository_directories**: Directory structure
4. **repository_files**: Files as JSON arrays (one row per directory)
5. **github_user_tokens**: OAuth tokens
6. **github_webhooks**: Webhook event logs

## Key Features

✅ **Public/Private Detection**: Automatic detection and handling
✅ **OAuth Flow**: Seamless GitHub authentication
✅ **Full Git Clone**: Includes .git directory and complete history
✅ **Automatic Webhooks**: Auto-creates webhooks with ngrok URL
✅ **JSON Storage**: Optimized file storage in database
✅ **Auto-Attach**: Repository automatically attached after OAuth
✅ **Frontend Redirect**: Redirects back to your app after OAuth

## Testing the Flow

1. Start the services:
   ```bash
   docker compose up -d --build git-integration
   ```

2. Try attaching a public repository:
   ```bash
   curl -X POST http://localhost:8000/api/github/attach-repository \
     -H "Content-Type: application/json" \
     -H "x-user-id: your-user-id" \
     -d '{"repository_url": "https://github.com/octocat/Hello-World", "branch_name": "master"}'
   ```

3. Try attaching a private repository:
   - Will return auth_url
   - Visit the auth_url in browser
   - Authorize on GitHub
   - Will redirect back and auto-attach

4. Check stored files:
   ```bash
   ls -la "/home/tech4biz/Desktop/today work/git-repo/"
   ```

5. Verify webhook was created:
   - Go to GitHub repository → Settings → Webhooks
   - Should see webhook with your ngrok URL

## Troubleshooting

### Repository not cloning
- Check ATTACHED_REPOS_DIR permissions
- Verify OAuth token is valid
- Check git-integration service logs

### Webhook not created
- Verify PUBLIC_BASE_URL is set correctly
- Check OAuth token has admin:repo_hook scope
- Verify ngrok is running and accessible

### OAuth redirect not working
- Check FRONTEND_URL environment variable
- Verify GITHUB_REDIRECT_URI matches GitHub App settings
- Check browser console for errors
