Backend Services
The backend is a microservices monorepo in the blitz repo, built on Bun + Elysia.
Tech Stack
| Layer | Technology |
|---|---|
| Runtime | Bun (not Node.js) |
| Framework | Elysia (not Express/Fastify) |
| ORM | Prisma with PostgreSQL |
| Language | TypeScript |
| Testing | Bun built-in test runner |
| Dependency Injection | InversifyJS |
Repository Structure
blitz/src/
├── apps/ # Deployable microservices
├── packages/ # Domain business logic (dual-package pattern)
├── libs/ # Shared libraries (@blitz/lib-*)
└── playground/ # Experimental projectsDual-Package Pattern
Each domain is split into two packages:
*a— API layer: controllers, services, schemas, event handlers*d— Data layer: Prisma schema, migrations, generated client*wf(some domains) — Temporal workflow definitions
Example: casha + cashd = complete cash domain.
Never import generated Prisma clients directly — use factory functions:
// Correct
import { createDefaultCashClient } from "@blitz/cashd";
// Wrong
import { PrismaClient } from "@blitz/cashd/generated";Domain Packages
| Domain | Packages | Description |
|---|---|---|
| Cash | casha, cashd | Cash management |
| Close Hub | closehuba, closehub-eclosed | Period close management |
| Invoice | invoicea, invoiced | Invoicing |
| Journal | journala, journald | Journal entries |
| Reconciliation | reconciliationa, reconciliationd | Reconciliation |
| Core System | coresystema, coresystemd | Core financial operations |
| Finance Base | finbasea, finbased | Shared finance domain |
| Mgmt | mgmta, mgmtd | Multi-tenancy management |
| System | systema, systemd | Users, auth, settings, agents, workflows |
Deployed Microservices (6 active)
| Service | Port | Role |
|---|---|---|
api | 10001 | API gateway — single entry point for all clients |
ws | 10002 | WebSocket server for real-time features |
agents | 10013 | AI agent execution |
excelrw | 10014 | Excel read/write |
emailprocessor | — | Async email processing worker |
wfw | — | Temporal workflow worker (minimum 1 GB RAM — crashes at 512 MB) |
wfw runs system, closehub, cash, coresystem, and invoice Temporal workers in parallel.
Additional Services (built, not yet deployed)
23 services exist in the monorepo; 17 are built and in GHCR but not actively running in staging or production. See Gaps & Roadmap.
API Gateway Pattern
The api service (port 10001) aggregates all domain controllers:
const endpoint = new Elysia({ prefix: "/api" })
.use(tenantInfoResolverPlugin)
.use(systemControllers)
.use(authenticator)
.guard({}, (app) => app.use(cashControllers).use(journalControllers) /* ... */);Controller → Service → Prisma Flow
// Controller
const endpoint = new Elysia().group("/payments", (app) =>
app.post("/filter", async ({ logger, cashPrisma, body }) =>
await PaymentService.filterInstances(logger, cashPrisma, body), {
body: queryFilterSchema
})
);
// Service — static methods, Prisma passed as parameter
export class PaymentService {
public static async filterInstances(logger, prisma, filter) {
const { orderBy, where } = QueryBuilder.createQuery(logger, filter, ...);
return await prisma.payment.findMany({ ...orderBy, ...where });
}
}Database
PostgreSQL with multi-schema design. Two databases:
- finance DB:
cash,closehub/eclose,journal,invoice,finbase,reconciliation,sys - mgmt DB:
tm(tenant management)
Each *d package has its own Prisma schema targeting specific schemas:
generator client {
provider = "prisma-client"
output = "../generated"
runtime = "bun" // required
engineType = "client"
}
datasource db {
provider = "postgresql"
schemas = ["cash", "finbase", "sys"]
}Multi-Tenancy
Via @blitz/lib-tenancy — header-based (x-blitz-tenant-id) or domain-based. Toggle: TENANCY_ENABLED=true|false.
Available Elysia Context Services
Controllers receive these from DI:
loggerrootContainerbucketManagementService(RustFS)queueService(RabbitMQ)eventEmitterService{domain}Prisma(e.g.cashPrisma,journalPrisma)
Workflows (Temporal)
The wfw service runs Temporal workers. Workflow definitions live in *wf packages. Temporal UI is available on the Railway internal network.