System Architecture Deep Dive
Overview
The ITGPG website operates on a Thick-Client Serverless Architecture. It functions as a static Jekyll site hosted on GitHub Pages, but acts as a dynamic application in the browser.
To maintain a $0 infrastructure budget, all data fetching (study materials, certificates, newsletters, gallery images) is offloaded to the user’s browser, pulling directly from Google Drive and YouTube APIs.
1. Core Architecture
graph TD
subgraph "Hosting Layer (Free)"
GitHubPages[GitHub Pages]
end
subgraph "Client Layer (Student's Browser)"
UI[Static HTML/CSS]
JS[JavaScript Engine]
Cache[(sessionStorage)]
end
subgraph "Database Layer (Free)"
Drive[Google Drive API]
YouTube[YouTube Data API]
end
GitHubPages -- Serves static assets --> UI
UI -- Executes --> JS
JS -- Fetches data --> Drive
JS -- Fetches data --> YouTube
JS -- Caches response --> Cache
Cache -- Returns instant data --> UI
2. Build Pipeline
The project uses Jekyll to compile Markdown and Liquid templates into static HTML.
flowchart LR
A[Markdown Events] -->|Jekyll Build| D[Static HTML]
B[_data/ YAML Config] -->|Liquid Injection| E[config.js]
C[_includes / _layouts] -->|Jekyll Build| D
D --> F[Deployed to GitHub Pages]
E --> F
- Jekyll Execution: Merges
_layouts/default.htmlwith individual pages. - Configuration Compilation:
_data/site_config.ymlis parsed and serialized into a raw JavaScript object inassets/js/config.jsvia Liquid ({"API_KEY":"AIzaSyBd34cP4KHFKN0WyNNiqhlQ2HSM8j2tD_E","FOLDER_IDS":{"syllabusS2":"1qzlAm8Zi9RC11iwD2V2T0uU_8DMSlemE","newsletters":"14OT-O9JooQKzKxxL2bhLUUZkdB3MOSf8","faculty_development":"1yB9N4DKyGc3AL1EhGiPTgtpyPOlq8cvV","academic_calendar":"16a58BgCLN8h0SnGxjnYFGDdkfWqcuS49","certificates":"1vXU0cCwrYplFhmrGLu3MYuf1fVJeylWQ","gallery":"1vXU0cCwrYplFhmrGLu3MYuf1fVJeylWQ","pyq":{"sem_1":{"python":"1SPAJ_Azd-kVEc7l7rrerpmeQOeZJO2Xw","it":"1QvTM_Z80mrP7dTu9g9-dgGOdgtSzid-c","maths":"1xIFEVMpiB2wZvJL3KVRQKEdcecfUskLs","cse":"1O7ToNX0DIfhrB3K1ytSbPBxm8GhMNpqR","ech":"1JM5fS8mss8ViwNaO7sLpn4QF5btEX9WB"},"sem_2":{"Advance_python":"1SFSqASzR03MrKZ3neQFjxjBIhJVb6nUx","enginnering_maths_s2":"1TkyPmBgF9atrblZhIDwMcgKOB36FQTKN","Applied_maths_s2":"1P0h7Ol7a1et5I2E3hWuMb5nW1mKrpIFA","Modern_physics":"1KCKauTNQ8hyW-kj1sj-DPn1Zr9t_DpbC","enviromental_sustainability":"1_a51gVjCkEhuLYsXRjHHRqi1VTyEkvYH"},"sem_3":{"os":"1sWvegnzI20APrfIt07frmMX3ZXse4MLN","dbms":"1rKihco_dxwB9gB9xKAW96U8WaS9s8SX9","dsp":"1Epp-_61b6_bCZfW98MBAB0wNwHTBIC48","edm":"1viHPIpIpI_PswBzAyMMS8QUAsOF1p4Vh","oopj":"1zkn4Lq-lob58TDgSb0KwSkTBN3VffS_h"},"sem_4":{"csdf":"11KmApu8rlhekw9R9mapLsw7zAJPkjwtw","dmw":"1PBnsf6-UMIiYsEwALYWJ7_0xBbRfO2Ez","mcn":"1CAyBBW362FfhO0fBD_LwOi_GK4FJEK1b","fml":"1UONtiQfMBiJbO4QkZ2-ejmcDfohe8Vp-","es":"1k3GCTqT9CCSSkhvEUDsPzvunu2BjtEOd"}},"Notes":{"AIPD":"1qFeDy88uMM6thoNU9fy6xy4ohzO3bolMJeIFijF_mbU","Applied_maths":"1RI3gfrwmR-Muj8qujj2Wv_0mawZKDXxg","english":{"ES":"1ZxIE4Tjnsbl_VgnLY1b_4oy0dyjdzGWR","MPH":"1Cv82eCraCbeyBT_NVyMxDkOG2GB--E4G"},"gujarati":{"ES":"1PQ-HRdCURvnMYp274nppNjBvPGoMQSYf","MPH":"1w8mJkjdhw7lHJ_qxzMeuPGpRvWFL5QdL"}}},"yr_2024_2025":{"sem3":{"syllabus":"1Izl-nki7BKIvRyFJ_efTL18CiVKEzvyV"}},"yr_2025_2026":{"sem4":{"syllabus":"1nUND77k1CXaZNv6yjDTX8PSW3-3I3iCB"},"sem5":{"syllabus":"1L57gHa0FyEQBNjZ8aoU0KnL6MX9R1Rav","AIPD":"1tPzQopeOLOV7VF0_Y7ZLtGN4w95Tbrsu"}},"PLAYLIST_IDS":{"python":"PL5hA7O8RI2bPOSoX7l8zZIIuDQrc9b9wO","advPython":"PL5hA7O8RI2bMd6FrVKDz-VhKXNVezg_Ly","it":"PLZ3xYAWT5a-nskfWOvHd_Fvh4RZsedu7G","networking":"PL5hA7O8RI2bMBGjSduDQRYUCrNViAEee1","enginnering_maths":"PLs6nv4Vuoj-szyhRqc8PcTFTdFzDIJrfj","gtu_maths_2":"PLLfoR5ZJ0A_4ushGMb__Kvsk3ffqlrIr3","FSD":"PLWPirh4EWFpG2b1L3CL-OAPYcM25jLjXH","digital_markteting":"PL5hA7O8RI2bMH9S_-KbY7K-73hlrAyTHF","object_oriented_programming_java":"PLWKjhJtqVAbnklGh3XzZ4E8Jw9P9K2A1D","fundamentals_of_machine_learning":"PLWKjhJtqVAbm3m1QXg7EoSxKXWwRg8Zpq","web_development_php":"PLWKjhJtqVAbmGQoa6lN6a1xNq7kjP9B2h","foundation_ai_ml":"PLWKjhJtqVAbm3m1QXg7EoSxKXWwRg8Zpq","mobile_computing_networks":"PLWKjhJtqVAbnupwRFOq9zGOWjdvPRtCmO","advanced_java_programming":"PLWKjhJtqVAbnklGh3XzZ4E8Jw9P9K2A1D","mobile_application_development":"PLWKjhJtqVAbk3cFkeP2lQ6K6J9Z1nVU2q","cyber_security_digital_forensics":"PLWKjhJtqVAbm3m1QXg7EoSxKXWwRg8Zpq","software_development":"PLWKjhJtqVAbm7h1x3g8Yt7k7pXT3a7V7h","ui_ux":"PL5hA7O8RI2bPfFNLPitu1fZPI9J0y7Yqa"}}). - Deployment: Pushed to the
gh-pagesbranch or served directly via GitHub Actions.
3. Runtime & Request Lifecycle
When a student visits a dynamic page (e.g., Study Materials):
sequenceDiagram
participant Student
participant Browser
participant SessionStorage
participant GoogleAPI
Student->>Browser: Clicks "Semester 5 - AI"
Browser->>SessionStorage: Check cache for 'sem5_ai'
alt Cache Hit
SessionStorage-->>Browser: Return cached JSON
else Cache Miss
Browser->>GoogleAPI: fetch(Folder ID)
GoogleAPI-->>Browser: Return File List (JSON)
Browser->>SessionStorage: Save JSON to cache
end
Browser->>Browser: Parse JSON, strip extensions
Browser->>Browser: Inject HTML elements into DOM
Browser-->>Student: Display Study Materials
4. Configuration System
To isolate content managers from JavaScript logic, a strict “Zero-JS” pattern is enforced.
All IDs (Drive folders, YouTube playlists, API keys) live in _data/site_config.yml.
# _data/site_config.yml
API_KEY: "AIzaSy..."
FOLDER_IDS:
certificates: "1vXU0c..."
This is automatically injected into the global window.CONFIG object at build time, allowing the JS to access it dynamically without hardcoded values.
5. JavaScript Architecture
The JS layer is highly componentized:
config.js: Holds the globalCONFIGobject.YouTubeHandler.js: Standardized fetch wrapper for YouTube Data API v3 and Google Drive v3 API.- Page Controllers (
events.js,certificate-verification.js): Page-specific logic that maps API responses to the DOM.
Caching Strategy
To prevent Google API quota exhaustion (e.g., 50 students clicking folders simultaneously), aggressive caching is implemented via sessionStorage. Data is cached for the lifecycle of the browser tab.
6. CSS Architecture
We use Vanilla CSS with Bootstrap 5.3 handling the grid system and basic utility classes.
Styles are heavily scoped to prevent bleed:
main.css: Global variables (colors, fonts).components/: Navbar, footer, hero section.pages/: Specific page styles (e.g.,certificate-verification.cssholds the confetti animation logic).
7. Limitations & Technical Debt
Limitations
- API Quotas: Relying entirely on client-side fetching means that if usage spikes massively, the Google API daily quota could be exceeded, temporarily breaking dynamic pages.
- SEO for Dynamic Content: Because study materials are loaded via JS, search engine crawlers will not index the individual PDF links. (We mitigate this by heavily indexing the static pages).
Known Technical Debt
- No Global Error Boundaries: If
window.CONFIGfails to load, subsequent JS files will throw undefined errors.
8. Future Improvements
- Proxy Server (Cloudflare Workers): If API quotas become an issue, we can route Google API requests through a free Cloudflare Worker to cache requests globally, reducing hits to Google.
- Strict Typings: Converting the JS components to TypeScript (or adding JSDoc comments) to prevent runtime errors when
site_config.ymlshapes change. - Automated E2E Testing: Implementing Cypress or Playwright to simulate navigating folders to catch silent API failures before users notice them.