Skip to content

System Architecture

Complete technical documentation of Skigk Søkeapp's system design.

High-Level Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Browser / Client                        │
│                   (Angular 20 SPA)                          │
│                                                             │
│  ┌──────────────────┐  ┌──────────────────────┐            │
│  │  UI Components   │  │  Service Layer       │            │
│  │ - Search Input   │  │ - AuthService        │            │
│  │ - File List      │  │ - DriveService       │            │
│  │ - Summary Panel  │  │ - GeminiService      │            │
│  └──────────────────┘  └──────────────────────┘            │
└─────────────────────────────────────────────────────────────┘
          ↓                        ↓                    ↓
┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐
│  Google OAuth    │  │ Google Drive API │  │ Google Gemini API│
│  Authorization   │  │  File Search     │  │  AI Summaries    │
│                  │  │  File Content    │  │                  │
└──────────────────┘  └──────────────────┘  └──────────────────┘
          ↓                        ↓                    ↓
      Google Cloud Platform (APIs)

Component Overview

Frontend (Angular 20)

app.component.ts - Main application component - Handles search input and state management - Manages search debouncing with RxJS - Displays search results - Triggers AI summarization

Services:

  1. AuthService (src/services/auth.service.ts)
  2. Manages Google OAuth 2.0 authentication
  3. Handles token lifecycle
  4. Manages user profile
  5. Provides logout functionality

  6. DriveService (src/services/drive.service.ts)

  7. Searches files across all Drives
  8. Retrieves file content
  9. Exports Google Docs/Sheets to text
  10. Handles Drive API errors

  11. GeminiService (src/services/gemini.service.ts)

  12. Calls Google Gemini API
  13. Generates file summaries
  14. Handles summarization errors
  15. Returns formatted summaries

Models:

  • DriveFile - Represents a searchable file
  • User - Represents authenticated user

Data Flow

Search Flow

User Types → Input (debounced) → Search Subject
                                    ↓
                        DriveService.searchFiles()
                                    ↓
                        Google Drive API
                                    ↓
                        Files array returned
                                    ↓
                        Display in UI

Summarization Flow

User clicks "Get Summary" → GeminiService.summarizeContent()
                                    ↓
                        DriveService.getFileContent()
                                    ↓
                        Google Gemini API
                                    ↓
                        Summary text returned
                                    ↓
                        Display below file

API Specifications

Google Drive API

Endpoint: https://www.googleapis.com/drive/v3/files

Search Query Parameters:

q=fullText contains '{query}'&
corpora=allDrives&
includeItemsFromAllDrives=true&
supportsAllDrives=true&
pageSize=20

Response:

{
  "files": [
    {
      "id": "file-id",
      "name": "Document Name",
      "mimeType": "application/vnd.google-apps.document",
      "owners": [{"displayName": "John Doe"}],
      "modifiedTime": "2026-01-17T10:00:00Z",
      "webViewLink": "https://drive.google.com/file/d/{id}/view"
    }
  ]
}

Google Gemini API

Endpoint: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent

Request:

{
  "contents": [{
    "parts": [{
      "text": "Summarize the following file content:\n\n{content}"
    }]
  }]
}

Response:

{
  "candidates": [{
    "content": {
      "parts": [{
        "text": "Summary of the file..."
      }]
    }
  }]
}

Authentication Flow

OAuth 2.0 Authorization Code Flow

1. User clicks "Logg inn"
              ↓
2. Redirect to Google OAuth Consent Screen
              ↓
3. User authorizes permissions
              ↓
4. Google redirects with authorization code
              ↓
5. Client exchanges code for access token
              ↓
6. Token stored in localStorage
              ↓
7. Token used for all Drive API requests

Required Scopes: - https://www.googleapis.com/auth/drive.readonly - Read Drive files - https://www.googleapis.com/auth/userinfo.profile - Read user profile - https://www.googleapis.com/auth/spreadsheets.readonly - Read Sheets

State Management

Signal-Based (Angular 20):

// Reactive signals in app.component.ts
searchQuery = signal('');
isLoading = signal(false);
isSummarizing = signal(false);
summaries = signal<Map<string, string>>(new Map());

No Redux/NgRx: - Uses Angular's built-in Signals for reactivity - Computed signals for derived state - Effects for side effects (logging, analytics)

Deployment Architecture

Firebase Hosting

Configuration: firebase.json

{
  "hosting": {
    "public": "dist",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

Benefits: - ✅ Global CDN distribution - ✅ Automatic SSL/HTTPS - ✅ Serverless (no backend needed) - ✅ Built-in analytics - ✅ 99.95% uptime SLA

Build Pipeline

Source Code (TypeScript)
        ↓
Angular Compiler
        ↓
Optimized JavaScript (minified)
        ↓
dist/ folder
        ↓
Firebase Hosting
        ↓
Global CDN

Security Considerations

OAuth Scopes

  • ✅ Uses drive.readonly - Cannot modify files
  • ✅ No delete permissions
  • ✅ No write permissions
  • ✅ Respects Google Drive permissions

API Keys

  • ✅ OAuth tokens stored in localStorage
  • ✅ Tokens have expiration (1 hour typically)
  • ✅ Automatic token refresh
  • ✅ No credentials in code

CORS & Origins

  • ✅ Authorized origins configured in Google Cloud
  • ✅ Only allows requests from whitelisted domains
  • ✅ Prevents cross-origin attacks

Performance Optimizations

Frontend

  1. Search Debouncing - 300ms debounce on input
  2. Lazy Loading - Results loaded as user scrolls
  3. Code Splitting - Angular auto-splits bundles
  4. Caching - Browser caches Drive API responses

Backend (Google APIs)

  1. Page Size - Limited to 20 results per request
  2. Pagination - User can load more results
  3. Indexing - Google Drive has built-in indexing

Scalability

Current Limits

  • Users: 100+ concurrent users
  • Files Searchable: 1,000,000+ (Google Drive limit)
  • Search Speed: <2 seconds typically
  • Concurrent Requests: Limited by Google API quotas

Future Scaling

For 1,000+ users or enterprise deployments:

  1. Add Backend Cache:
  2. Redis for search results
  3. Reduces Google API calls

  4. Multi-Region Deployment:

  5. Replicate to multiple Firebase regions
  6. Reduce latency globally

  7. Database Integration:

  8. Store search history
  9. Persist user preferences
  10. Analytics and metrics

  11. Rate Limiting:

  12. Per-user quotas
  13. Prevent API abuse

Technology Stack

Component Technology Version
Frontend Framework Angular 20
Language TypeScript 5.0+
Styling Tailwind CSS 3.0+
State Management Angular Signals 20
Async RxJS 7.0+
Build Tool Vite/Angular CLI Latest
Deployment Firebase Hosting Latest
APIs Google Cloud APIs v3

Code Organization

src/
├── app.component.ts       # Main component
├── config.ts              # Configuration
├── env.ts                 # Environment variables
├── components/            # Reusable components
│   └── file-icon.component.ts
├── models/                # Data models
│   ├── drive-file.model.ts
│   └── user.model.ts
└── services/              # Business logic
    ├── auth.service.ts
    ├── drive.service.ts
    └── gemini.service.ts

Next Steps