
Artimus — AI-Powered Exam Platform
An event-driven microservices platform for banking exam preparation: Fastify backend services behind an API gateway, Kafka with transactional outbox, schema-per-service Postgres, and AI question generation.
Timeline
2025 — 2026
Role
Solo — architecture, backend services, frontend, infrastructure
Status
In-progressTechnology Stack
Key Challenges
- Enforcing strict service decoupling without the operational overhead of 5 separate database servers
- Guaranteeing reliable event publishing atomically with local database transactions via outbox pattern
- Securing exam integrity with authoritative server-side scoring and immutable attempt snapshots
- Offloading heavy AI question generation and CSV exports to asynchronous background workers
Key Learnings
- The Transactional Outbox pattern prevents distributed data drift between services and Kafka
- Schema-per-service with restricted PostgreSQL roles physically blocks cross-service joins
- Opaque tokens with Redis caching simplify session revocation during live exam attempts
- Precomputing read models via Kafka consumers keeps high-traffic analytics dashboards fast
Overview
Artimus is an event-driven examination and analytics platform engineered for banking and competitive test preparation. It handles high-concurrency exam attempts, real-time analytics rollups, and asynchronous AI-assisted question generation.
To isolate write-heavy exam submissions from analytics and AI jobs, the system is architected as an event-driven microservices platform inside a Turborepo monorepo.
System Architecture
The system decouples responsibilities into dedicated Fastify microservices behind an API Gateway, communicating asynchronously over Kafka (Redpanda) and caching active session state in Redis.
Microservices Breakdown
| Service | Primary Stack | Core Responsibility |
|---|---|---|
gateway | Fastify, Redis | Reverse proxy, rate limiting, request validation, token denylist verification |
identity-svc | Fastify, Prisma | User lifecycle, authentication, opaque token generation, blast-radius isolation |
catalog-svc | Fastify, Gemini API | Question bank, subjects, chapters, and async AI question generation |
assessment-svc | Fastify, Vitest | Timed attempt lifecycle, immutable question snapshots, authoritative scoring |
analytics-svc | Fastify, MinIO | Kafka consumer read-models, percentile calculations, CSV export worker |
notification-svc | Fastify, Web Push | Real-time announcements, browser push notifications, Server-Sent Events (SSE) |
Key Technical Decisions
1. Schema-per-Service Database Isolation
Instead of provisioning five separate PostgreSQL database clusters, Artimus runs a single PostgreSQL 16 instance with dedicated schemas (identity, catalog, assessment, analytics, notification) and restricted database user roles. Each service maintains its own Prisma schema, migrations, and connection pool. Cross-schema joins are physically revoked at the database level.
2. Transactional Outbox Pattern
When an assessment attempt completes, an event must be published to Kafka without distributed drift. Outgoing events are written to an outbox table inside the same local database transaction. A dedicated worker drains the outbox to Kafka, ensuring guaranteed at-least-once delivery paired with idempotent Redis consumer handlers.
3. Authoritative Server-Side Scoring & Snapshots
When a student starts an exam, an immutable snapshot of questions and grading criteria is written to attempt_snapshot. Scoring is executed server-side in assessment-svc with pure deterministic functions covered by unit tests, making client-side answer tampering impossible.
4. Asynchronous AI & Export Workers
Heavy tasks like Google Gemini quiz generation and large CSV analytics exports are offloaded from request handlers. Endpoints immediately return job IDs while background workers process the tasks and write artifacts to MinIO object storage.
Monorepo & Infrastructure
- Monorepo: Turborepo with pnpm workspaces
- Shared Packages:
packages/contracts: Zod DTO and event schemas (single source of truth)packages/kafka-kit: Transactional outbox publisher & idempotent consumerpackages/redis-kit: Redis client and centralized key managementpackages/observability: Structured Pino logging and OpenTelemetry trace propagation
- Infrastructure: Docker Compose (
docker-compose.yml), Caddy reverse proxy with automatic TLS
