Aleks Manov

Case studies

Selected work

Three systems, each described the same way: the problem, the approach, and what it achieved. Code is from the real implementation.

0012024InfrastructureIn production

DDoS Shield

Serverless request filtering and routing at the edge. Cloudflare Workers rate-limit abusive IPs and steer legitimate traffic to the nearest healthy origin.

Problem

Origin servers were absorbing bursts of abusive traffic directly. Filtering at the origin was too late: bandwidth was already consumed, and a single flood could degrade service for every region at once.

Approach

Move the decision to the edge. A Cloudflare Worker checks every request against a per-IP counter in Workers KV before it ever reaches an origin. Requests over the limit are rejected at the edge with a 429. Legitimate requests are routed using the request's geolocation: the worker picks candidate origins near the caller, probes them, and returns the healthiest one. Prometheus and Grafana watch origin health from the outside.

Outcome

Abusive traffic is dropped before it touches origin bandwidth, and users are served from the closest healthy machine. The system runs with no servers to patch and no capacity to pre-provision.

Stack

Cloudflare Workers · Workers KV · TypeScript · Docker · Prometheus · Grafana

The worker's hot path: rate-limit check against KV, then geolocation-aware origin selection.
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const RATE_LIMIT = 1;
    const TIME_WINDOW = 60;

    try {
      const ip = request.headers.get('x-real-ip');
      if (!ip) {
        return new Response('IP not found', { status: 400 });
      }

      // Rate limiting with KV store
      const count = await env.RATE_LIMIT_STORE.get(ip);
      if (parseInt(count || '0') >= RATE_LIMIT) {
        return new Response('Rate limit exceeded', { status: 429 });
      }

      await env.RATE_LIMIT_STORE.put(
        ip,
        (parseInt(count || '0') + 1).toString(),
        { expirationTtl: TIME_WINDOW }
      );

      // Intelligent VM selection
      const { country, city } = request.cf;
      const vmIpsArray = env.VMS.split(',');
      const selectedVms = selectVmsBasedOnLocation(vmIpsArray, { country, city });

      const bestVm = await findOptimalVm(selectedVms);
      return new Response(bestVm.ip);
    } catch (error) {
      return new Response('Service unavailable', { status: 503 });
    }
  }
};

Next · E-Commerce Engine

0022024Web applicationIn production

E-Commerce Engine

A storefront on Next.js with Strapi as the headless CMS and Stripe Checkout for payments. Editors manage the catalog; the frontend stays static and fast.

Problem

The store needed content editors to manage products without touching code, while keeping the customer-facing pages fast and the payment path secure. An all-in-one platform would have meant fighting its templates; a fully custom backend would have meant building a CMS from scratch.

Approach

Split the concerns. Strapi (backed by PostgreSQL) owns the catalog and gives editors a real admin UI. Next.js renders the storefront from Strapi's API, so product pages are statically generated and revalidated instead of computed per-request. Payment never touches the application server: the cart is handed to Stripe Checkout, which owns the card form, 3-D Secure, and receipts.

Outcome

Editors ship catalog changes without deploys, checkout is PCI-scoped to Stripe rather than the app, and the storefront serves static HTML for the pages customers actually browse.

Stack

Next.js · TypeScript · Strapi · PostgreSQL · Stripe · Tailwind CSS

Handing the cart to Stripe Checkout — the app never sees card data.
import { loadStripe } from '@stripe/stripe-js';
import { CartItem } from '@/types';

export async function createCheckoutSession(items: CartItem[]) {
  const stripe = await loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);

  const lineItems = items.map(item => ({
    price_data: {
      currency: 'usd',
      product_data: {
        name: item.name,
        images: [item.image],
      },
      unit_amount: item.price * 100,
    },
    quantity: item.quantity,
  }));

  const { error } = await stripe!.redirectToCheckout({
    lineItems,
    mode: 'payment',
    successUrl: `${window.location.origin}/success`,
    cancelUrl: `${window.location.origin}/cart`,
  });

  if (error) {
    console.error('Stripe error:', error);
  }
}

Next · CMS Core API

0032023BackendIn production

CMS Core API

The API behind a content management system: Express and PostgreSQL with a Redis cache in front, JWT auth, and Discord webhooks for operational notifications.

Problem

Content reads dominated the workload — the same pages requested far more often than they changed. Hitting PostgreSQL for every read made response times depend on database load, and the team had no immediate signal when something went wrong.

Approach

Put Redis between the API and the database with a small cache service that owns serialization and TTLs, so route handlers stay oblivious to caching. Auth is stateless JWT, which keeps the API horizontally scalable with no session store. Failures and notable events post to a Discord channel via webhook — the channel the team already watched, instead of a dashboard nobody opened.

Outcome

Hot content is served from memory instead of the database, the API scales by adding processes rather than tuning sessions, and operational events reach the team in the channel they already use.

Stack

TypeScript · Express.js · Redis · PostgreSQL · JWT · Discord API

The cache service: route handlers call get/set and never touch Redis directly.
import { createClient } from 'redis';
import jwt from 'jsonwebtoken';

class CacheService {
  private redis = createClient({
    url: process.env.REDIS_URL
  });

  async get<T>(key: string): Promise<T | null> {
    try {
      const data = await this.redis.get(key);
      return data ? JSON.parse(data) : null;
    } catch (error) {
      console.error('Cache get error:', error);
      return null;
    }
  }

  async set(key: string, value: any, ttl: number = 3600): Promise<void> {
    try {
      await this.redis.setEx(key, ttl, JSON.stringify(value));
    } catch (error) {
      console.error('Cache set error:', error);
    }
  }
}

export const cacheService = new CacheService();

Working on something similar? Get in touch.