Overview
Kasu.AI is an AI-powered approval workflow platform that routes, reviews, and resolves approval requests using a combination of rule-based logic and LLM decision-making. Before Kasu, approval chains at client organizations ran over email threads and spreadsheets — cycles that routinely stretched 1–3 days.
The goal was to collapse that into minutes by automating routing decisions, surfacing the right context to approvers, and integrating a conversational interface (Dialogflow) so approvers could query the system in natural language.
My Role
I was the full-stack engineer responsible for the BFF layer and the approval engine UI. On the frontend I owned the real-time approval state system; on the backend I designed the Next.js API routes that formed the BFF between the React client and the upstream GraphQL services.
- Designed and implemented the BFF (Next.js API routes) — aggregated calls to the GraphQL service layer, transformed responses into typed DTOs, and enforced auth at the BFF boundary
- Built the RTK Query integration — defined entity tags for approval requests, handled optimistic updates for status toggles, and wrote invalidation logic that kept the list view consistent across concurrent sessions
- Integrated Dialogflow for the conversational query interface — approvers could ask "show me pending requests over $10k" and get filtered results without navigating the UI
- Implemented real-time approval state propagation using polling with short TTL (SSE upgrade was scoped for Phase 2)
Architecture
React (RTK Query)
│
▼
Next.js BFF (API routes)
├── auth validation (JWT verification)
├── data aggregation (4 upstream calls → 1 response)
└── Dialogflow intent routing
│
▼
GraphQL service layer
├── Approval engine (rule-based + LLM decision node)
└── Audit log service
│
▼
Upstream data sources (ERP, HRMS, finance systems)
The BFF was the critical seam — it let the frontend stay thin while the service layer evolved independently. Changes to the upstream GraphQL schema were absorbed at the BFF without touching any React component.
Key Challenges & Decisions
Real-time approval state across concurrent sessions. Multiple approvers could be looking at the same request list. If approver A acted on a request, approver B's list needed to reflect that immediately. We solved this with short-TTL polling (5s) with RTK Query's refetchOnFocus and refetchOnReconnect enabled — a pragmatic choice that avoided WebSocket infrastructure complexity. The upgrade path to SSE is documented but not yet needed given usage patterns.
BFF vs. direct GraphQL from the client. The client team initially wanted to query GraphQL directly. I pushed for the BFF because: (1) we needed to aggregate 4 schema types into a single approval context object, (2) auth enforcement belonged on the server, not the client, and (3) Dialogflow routing had to happen server-side. The tradeoff was an additional network hop, which RTK Query's caching made negligible.
LLM decision node placement. The LLM was used for non-trivial routing decisions (e.g., "this request has ambiguous category — route to finance or legal?"). Placing it inside the approval engine (server-side) rather than in the UI meant: consistent decisions, auditable outputs, and no LLM SDK leaking to the client bundle.
Impact & Outcomes
- Approval cycle reduced from 1–3 days to under 30 minutes — the stated goal of the product
- BFF aggregation replaced multiple sequential client-side fetches with a single typed server response
- Dialogflow integration let approvers query the system in natural language without navigating the full UI
Visualization
Animated workflow diagram coming in Phase 3 — will trace an approval request from React UI through the BFF, GraphQL layer, and LLM decision node.