AkaiBlogs is a high-performance, developer-focused blogging and secure collaborative messaging platform. It is engineered with a zero-trust End-to-End Encryption (E2EE) messaging protocol, a custom block-based content editor, and a containerized local infrastructure via Docker Compose.
The main feed is backed by a custom, asynchronous personal recommendation scorer. Trending weights and interests decay dynamically based on time and engagement.
A custom-built block content engine that serializes nested layout blocks (text, headings, image objects, lists, code) into a single structured JSON schema.
Secure chat sessions powered by client-side Web Crypto and Socket.IO. Features include real-time typing indicators, read receipts, and user presence tracking.
flowchart TD
subgraph Client ["Client Browser (Next.js Frontend)"]
UI["User Interface (Zustand State)"]
Editor["Custom Block Editor"]
WebCrypto["Web Crypto API (ECDH / AES-GCM)"]
IDB["IndexedDB (Secure Private Key)"]
end
subgraph Containerized_Edge ["Docker Containerized Layer"]
App["App Container (Next.js App)"]
Socket["Socket Container (Socket.io Server)"]
Workers["Workers Container (BullMQ Workers)"]
end
subgraph Storage ["Database & Search Infrastructure"]
PG["Supabase Postgres"]
Redis["Redis Container (Cache / BullMQ Broker)"]
Algolia["Algolia Search Index"]
end
UI -->|1. Authenticates & Fetches Session| App
UI -->|2. Opens WebSocket Connection| Socket
UI -->|3. Fetches / Resolves Peer Public Keys| App
UI -.->|4. Generates Shared Secret & Encrypts Locally| WebCrypto
WebCrypto <-->|Read / Write Keys| IDB
App <-->|SQL Operations| PG
App -->|Publish Jobs| Redis
App <-->|Cache Reads/Writes| Redis
Socket <-->|Presence & WebSocket State| Redis
Socket -->|Writes Messages| PG
Workers <-->|Consumes & Dispatches Jobs| Redis
Workers -->|Updates Database Records| PG
PG -->|Database Webhooks| Algolia
UI -->|Instant Search Requests| Algolia
- Asymmetric Key Exchange: During registration, clients generate an ECDH P-256 key pair. The private key remains stored locally inside IndexedDB and never leaves the device. The public key is uploaded to Supabase.
- Shared Secret Derivation: Before transmitting messages, the sender derives a unique shared key using their local private key and the receiver's public key.
- Symmetric Encryption: Plaintext messages are encrypted client-side using AES-256-GCM with a cryptographically secure random Initialization Vector (IV). Only ciphertext and the IV are stored on the database.
- Auto-Healing: If the database is wiped or reset, the client dynamically detects the missing public key, regenerates the keypair, updates IndexedDB, and synchronization recovers automatically.
- Designed from scratch to avoid heavy library dependencies.
- Serializes rich content into a clean, nested JSON block format, supporting paragraph, headings, code snippets, lists, and dynamic media embeds.
- Offers better payload compression and faster client-side parsing than traditional HTML string text stores.
- Leverages BullMQ and Redis to dispatch long-running operations away from the main thread.
- OTP Email Worker: Dispatches mail via Nodemailer when authentication codes are requested.
- Trending Feed Engine: Recomputes feed items based on post interaction scores (Views, Likes, Comments) and age (decays over time).
- Analytics Worker: Tracks user category weights asynchronously to personalize feed indexes.
- Rather than performing heavy resource-intensive SQL query matching (
LIKE %query%) on PostgreSQL, search query matching is decoupled to Algolia. - To prevent data drift, a secure Supabase Database Webhook is configured to trigger on any
INSERT,UPDATE, orDELETEevents within theBlogtable. - These webhooks dispatch payload modifications to a Next.js Edge handler route (
/api/webhooks/supabase), which sanitizes the data using custom transformers and updates the Algolia index in real-time.
- Features a production-safe Prisma seed script (
prisma/seed.ts) that initializes the local schema with clean mock data. - Creates a default administrator profile (
demo_ronin), secures it usingbcryptpassword hashing, and populates categorized posts under Technology, Lifestyle, and Design classes to allow developers to experience the personalized feed routing instantly upon cloning.
- Frontend: Next.js 16 (App Router), React 19, Zustand, Tailwind CSS, Lucide Icons, Web Crypto API
- Backend: Next.js Serverless Routes, Socket.io, BullMQ (Workers)
- Databases: Supabase PostgreSQL (Prisma ORM), Upstash Redis
- Search: Algolia Instant Search
- Testing: Playwright (E2E testing), Vitest (Unit/API testing)
- DevOps: Docker, Docker Compose, GitHub Actions CI
Follow these steps to run the complete environment locally.
Make sure you have installed:
- Node.js (v20+ recommended)
- Docker Desktop (to run Redis & Postgres easily)
git clone https://github.com/ggoswami777/akaiblogs.git
cd akaiblogsnpm installCreate a .env file in the root of the project:
cp .env.example .envFill out the variables inside .env. Here is a guide:
# Database (Supabase or Local Postgres)
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/akaiblogs"
# Auth (Generate a secure string)
JWT_SECRET="generate_a_random_jwt_secret_key"
# Email Verification (Gmail SMTP config)
GMAIL_USER="your-email@gmail.com"
GMAIL_APP_PASSWORD="your-16-character-gmail-app-password"
EMAIL_FROM_NAME="AkaiBlogs Support"
OTP_EXPIRY_MINUTES=10
# Redis & WebSockets
REDIS_URL="redis://localhost:6379"
NEXT_PUBLIC_SOCKET_URL="http://localhost:4000"
SOCKET_PORT=4000
NEXT_PUBLIC_APP_URL="http://localhost:3000"
# UploadThing (For Blog Cover Images)
UPLOADTHING_TOKEN="your_uploadthing_token_here"
# Algolia Config
NEXT_PUBLIC_ALGOLIA_APP_ID="your_algolia_app_id"
ALGOLIA_ADMIN_API_KEY="your_algolia_admin_key"
NEXT_PUBLIC_ALGOLIA_SEARCH_KEY="your_algolia_search_key"
# Supabase Webhooks Security
SUPABASE_WEBHOOK_SECRET="generate_a_secure_webhook_passphrase"Generate the Prisma Client and migrate your database:
npx prisma db pushRun the seed script to create test users and default blog posts:
npm run db:seedYou can run the application using either Docker Compose or npm scripts locally.
Start all services (Frontend, Socket server, Workers, and Redis instance) in containerized isolation:
docker-compose up --buildIf you prefer running without Docker containers:
# Starts Next.js app, Socket.IO server, and background workers concurrently
npm run dev:servicesOpen http://localhost:3000 to view the application.
Unit and integration tests are located in /tests.
# Run tests once
npm run test
# Run tests in watch mode
npm run test:watch
# Generate test coverage reports
npm run test:coverageE2E browser automation tests are located in /e2e. Ensure you build the app first:
npx playwright install
npm run build
# Run E2E tests headlessly
npm run test:e2e
# Run E2E tests in the Interactive UI runner
npm run test:e2e:ui

