AI-powered, multi-tenant university intelligence system designed for the University of Carthage (UCAR). Live Website: https://hack4ucar.ahmedxsaad.me/
UCAROS is a centralized, multi-tenant university platform with a working end-to-end pipeline from data ingestion to analytics and reporting.
- A full microservices backend behind Kong with JWT auth, tenant context, and role-aware APIs.
- File/manual ingestion plus preprocessing and Kafka-based handoff to core management.
- Core academic/administrative data management in PostgreSQL with tenant isolation.
- Analytics, anomaly detection, notifications, and report generation workflows.
- A Next.js frontend and AI chatbot entry point for dashboarding and natural-language interaction.
- Local infra stack (PostgreSQL, ClickHouse, Kafka, MinIO, Kong) with Prometheus metrics exposure.
- Kubernetes deployment manifests via Helm, with Prometheus + Grafana dashboards and alert rules.
[ Non-Technical Users (Rectors, Deans, Admins) ]
|
v
+---------------------------------------------------+
| Web App / Chatbot UI | (Next.js 15, TailwindCSS)
+---------------------------------------------------+
| (HTTPS / SSE)
v
+---------------------------------------------------+
| API Gateway (Kong 3.8, DB-less) |
| Auth enforcement, rate limiting, routing |
+---------------------------------------------------+
|
+---------------+---------------+---------------+
| | | |
+--v--+ +--v--+ +--v--+ +--v--+
| IAM | |Core | | AI /| |Ingest
| SVC | | Mgmt| |Chat | | SVC |
|(JWT)| |(CRUD| | SVC | |(ETL)|
+--+--+ +--+--+ +--+--+ +--+--+
| | | |
+---------------+-------+-------+---------------+
| (Apache Kafka 3.8, KRaft)
+-------+-------+
| |
+-----v-----+ +-----v-----+
| Analytics | | Notif/ |
| Service | | Reports |
+-----------+ +-----------+
| |
v v
+---------------------------------------------------+
| Data Layer |
| PostgreSQL 16 (OLTP) | ClickHouse 24.8 (OLAP) |
| MinIO (Object Storage)| Kafka (Event Bus) |
+---------------------------------------------------+
| Service | Port | Responsibility |
|---|---|---|
iam-service |
9010 | JWT auth, RBAC, tenant resolution, audit trail |
ingestion-service |
9011 | File upload (PDF/Excel/CSV) and JSON ingestion |
data-preprocessor |
8005 | Column mapping, cleaning, normalization |
core_management_service |
8008 | CRUD API for students, courses, faculty, finance |
analytics_service |
8007 | Anomaly detection, predictions, KPI comparison |
chatbot_service |
8006 | Multi-agent AI cabinet (6 specialist agents + synthesis) |
report_generation_service |
8004 | LaTeX/PDF report generation with scheduler |
notification_service |
8003 | Email + in-app notifications via Kafka events |
learning_service |
8009 | Anomaly feedback loop and weekly LLM insights |
All services are FastAPI (Python 3.11/3.12), containerized, and run behind Kong.
For service-specific setup, API contracts, and internals:
- IAM Service
- Ingestion Service
- Data Preprocessor
- Core Management Service
- Analytics Service
- Chatbot Service
- Notification Service
- Report Generation Service
- Learning Service
- Next.js 15 (App Router, TypeScript)
- TailwindCSS + Tremor + Apache ECharts
- FastAPI with async/await (Python 3.11–3.12)
- pydantic-settings for configuration
- structlog for structured JSON logging
- PostgreSQL 16 — transactional data (OLTP), Row-Level Security enforced
- ClickHouse 24.8 — analytics (OLAP), KPI time-series
- Apache Kafka 3.8 (KRaft mode, no ZooKeeper) — event bus
- MinIO — S3-compatible object storage for uploaded files
- Docker Compose (full local stack) / Kubernetes (production)
- Kong 3.8 (DB-less, declarative) — API gateway
- Prometheus metrics exposed by every service
- Local environment:
docker-compose.yml+make infra-up - Kubernetes environment: Helm chart in
infra/helm/ucar-platform - Monitoring stack on Kubernetes: Prometheus + Grafana + ServiceMonitors + PrometheusRule alerts
More details:
Pooled tenancy with PostgreSQL Row-Level Security (RLS).
Every table in the university.* schema carries a tenant_id column. RLS policies enforce strict per-tenant data isolation at the database level. Super-admins hold the BYPASSRLS privilege and can perform cross-institution aggregations.
-- Cross-institution KPI aggregation (super_admin only)
SELECT tenant_id, AVG(success_rate)
FROM university.academic_kpis
GROUP BY tenant_id;Tenant resolution order (IAM middleware, first match wins):
- JWT claim
tenant_id X-Tenant-IDheader- Subdomain (
enit.ucar.edu→ slug → DB lookup) - Fallback:
GLOBAL
1. File/manual upload → ingestion-service
│ validates, extracts, publishes
▼
Kafka: raw.data.ingested
│
▼
2. data-preprocessor consumes, cleans, normalizes
│ publishes batches of 500 records
▼
Kafka: tenant.data.normalized
│
▼
3. core_management_service upserts into PostgreSQL
(university.students, courses, enrollments …)
│
├──► analytics_service reads KPIs → anomaly detection
│ │
│ ▼
│ Kafka: analytics.anomaly.detected.v1
│ │
│ ├──► notification_service → email + in-app alerts
│ └──► learning_service → feedback loop + insights
│
└──► report_generation_service reads PostgreSQL → LaTeX → PDF
Kafka topic definitions and payload schemas: infra/kafka/topics.md.
# 1. Copy env template (edit secrets if needed)
cp -n .env.example .env
# 2. Start all infrastructure and backend services
make infra-up
# 3. Start the frontend dev server
npm -w @ucar/frontend run dev| Service | URL |
|---|---|
| Frontend | http://127.0.0.1:3000 |
| IAM (docs) | http://127.0.0.1:9010/docs |
| Ingestion (docs) | http://127.0.0.1:9011/docs |
| Data Preprocessor (docs) | http://127.0.0.1:8005/docs |
| Core Management (docs) | http://127.0.0.1:8008/docs |
| Analytics (docs) | http://127.0.0.1:8007/docs |
| Chatbot (docs) | http://127.0.0.1:8006/docs |
| Notification (docs) | http://127.0.0.1:8003/docs |
| Report Service (docs) | http://127.0.0.1:8004/docs |
| Learning Service (docs) | http://127.0.0.1:8009/docs |
| Kong Proxy | http://127.0.0.1:8000 |
| Kong Admin API | http://127.0.0.1:8001 |
| Kong Manager | http://127.0.0.1:8002 |
| Kafka UI | http://127.0.0.1:8090 |
| MinIO API | http://127.0.0.1:9002 |
| MinIO Console | http://127.0.0.1:9001 |
| ClickHouse HTTP | http://127.0.0.1:8123 |
| PostgreSQL | localhost:5433 |
make e2e-smokeRuns: login → manual ingest → Kafka handoff → core import verification.
Note: The Postgres migration grants
BYPASSRLSto roleapp_superadmin. If you have an existing volume from an older version, runmake infra-destroyonce to recreate roles with updated privileges.
| Role | Password | Tenant | |
|---|---|---|---|
| tenant_admin | [email protected] | GW_Admin#2024! | 11111111-0000-0000-0000-000000000001 |
| tenant_admin | [email protected] | SR_Admin#2024! | 22222222-0000-0000-0000-000000000002 |
| faculty | [email protected] | Faculty#2024! | Greenwood |
| faculty | [email protected] | Faculty#2024! | Greenwood |
| faculty | [email protected] | Faculty#2024! | Sunridge |
| student | [email protected] | Student#2024! | Greenwood |
| student | [email protected] | Student#2024! | Greenwood |
| student | [email protected] | Student#2024! | Sunridge |
| student | [email protected] | Student#2024! | Sunridge |
# Stop containers, keep DB volumes
make infra-down
# Stop containers and delete all data volumes
make infra-destroy