GAZAR

Principal Engineer | Mentor

How would you design a resource allocation app?

How would you design a resource allocation app?

In urban infrastructure, chambers serve as crucial connection points, facilitating various utilities. With the increasing demand for high-speed internet services, efficiently managing chambers becomes imperative. In this article, we'll delve into designing a web application using the Command Query Responsibility Segregation (CQRS) pattern to streamline chamber management.

And a bit more data in a table format:

Screenshot 2024-03-24 at 10.22.06 AM.png

The Problem

We've had an influx of new customers wanting our 10Gbps internet product! We need a way of identifying the

closest chamber to the potential customer, ensuring we have capacity to connect them, and give us a heads

up when we might need to increase capacity near a chamber.

Write a web application that allows a Vorboss sales team member to enter details about a new customer

ordering our 10Gbps internet product. The application should call a backend API that does the following:

Persist the details of the new customer in a data store

Provide the user with the ID of the closest chamber that has available capacity.

Alert the user if the nearest chamber doesn't have capacity, but still provide the next closest that does have capacity.

Alert the user if the provided chamber is now at capacity with the addition of the new customer.

Screenshot 2024-03-24 at 10.22.06 AM.png

Then High Level Architecture Design:

architecture-high-level.png

High Level API Design

Please have a look at our swagger here and These will be the lists

  • Auth (Login,Register,Forgot,Reset,Resend)
  • Package (ListPackages)
  • Chamber (AvailableChambersPerPackage)
  • Order (Create, GetAllByUser, Change, GetOrdersByUser)
  • User (GetProfile, GetAllCustomersCreatedByMe, create)

Two roles: sales | customer

UI layout and the User Flow:

ui-sketch.png

The Key points of implementations:

If you want to know the little issues and technical solutions:

  • How to write down seeding the data to postgres using Prisma
await prisma.$executeRaw`
    INSERT INTO "Chamber" (id, latitude, longitude, total_capacity, used_capacity, geom)
    VALUES
    (
        'VORB-X8734',
        51.52466903333144,
        -0.08320212364196779,
        100,
        70,
        ST_SetSRID(ST_MakePoint(-0.08320212364196779, 51.52466903333144), 4326)
    ),
    (
        'VORB-Z4784',
        51.523641015718525,
        -0.08601307868957521,
        100,
        10,
        ST_SetSRID(ST_MakePoint(-0.08601307868957521, 51.523641015718525), 4326)
    ),
    (
        'VORB-N2837',
        51.523434943212514,
        -0.08114755153656007,
        100,
        40,
        ST_SetSRID(ST_MakePoint(-0.08114755153656007, 51.523434943212514), 4326)
    ),
    (
        'VORB-V9345',
        51.52211691871454,
        -0.0851869583129883,
        100,
        30,
        ST_SetSRID(ST_MakePoint(-0.0851869583129883, 51.52211691871454), 4326)
    ),
    (
        'VORB-Q9547',
        51.523304662537235,
        -0.08331477642059326,
        100,
        70,
        ST_SetSRID(ST_MakePoint(-0.08331477642059326, 51.523304662537235), 4326)
    );
`;

  • Then make sure your Dockerfile for your backend works
FROM node:lts-iron as build
RUN apt-get update -y
RUN apt-get install -y openssl
RUN apt-get install -y apt-utils

ARG DATABASE_URL=""
ARG NODE_ENV=production
ARG PORT=8000
ARG JWT_SECRET=""

ENV NODE_ENV=$NODE_ENV
ENV PORT=$PORT
ENV DATABASE_URL=$DATABASE_URL
ENV JWT_SECRET=$JWT_SECRET

WORKDIR /app
COPY package*.json ./
RUN npm install 
RUN npm install --only=dev

COPY . .
RUN npx prisma generate

EXPOSE 8000
CMD ["npm", "start"]

  • And to query the closest chamber, you can use postgres native features:
const chambers = await pg.query( `
    SELECT * FROM "Chamber"
    ${ids?.length ? `WHERE id IN (${ids.join(",")})` : ""}
    ORDER BY ST_Distance(
      geom,
      ST_SetSRID(ST_MakePoint($1, $2), 4326)
    )
    LIMIT $3;
  `,
    [longitude, latitude, limit || 1]
  );

  • For DB you can just have a docker-compose.yml file
version: "3.8"
services:
  db:
    image: postgis/postgis
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      - "5432:5432"
    restart: unless-stopped
  • And for frontend, you can use RemixJS with Docker and Tailwind
FROM node:lts-iron as build
RUN apt-get update -y
RUN apt-get install -y openssl
RUN apt-get install -y apt-utils

ARG NODE_ENV=production
ARG PORT=3000
ARG REACT_APP_API_URL=http://localhost:8000

WORKDIR /app
ENV NODE_ENV=development
COPY package*.json ./
RUN npm install 

COPY . .
RUN npm run build
ENV NODE_ENV=production
ENV PORT=$PORT
ENV REACT_APP_API_URL=$REACT_APP_API_URL

EXPOSE 3000
CMD ["npm", "start"]
  • And Finally a docker-composer.yml on the root folder can handle everything easily
# docker compose 
version: '3.8'
services:  
  database: 
    container_name: app-database
    image: postgis/postgis
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    restart: unless-stopped
    volumes:
      - database-data:/var/lib/postgresql/data

  backend:
    container_name: app-backend
    build: 
      context: ./backend
      dockerfile: Dockerfile
      args:
        NODE_ENV: development
        DATABASE_URL: postgres://postgres:postgres@database:5432/mydb?schema=public&connect_timeout=300
        JWT_SECRET: randomsecret
        PORT: 8000
    ports:
      - "8000:8000"
    depends_on:
      - database
    links:
      - database
    restart: unless-stopped

  frontend:
    container_name: app-frontend
    build: 
      context: ./frontend
      dockerfile: Dockerfile
      args:
        NODE_ENV: production
        PORT: 3000
        REACT_APP_API_URL: http://backend:8000
    depends_on:
      - backend
    links:
      - backend
    ports:
      - "3000:3000"
    restart: unless-stopped
volumes:
  database-data:

Implementing CQRS in our chamber management application allows for efficient handling of commands and queries, optimizing resource allocation and enhancing user experience. By leveraging robust backend APIs and modern frontend frameworks, we can provide Vorboss sales team members with a streamlined order process while ensuring optimal chamber utilization.