Comprehensive technical architecture of iamovi.github.io. Zero hand-waving: proxy routing, database schemas, real-time Telegram notification webhooks, background cron jobs, and sound synthesis explained.
The site is fully static with zero build steps or server-side frameworks. Dynamic capabilities (guestbook, reactions, visitor counter, contact messages, real-time status) are powered by serverless cloud integrations.
/proxy, injects
secret Supabase API key, handles CORS headers, and routes notifications to
Telegram.
The serverless worker at <worker-domain>.workers.dev serves three distinct
routing responsibilities:
| Route | Method | Functionality |
|---|---|---|
/proxy/* |
GET, POST, OPTIONS | Rewrites path to Supabase REST/RPC API with secret SUPABASE_ANON_KEY. |
/notify |
POST | Formats and pushes incoming user submissions to Telegram Bot API. |
/webhook |
POST | Receives incoming Telegram updates (e.g., bot /about command handling).
|
To eliminate polling or manual database checks, the Cloudflare Worker contains a dedicated
notification dispatcher (/notify) connected to a private Telegram bot channel.
Input strings are clipped to safe buffer lengths before sending to Telegram's
sendMessage API, preventing payload overflow attacks while enforcing origin
verification checks (Origin: https://iamovi.github.io).
Data persistence is managed via Supabase PostgreSQL tables. Security is strictly maintained using PostgreSQL Row Level Security (RLS) policies.
| Table | Description | Read Policy | Insert Policy | Update/Delete |
|---|---|---|---|---|
guestbook |
Messages & threaded reply nodes | Public (anon) | Public (anon) | Authenticated (admin) |
reactions |
Emoji reactions across site assets | Public (anon) | Public (anon) | Blocked |
status |
Single-row header status message | Public (anon) | Blocked | Authenticated (admin) |
visits |
Daily visitor session log | Public (anon) | Public (anon) | Blocked |
Threaded conversations use a self-referential foreign key inside a single database table:
The frontend retrieves all rows in a single query ordered by created_at ASC, then
constructs a nested tree in JavaScript:
buildTree(all, null) isolates top-level roots (where
parent_id === null), sorted newest first.
parent_id === parent.id, sorted
chronologically.
escapeHtml() before embedding into nested
indent structures.
ON DELETE CASCADE to purge all sub-replies cleanly.
Emoji reactions (💀 🔥 👾 [lol]) support projects, blog posts, and guestbook comments.
Instead of dispatching one network request per card, loadReactionCounts() combines all
visible items into a single batched OR REST query, minimizing database connections.
Reaction states are stored locally per device using keys formatted as
r:target_type:target_id:reaction in localStorage. Clicking a reaction
immediately increments UI tallies; if the POST call fails, the state automatically reverts.
The banner status message ("ovi says —") relies on an automated PostgreSQL trigger to
keep timestamp metadata updated on edit.
The visitor counter relies on a PostgreSQL Remote Procedure Call (RPC) bound explicitly to Bangladesh
Time (Asia/Dhaka, UTC+6):
Sessions are guarded using sessionStorage so tab reloads do not trigger duplicate counts
during an active session.
To keep the free-tier database under size quotas, the PostgreSQL pg_cron extension runs
a scheduled deletion job daily:
Located at /admin/ (marked with noindex meta tags), the control
panel provides site administration via Supabase Auth email/password login.
Upon successful authentication, the generated JWT token is sent with all mutating requests via the
Authorization: Bearer <JWT> header, enabling RLS policies for database mutation
and comment moderation.
All UI interaction sounds (hover taps, click clacks, menu opens, page loads) are synthesized procedurally in real-time via standard browser Web Audio API nodes in sounds.js — zero external sound files required.
| Sound Action | Audio Graph Components |
|---|---|
| Page load | Sawtooth sweep + noise buffer burst + sine thud layered |
| Menu open/close | Bandpass noise + frequency ramp oscillator |
| Button click | High-frequency bandpass noise + typewriter square wave decay |
| Hover tap | Low-gain (vol 0.04) sine rise with soft noise tap |
The main portfolio operates as a lightweight single page with pure CSS display switching:
showSection(name) toggles CSS classes without full
page reloads, persisting navigation state to sessionStorage.| Service | Role | Tier / Cost |
|---|---|---|
| GitHub Pages | Static site hosting (HTML/CSS/JS) | Free ($0) |
| Supabase | PostgreSQL database, Auth, REST/RPC API | Free Tier ($0) |
| Cloudflare Workers | Security proxy, CORS headers, Telegram dispatch | Free Tier ($0) |
| GitHub Actions | Automated workflow pinging Supabase to prevent project pausing | Free ($0) |
.github/workflows/keep-supabase-alive.yml) pings Supabase periodically to prevent the
free tier database from pausing due to inactivity.