# Google Sheets Auto-Sync for Sellers

**Document Version:** 1.0
**Created:** November 20, 2025
**Status:** Proposal (Not Implemented)

---

## Table of Contents
1. [Overview](#overview)
2. [Business Requirements](#business-requirements)
3. [Current Workflow vs Proposed Workflow](#current-workflow-vs-proposed-workflow)
4. [Technical Architecture](#technical-architecture)
5. [Database Schema Changes](#database-schema-changes)
6. [Google API Integration](#google-api-integration)
7. [User Flow](#user-flow)
8. [Implementation Checklist](#implementation-checklist)
9. [Security & Privacy](#security--privacy)
10. [Error Handling & Edge Cases](#error-handling--edge-cases)
11. [Testing Scenarios](#testing-scenarios)

---

## Overview

### Problem Statement
Sellers currently need to manually export or track their orders. They want automatic synchronization of their sales data to their personal Google Sheets for:
- Real-time tracking of their sales
- Custom reporting and analysis
- Integration with their own business tools
- Backup and record-keeping

### Solution
Implement a Google Sheets integration that:
1. Allows sellers to connect their Google account (Gmail)
2. Automatically creates a Google Sheet in their Google Drive
3. Syncs every order created from sales page/checkout form to their sheet in real-time
4. Provides a settings page to manage the connection

---

## Business Requirements

### Functional Requirements

1. **Google Account Connection**
   - Seller can link their Gmail/Google account
   - OAuth 2.0 secure authentication
   - One Google account per seller
   - Ability to disconnect and reconnect

2. **Automatic Sheet Creation**
   - Create a new Google Sheet when seller first connects
   - Sheet name format: `[Seller Name] - Sales Orders - [Date]`
   - Pre-formatted with proper headers and columns
   - Stored in seller's Google Drive (they own it)

3. **Real-time Order Sync**
   - Every new order created by seller → automatically added to their sheet
   - Sources: Sales page orders, checkout form orders, manually created orders
   - Sync happens immediately after order creation
   - Update existing row if order is modified

4. **Settings Management**
   - Button to connect Google account
   - View connection status (connected/disconnected)
   - Button to disconnect
   - Button to manually trigger full re-sync
   - View last sync time and status

5. **Data to Sync**
   - Order number
   - Customer name
   - Phone number
   - Email
   - Address (full)
   - Products ordered (with SKU and quantity)
   - Order total
   - Payment method
   - Order status
   - Date created
   - Tracking number (if available)

---

## Current Workflow vs Proposed Workflow

### Current Workflow (Manual)
```
1. Seller creates order via sales page/checkout form
2. Order saved to database
3. Seller manually exports data (Excel/CSV) from dashboard
4. Seller manually imports to their own Google Sheets
5. Repeat for every batch of orders
```

**Problems:**
- ❌ Manual work required
- ❌ Data not real-time
- ❌ Prone to human error
- ❌ Time-consuming

### Proposed Workflow (Automated)
```
1. Seller connects Google account ONCE (one-time setup)
2. System creates Google Sheet in seller's Drive
3. Seller creates order via sales page/checkout form
4. Order saved to database
5. System AUTOMATICALLY syncs order to Google Sheet
6. Seller sees new order in their Google Sheet instantly
```

**Benefits:**
- ✅ Zero manual work
- ✅ Real-time data sync
- ✅ No human error
- ✅ Time-saving
- ✅ Seller owns their data (in their own Drive)

---

## Technical Architecture

### High-Level Flow

```
┌─────────────────┐
│  Seller Creates │
│     Order       │
│ (Sales Page/    │
│ Checkout Form)  │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Order Saved    │
│  to Database    │
│  (orders table) │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Trigger Event:  │
│ OrderCreated    │
│ OrderUpdated    │
└────────┬────────┘
         │
         ▼
┌─────────────────────────────┐
│ GoogleSheetsService         │
│                             │
│ 1. Check if seller has      │
│    Google Sheets connected  │
│                             │
│ 2. If YES: Sync to Sheet    │
│    If NO: Skip              │
└────────┬────────────────────┘
         │
         ▼
┌─────────────────────────────┐
│ Google Sheets API           │
│                             │
│ - Authenticate with token   │
│ - Find seller's sheet       │
│ - Append/update row         │
└─────────────────────────────┘
```

### Components Needed

1. **Google OAuth Controller**
   - Handle OAuth flow
   - Store access tokens securely
   - Refresh tokens when expired

2. **Google Sheets Service**
   - Create new sheet
   - Append row (new order)
   - Update row (order modified)
   - Batch sync (full re-sync)

3. **Order Event Listeners**
   - Listen to `OrderCreated` event
   - Listen to `OrderUpdated` event
   - Trigger sync to Google Sheets

4. **Settings Controller**
   - Display connection status
   - Connect/disconnect buttons
   - Manual sync trigger

5. **Database Migration**
   - Add `google_sheet_id` to users table
   - Add `google_access_token` (encrypted)
   - Add `google_refresh_token` (encrypted)
   - Add `google_sheets_sync_enabled` flag
   - Add `google_sheets_last_sync` timestamp

---

## Database Schema Changes

### 1. Modify `users` Table

```sql
ALTER TABLE `users`
ADD COLUMN `google_sheet_id` VARCHAR(255) NULL
  COMMENT 'Google Sheet ID for order sync',
ADD COLUMN `google_access_token` TEXT NULL
  COMMENT 'Encrypted Google OAuth access token',
ADD COLUMN `google_refresh_token` TEXT NULL
  COMMENT 'Encrypted Google OAuth refresh token',
ADD COLUMN `google_token_expires_at` TIMESTAMP NULL
  COMMENT 'When the access token expires',
ADD COLUMN `google_sheets_sync_enabled` TINYINT(1) DEFAULT 0
  COMMENT 'Whether Google Sheets sync is enabled',
ADD COLUMN `google_sheets_last_sync` TIMESTAMP NULL
  COMMENT 'Last successful sync timestamp',
ADD COLUMN `google_email` VARCHAR(255) NULL
  COMMENT 'Connected Google account email';
```

### 2. Create `google_sheets_sync_log` Table (Optional - for debugging)

```sql
CREATE TABLE `google_sheets_sync_log` (
  `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user_id` BIGINT(20) UNSIGNED NOT NULL,
  `order_id` BIGINT(20) UNSIGNED NOT NULL,
  `action` ENUM('create', 'update', 'delete') NOT NULL,
  `status` ENUM('success', 'failed', 'pending') NOT NULL,
  `error_message` TEXT NULL,
  `synced_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `order_id` (`order_id`),
  KEY `synced_at` (`synced_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

---

## Google API Integration

### Step 1: Google Cloud Console Setup

1. **Create Project**
   - Go to https://console.cloud.google.com/
   - Create new project: "Multistore Order Sync"

2. **Enable APIs**
   - Enable "Google Sheets API"
   - Enable "Google Drive API"

3. **Create OAuth 2.0 Credentials**
   - Create OAuth 2.0 Client ID
   - Application type: Web application
   - Authorized redirect URIs:
     - `https://multistore.test/auth/google/callback`
     - `https://yourdomain.com/auth/google/callback`
   - Copy Client ID and Client Secret

4. **Configure OAuth Consent Screen**
   - User type: External
   - App name: "Multistore Order Sync"
   - Scopes needed:
     - `https://www.googleapis.com/auth/spreadsheets` (Read/write sheets)
     - `https://www.googleapis.com/auth/drive.file` (Create files in Drive)
     - `https://www.googleapis.com/auth/userinfo.email` (Get user email)

### Step 2: Install Google API PHP Client

```bash
composer require google/apiclient:^2.0
```

### Step 3: Environment Variables

Add to `.env`:
```env
GOOGLE_CLIENT_ID=your_client_id_here
GOOGLE_CLIENT_SECRET=your_client_secret_here
GOOGLE_REDIRECT_URI=https://multistore.test/auth/google/callback
```

---

## User Flow

### Flow 1: First-Time Setup (Seller Connects Google Account)

```
┌──────────────────────────────────────────────────┐
│ 1. Seller goes to Settings → Google Sheets Sync │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 2. Clicks "Connect Google Account" button       │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 3. Redirected to Google OAuth consent screen    │
│    - Shows app name: "Multistore Order Sync"    │
│    - Requests permissions for Sheets & Drive     │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 4. Seller selects Google account & clicks Allow │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 5. Google redirects back to callback URL        │
│    with authorization code                       │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 6. System exchanges code for access/refresh     │
│    tokens and stores them (encrypted)            │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 7. System creates new Google Sheet in seller's  │
│    Drive with name:                              │
│    "John Doe - Sales Orders - 2025-11-20"        │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 8. System adds header row to sheet:             │
│    Order No | Date | Customer | Phone | etc.    │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 9. System performs initial sync of existing     │
│    orders (optional - ask seller)                │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 10. Redirect to settings page with success      │
│     message: "Google Sheets connected!"          │
│     Shows: Connected as john@gmail.com           │
└──────────────────────────────────────────────────┘
```

### Flow 2: Order Creation Auto-Sync

```
┌──────────────────────────────────────────────────┐
│ 1. Seller creates order via sales page          │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 2. Order saved to database                      │
│    Event: OrderCreated                           │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 3. Event listener triggers                      │
│    GoogleSheetsService::syncOrder()              │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 4. Check: Does seller have Google Sheets        │
│    connected?                                    │
└─────────┬──────────────────────┬─────────────────┘
          │ YES                  │ NO
          ▼                      ▼
┌─────────────────────┐   ┌──────────────────┐
│ 5. Refresh token    │   │ Skip sync        │
│    if expired       │   │ (exit silently)  │
└──────┬──────────────┘   └──────────────────┘
       │
       ▼
┌──────────────────────────────────────────────────┐
│ 6. Format order data into array:                │
│    [Order #123, 2025-11-20, John Tan, ...]       │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 7. Call Google Sheets API to append row         │
│    to seller's sheet                             │
└─────────┬────────────────────┬───────────────────┘
          │ SUCCESS            │ FAILED
          ▼                    ▼
┌─────────────────────┐   ┌──────────────────────┐
│ 8. Update last_sync │   │ Log error            │
│    timestamp        │   │ Retry later (queue)  │
│    Log success      │   └──────────────────────┘
└─────────────────────┘
```

### Flow 3: Disconnect Google Account

```
┌──────────────────────────────────────────────────┐
│ 1. Seller goes to Settings → Google Sheets Sync │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 2. Clicks "Disconnect Google Account" button    │
└────────────────┬─────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────┐
│ 3. Confirmation dialog:                          │
│    "Your orders will no longer sync. Continue?"  │
└─────────┬────────────────────┬───────────────────┘
          │ YES                │ NO
          ▼                    ▼
┌─────────────────────┐   ┌──────────────────┐
│ 4. Revoke token at  │   │ Cancel           │
│    Google (optional)│   └──────────────────┘
│ Clear tokens from   │
│ database            │
│ Set sync_enabled=0  │
└──────┬──────────────┘
       │
       ▼
┌──────────────────────────────────────────────────┐
│ 5. Show success: "Google account disconnected"  │
│    Note: "Your existing Google Sheet is still   │
│           in your Drive"                         │
└──────────────────────────────────────────────────┘
```

---

## Implementation Checklist

### Phase 1: Google OAuth Setup
- [ ] Create Google Cloud project
- [ ] Enable Google Sheets API and Google Drive API
- [ ] Create OAuth 2.0 credentials
- [ ] Configure OAuth consent screen
- [ ] Add credentials to .env file
- [ ] Install Google API PHP Client library

### Phase 2: Database Layer
- [ ] Create migration to add Google-related columns to users table
- [ ] Create GoogleSheetsSyncLog model (optional)
- [ ] Update User model with Google Sheets relationships
- [ ] Add accessor/mutator for encrypted tokens

### Phase 3: Google OAuth Implementation
- [ ] Create GoogleAuthController
  - [ ] `redirectToGoogle()` - Initiate OAuth flow
  - [ ] `handleGoogleCallback()` - Handle OAuth callback
  - [ ] `disconnect()` - Disconnect Google account
- [ ] Add routes for Google OAuth
- [ ] Implement token storage (encrypted)
- [ ] Implement token refresh mechanism

### Phase 4: Google Sheets Service
- [ ] Create GoogleSheetsService class
  - [ ] `authenticate()` - Authenticate with Google API
  - [ ] `createSheet()` - Create new Google Sheet
  - [ ] `addHeaderRow()` - Add column headers
  - [ ] `appendOrder()` - Append order to sheet
  - [ ] `updateOrder()` - Update existing order row
  - [ ] `batchSyncOrders()` - Sync all orders at once
  - [ ] `findOrderRow()` - Find order row by order number
  - [ ] `refreshToken()` - Refresh expired access token

### Phase 5: Event Listeners
- [ ] Create OrderCreatedListener
  - [ ] Check if seller has Google Sheets enabled
  - [ ] Trigger GoogleSheetsService::syncOrder()
- [ ] Create OrderUpdatedListener
  - [ ] Check if seller has Google Sheets enabled
  - [ ] Trigger GoogleSheetsService::updateOrder()
- [ ] Register event listeners in EventServiceProvider

### Phase 6: Settings UI
- [ ] Create Google Sheets sync settings page
  - [ ] Connection status display
  - [ ] "Connect Google Account" button
  - [ ] "Disconnect" button
  - [ ] "Manual Sync Now" button
  - [ ] Last sync timestamp display
  - [ ] Sync history/logs (optional)
- [ ] Add route to settings
- [ ] Add menu item for sellers

### Phase 7: Queue Implementation (Optional but Recommended)
- [ ] Create SyncOrderToGoogleSheets job
- [ ] Dispatch job instead of direct sync (for reliability)
- [ ] Configure queue worker
- [ ] Implement retry logic for failed syncs

### Phase 8: Testing
- [ ] Test OAuth flow (connect/disconnect)
- [ ] Test sheet creation
- [ ] Test order sync (create new order)
- [ ] Test order update sync
- [ ] Test token refresh
- [ ] Test error handling (API down, invalid token, etc.)
- [ ] Test with multiple sellers

### Phase 9: Documentation & Rollout
- [ ] Write user guide for sellers
- [ ] Create video tutorial
- [ ] Announce feature to sellers
- [ ] Monitor sync logs for errors

---

## Security & Privacy

### Security Measures

1. **Token Encryption**
   ```php
   // Encrypt tokens before storing
   use Illuminate\Support\Facades\Crypt;

   $user->google_access_token = Crypt::encryptString($accessToken);
   $user->google_refresh_token = Crypt::encryptString($refreshToken);
   ```

2. **HTTPS Only**
   - All OAuth flows must use HTTPS
   - Redirect URIs must be HTTPS in production

3. **Token Expiry**
   - Access tokens expire after 1 hour
   - Automatically refresh using refresh token
   - Implement token refresh before each API call

4. **Scope Limitation**
   - Only request necessary scopes:
     - `spreadsheets` (read/write sheets)
     - `drive.file` (create files only, not access existing)
     - `userinfo.email` (get email for verification)
   - DO NOT request full Drive access

5. **Rate Limiting**
   - Google Sheets API has quotas:
     - 300 requests per minute per project
     - 60 requests per minute per user
   - Implement rate limiting in GoogleSheetsService
   - Use queue to batch requests

### Privacy Considerations

1. **Data Ownership**
   - Seller owns the Google Sheet (created in their Drive)
   - Admin cannot access seller's Google Sheet
   - Seller can delete/modify sheet anytime

2. **Transparency**
   - Clear explanation of what data is synced
   - Show which Google account is connected
   - Easy disconnect option

3. **Optional Feature**
   - Google Sheets sync is completely optional
   - Sellers can continue using system without connecting

4. **Token Revocation**
   - When seller disconnects, revoke token at Google
   - Clear all Google-related data from database

---

## Error Handling & Edge Cases

### Common Errors & Solutions

| Error | Cause | Solution |
|-------|-------|----------|
| **Token Expired** | Access token expired (1 hour) | Auto-refresh using refresh token |
| **Invalid Grant** | Refresh token revoked/expired | Prompt seller to reconnect |
| **Quota Exceeded** | Too many API requests | Queue requests, retry later |
| **Sheet Not Found** | Seller deleted sheet | Prompt to reconnect, create new sheet |
| **Network Error** | API unreachable | Queue for retry, log error |
| **Permission Denied** | Seller revoked access | Disable sync, notify seller |

### Edge Cases

1. **Seller Deletes Google Sheet**
   - System tries to append → gets 404 error
   - Solution: Create new sheet automatically OR prompt seller

2. **Seller Changes Google Account Password**
   - Refresh token may be revoked
   - Solution: Prompt seller to reconnect

3. **Seller Manually Modifies Sheet**
   - Row numbers may not match
   - Solution: Use order number to find row (not row index)

4. **Order Updated After Sync**
   - Find row by order number
   - Update entire row with new data

5. **Multiple Orders Created Quickly**
   - May hit rate limit
   - Solution: Use queue to batch requests

6. **Seller Disconnects Then Reconnects**
   - Old sheet may still exist
   - Solution: Create new sheet with timestamp in name

---

## Testing Scenarios

### Test Case 1: First-Time Connection
**Steps:**
1. Go to Settings → Google Sheets Sync
2. Click "Connect Google Account"
3. Select Google account and authorize
4. Verify redirect back to settings
5. Verify sheet created in seller's Google Drive
6. Verify header row added to sheet

**Expected:**
- ✅ Connection status shows "Connected as [email]"
- ✅ Google Sheet exists in seller's Drive
- ✅ Sheet has proper headers

---

### Test Case 2: Order Auto-Sync
**Steps:**
1. Ensure seller has Google Sheets connected
2. Create new order via sales page
3. Check Google Sheet

**Expected:**
- ✅ Order appears in Google Sheet within 5 seconds
- ✅ All order details are correct
- ✅ Last sync timestamp updated

---

### Test Case 3: Order Update Sync
**Steps:**
1. Create order (synced to sheet)
2. Update order status (e.g., add tracking number)
3. Check Google Sheet

**Expected:**
- ✅ Row updated with new data
- ✅ No duplicate rows created

---

### Test Case 4: Token Refresh
**Steps:**
1. Manually expire access token in database
2. Create new order
3. Check sync log

**Expected:**
- ✅ System auto-refreshes token
- ✅ Order syncs successfully
- ✅ New access token stored

---

### Test Case 5: Disconnect Account
**Steps:**
1. Go to Settings → Google Sheets Sync
2. Click "Disconnect"
3. Confirm disconnect
4. Create new order

**Expected:**
- ✅ Connection status shows "Not Connected"
- ✅ New order does NOT sync to Google Sheet
- ✅ Old sheet still exists in seller's Drive

---

### Test Case 6: Reconnect After Disconnect
**Steps:**
1. Disconnect Google account
2. Reconnect with same Google account
3. Create new order

**Expected:**
- ✅ New sheet created (with new timestamp in name)
- ✅ Order syncs to NEW sheet
- ✅ Old sheet untouched

---

## File Structure

```
app/
├── Http/
│   └── Controllers/
│       └── GoogleAuthController.php         # OAuth flow
│
├── Services/
│   └── GoogleSheetsService.php             # Google Sheets API logic
│
├── Listeners/
│   ├── OrderCreatedListener.php            # Trigger sync on new order
│   └── OrderUpdatedListener.php            # Trigger sync on order update
│
├── Jobs/
│   └── SyncOrderToGoogleSheets.php         # Queue job for sync
│
└── Models/
    └── GoogleSheetsSyncLog.php             # Sync log model

database/
└── migrations/
    ├── YYYY_MM_DD_add_google_sheets_to_users.php
    └── YYYY_MM_DD_create_google_sheets_sync_log.php

resources/
└── views/
    └── settings/
        └── google-sheets.blade.php         # Settings UI

routes/
└── web.php                                 # Routes for OAuth & settings
```

---

## Implementation Timeline

| Phase | Task | Estimated Time |
|-------|------|----------------|
| **Phase 1** | Google OAuth Setup | 1-2 hours |
| **Phase 2** | Database Layer | 1 hour |
| **Phase 3** | Google OAuth Implementation | 3-4 hours |
| **Phase 4** | Google Sheets Service | 4-6 hours |
| **Phase 5** | Event Listeners | 2 hours |
| **Phase 6** | Settings UI | 2-3 hours |
| **Phase 7** | Queue Implementation | 2 hours |
| **Phase 8** | Testing | 3-4 hours |
| **Phase 9** | Documentation & Rollout | 2 hours |
| **TOTAL** | | **20-26 hours** |

---

## Example: Google Sheet Format

**Sheet Name:** `John Doe - Sales Orders - 2025-11-20`

| Order No | Date | Customer Name | Phone | Email | Address | Products | SKU | Qty | Total | Payment | Status | Tracking |
|----------|------|---------------|-------|-------|---------|----------|-----|-----|-------|---------|--------|----------|
| ORD-001 | 2025-11-20 | Ahmad Ali | 0123456789 | ahmad@email.com | 123 Jalan Ampang, KL | Product A, Product B | SKU-001, SKU-002 | 2, 1 | RM 150.00 | Online Banking | Processing | TRACKING123 |
| ORD-002 | 2025-11-20 | Siti Fatimah | 0129876543 | siti@email.com | 45 Jalan Tun Razak, KL | Product C | SKU-003 | 1 | RM 80.00 | COD | Completed | TRACKING456 |

---

## Benefits Summary

### For Sellers
- ✅ **Real-time tracking** - See orders instantly
- ✅ **Own their data** - Sheet is in their Google Drive
- ✅ **Custom analysis** - Can create charts, formulas
- ✅ **Integration** - Can connect to other Google tools
- ✅ **Backup** - Automatic backup in cloud
- ✅ **Mobile access** - View on phone via Google Sheets app

### For Admin
- ✅ **Less support requests** - Sellers self-serve
- ✅ **No manual exports** - Automated process
- ✅ **Improved UX** - Modern integration
- ✅ **Competitive advantage** - Unique feature

### For System
- ✅ **Scalable** - Each seller has own sheet
- ✅ **Reliable** - Google's infrastructure
- ✅ **Secure** - OAuth 2.0 standard
- ✅ **Maintainable** - Clean architecture

---

## Potential Enhancements (Future)

1. **Custom Field Mapping**
   - Let seller choose which columns to sync
   - Custom column order

2. **Multiple Sheets**
   - One sheet per month
   - Separate sheet for different product categories

3. **Bi-directional Sync**
   - Update order status from Google Sheet
   - (More complex, requires webhooks)

4. **Google Data Studio Integration**
   - Auto-create dashboard template
   - Visual reports from sheet data

5. **Other Integrations**
   - Microsoft Excel Online
   - Airtable
   - Notion

---

## Related Documents
- Google Sheets API Documentation: https://developers.google.com/sheets/api
- OAuth 2.0 for Web Server Applications: https://developers.google.com/identity/protocols/oauth2/web-server
- Laravel Events: https://laravel.com/docs/events
- Laravel Queues: https://laravel.com/docs/queues

---

**End of Document**
