← all cases
case study · EurasianTech · June 2025 — now

GRID — a B2B business-process automation platform

A multi-tenant platform: form builder, requests, approval chains, logs, an admin panel with IAM permissions. No screenshots — the project is internal. So this case is built on diagrams and reasoning.

Vue 3multi-tenantIAMinternal product

The task

Several tenant companies work in one system: they build forms for their processes, run requests through approval chains, keep logs. Permissions live at the IAM level: who sees, who approves, who administers.

I work as a frontend developer on the product team: interfaces for the form builder, requests, logs and admin panel, plus the client-side architecture.

What was hard

01

A frontend architecture you cannot break by accident

Three layers between the server and the screen: api.js knows HTTP, services know the domain, composables know state. Components are “dumb”: they only render, hold no logic, and never call api.js directly — forbidden by linter rules, not by verbal agreement. The allowlist of legacy imports is pinned down and keeps shrinking.

api.jsHTTP, nothing elseservices/domain logiccomposables/state and reactivitycomponents“dumb”: render onlyeslintno-restricted-importslayer boundarieschecked in CIlegacy imports:2024 ▮▮▮▮▮▮ 142025 ▮▮▮ 6now ▮ 2 ↓
02

One filter, two data strategies

Stages belong to a form, but request lists come in two kinds: logs bound to a single form, and mixed lists whose rows come from different forms with different stage sets. There is no single way to build the options — so two strategies hide behind one filter. A capability matrix pins down which section supports which filters, so the UI never draws a filter the backend will not accept.

stage filterstages belong to the form“from form” strategylog: a single form,stages known up front“from rows” strategymixed list: stages arecomputed from loaded rowscapability matrixform log✓ filter from formmixed list✓ filter from rowsarchive— no stage filter
03

A bug whose symptom and cause live in different layers

Navigation broke in the navbar, but the cause lived two layers below: while parsing the IAM response, a role string was spread — turning into an array of characters. Each “character role” was then faithfully processed by the whole chain. Bugs like this are the argument for layered architecture: the search path was short because the layers were not mixed.

What was done

  • Form builder and requests flowing through approval chains
  • Operation logs and an admin panel with IAM permissions
  • A three-layer frontend architecture enforced by linter rules
  • A stage filter with two encapsulated data strategies

The result

Architecture rules are checked by the linter in CI and do not depend on team memory. The platform keeps growing; the project is ongoing.

A similar task?

A B2B platform, complex processes, access permissions — let’s talk.

Discuss a project
Asanali · Astana2026 · built without a site builder