DataSage, doğal dil ile sorulan analitik soruları güvenli PostgreSQL sorgularına dönüştüren, sorguyu çalıştıran ve sonucu tablo/grafik olarak sunan API-first bir analytics platformudur.
DataSage; kullanıcıların teknik SQL yazmadan, doğal dilde soru sorarak veri analizi yapabilmesini hedefleyen çok katmanlı bir uygulamadır.
- Analist veya iş kullanıcısının SQL bilmeden veri sorgulamasını sağlar
- Doğal dil ile gelen isteği güvenli SQL akışına dönüştürür
- Sonuçları tablo, metadata ve uygun olduğunda grafik olarak gösterir
- Sorgu geçmişi, admin görünürlüğü ve schema görünümü ile operasyonel izlenebilirlik sunar
Temel akış şu şekildedir:
- Kullanıcı Angular arayüzünden doğal dilde soru sorar
- .NET API isteği alır ve orkestrasyonu yönetir
- FastAPI AI servisi soruyu SQL üretimine hazırlar
- Gerekirse Ollama/SQLCoder ile SQL üretilir
- .NET katmanı SQL güvenliğini doğrular
- PostgreSQL üzerinde sorgu çalıştırılır
- Sonuç satırları, çalışma metadata'sı ve chart payload frontend'e döner
- Doğal dil ile sorgu desteği
- Türkçe ve İngilizce soru desteği
- SQL generation
- Read-only SQL validation
- PostgreSQL query execution
- Result table rendering
- Backend chart metadata generation
- Query execution + result visualization
- Query history
- Admin panel
- Schema viewer + schema refresh
- JWT tabanlı giriş ve rol kontrolü
- Türkçe destek için question normalizer
- Desteklenen sorular için deterministic fast-path
- Desteklenmeyen sorular için AI fallback via Ollama/SQLCoder
frontend/datasage-ui- Angular tabanlı kullanıcı arayüzü
- Login, Query, History, Admin ve Access Denied ekranları
backend/src/DataSage.API- HTTP giriş noktası
- Auth, authorization, orchestration ve API contract'ları
backend/src/DataSage.Application- Abstraction ve DTO katmanı
backend/src/DataSage.Infrastructure- AI client, SQL validator, query executor, log persistence, schema metadata, auth service
ai-service- FastAPI tabanlı AI microservice
- SQL generation, repair ve prompt hazırlama
docker- Docker Compose, PostgreSQL seed/init ve container runtime yapısı
- Frontend: Angular
- Backend API: .NET 8 ASP.NET Core Web API
- AI Service: Python FastAPI
- LLM Runtime: Ollama + SQLCoder
- Database: PostgreSQL 16
- Dev runtime: Docker Compose
User
-> Frontend (Angular)
-> Backend (.NET API)
-> AI Service (FastAPI)
-> SQL generation
-> PostgreSQL execution
-> Response (rows + metadata + chart)
Daha ayrıntılı akış:
user
-> frontend
-> backend
-> ai-service
-> SQL
-> DB
-> backend response
-> frontend rendering
İlk çalışan sürümde doğal dil -> SQL akışı ağırlıklı olarak İngilizce örnekler ve İngilizce schema grounding üzerinden ilerliyordu. Bu nedenle:
- Türkçe sorgular bazen yavaş kalıyordu
- Model niyeti yanlış yorumlayabiliyordu
- Hatalı ya da alakasız SQL dönebiliyordu
- Kullanıcı tarafında sorgu "takılıyormuş" gibi hissedilebiliyordu
Türkçe destek için kontrollü ve güvenli bir çözüm eklendi:
question normalizer- Türkçe ve İngilizce desteklenen soru kalıplarını normalize eder
supported intents- Bilinen analitik soruları kararlı intent'lere eşler
deterministic SQL- Desteklenen intent'ler için doğrudan güvenilir SQL üretir
fallback AI- Desteklenmeyen sorular mevcut Ollama/SQLCoder akışına düşer
- Önce soru normalize edilir
- Desteklenen intent bulunursa deterministic fast-path çalışır
- Intent desteklenmiyorsa mevcut AI generation akışı korunur
- Orijinal kullanıcı sorusu mantıksal olarak korunur
en çok satan 5 ürün->top 5 products by saleskategoriye göre satışlar->sales by categorysatışa göre en iyi 5 çalışan->top 5 employees by salesaylık satış trendi->monthly sales trend
- Mevcut İngilizce akışı bozmaz
- SQL güvenliğini zayıflatmaz
- Türkçe temel analitik sorularda gecikmeyi ciddi şekilde azaltır
- Bakımı kolaydır
- Genişletilebilir bir yapı sunar
- Docker Desktop
- .NET 8 SDK
- Node.js + npm
- Python 3.12+ veya mevcut lokal Python kurulumu
Kök dizinde .env dosyasını oluştur:
Copy-Item .env.example .envTüm sistemi ayağa kaldır:
docker compose --env-file .env -f docker/docker-compose.yml up --buildİlk kurulumda model yoksa Ollama içine SQLCoder çek:
docker exec -it datasage-ollama ollama pull sqlcoderAltyapı servisleri:
docker compose --env-file .env -f docker/docker-compose.yml up -d postgres ollamaBackend:
cd backend
dotnet restore
dotnet run --project src/DataSage.API --launch-profile httpAI service:
cd ai-service
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000Frontend:
cd frontend/datasage-ui
npm.cmd install --legacy-peer-deps
npm.cmd start- Frontend UI:
http://localhost:4200 - Backend API Swagger:
http://localhost:8080/swaggerveya manuel moddahttp://localhost:5064/swagger - AI Service Docs:
http://localhost:8000/docs - PostgreSQL:
localhost:5432 - Ollama:
http://localhost:11434
- UI:
http://localhost:4200
- Admin
- kullanıcı adı:
admin - e-posta:
admin@datasage.local - şifre:
Admin123!
- kullanıcı adı:
- User
- kullanıcı adı:
analyst - e-posta:
user@datasage.local - şifre:
User123!
- kullanıcı adı:
Türkçe:
en çok satan 5 ürünkategoriye göre satışlarsatışa göre en iyi 5 çalışanaylık satış trendi
İngilizce:
top 5 products by salessales by categorytop 5 employees by salesmonthly sales trend
- Giriş yap
- Query sayfasına git
- Soru alanına doğal dilde sorunu yaz
Run Queryile sorguyu gönder- SQL, execution metadata, table ve chart sonucunu incele
Request:
{
"question": "en çok satan 5 ürün"
}Örnek response:
{
"sql": "SELECT products.product_id, products.product_name, SUM(order_details.unit_price * order_details.quantity * (1 - order_details.discount)) AS total_sales FROM products JOIN order_details ON products.product_id = order_details.product_id GROUP BY products.product_id, products.product_name ORDER BY total_sales DESC LIMIT 5;",
"raw": "SELECT products.product_id, products.product_name, SUM(order_details.unit_price * order_details.quantity * (1 - order_details.discount)) AS total_sales FROM products JOIN order_details ON products.product_id = order_details.product_id GROUP BY products.product_id, products.product_name ORDER BY total_sales DESC LIMIT 5;",
"columns": [
"product_id",
"product_name",
"total_sales"
],
"rows": [
{
"product_id": 12,
"product_name": "Queso Manchego La Pastora",
"total_sales": 2222.24
}
],
"rowCount": 5,
"executionTimeMs": 38,
"attemptCount": 1,
"wasRepaired": false,
"error": null,
"chart": {
"type": "bar",
"title": "Top 5 Products By Sales",
"xKey": "product_name",
"yKeys": ["total_sales"]
}
}Aşağıdaki Türkçe ve İngilizce örnekler doğrulandı:
| Soru | Durum | Sonuç |
|---|---|---|
en çok satan 5 ürün |
OK | Doğru SQL + 5 satır |
kategoriye göre satışlar |
OK | Doğru SQL + kategori bazlı sonuç |
satışa göre en iyi 5 çalışan |
OK | Doğru SQL + 5 çalışan |
aylık satış trendi |
OK | Doğru SQL + line-chart uyumlu sonuç |
top 5 products by sales |
OK | Doğru SQL + 5 satır |
sales by category |
OK | Doğru SQL + kategori bazlı sonuç |
top 5 employees by sales |
OK | Doğru SQL + 5 çalışan |
monthly sales trend |
OK | Doğru SQL + line-chart uyumlu sonuç |
Kısa özet:
- Türkçe desteklenen intent'lerde hızlı ve deterministik sonuç alınıyor
- İngilizce akış korunuyor
- Query execution, history, admin ve auth akışı etkilenmiyor
- Deterministic yaklaşım şu an yalnızca desteklenen intent seti için geçerli
- Daha karmaşık Türkçe sorular AI fallback yoluna gider
- Local model zaman zaman yavaş olabilir
- AI fallback tam garantili değildir
- Grafik seçimi deterministik kural tabanlıdır, AI tabanlı değildir
- Türkçe intent kapsama alanını genişletmek
- Daha zengin synonym ve domain terim desteği eklemek
- Karmaşık Türkçe sorular için daha güçlü bilingual prompt tasarımı
- AI accuracy ve repair kalitesini artırmak
- Sorgu örnekleri ve intent kataloğunu genişletmek
DataSage/
|-- backend/
| |-- src/
| | |-- DataSage.API/
| | |-- DataSage.Application/
| | |-- DataSage.Domain/
| | `-- DataSage.Infrastructure/
| `-- tests/
|-- frontend/
| `-- datasage-ui/
|-- ai-service/
| `-- app/
|-- docker/
| `-- postgres/init/
|-- docs/
|-- .env.example
`-- README.md
- Query guide ve queryable tables açıklamaları için
docs/query-guide.md - Mimari kararlar için
docs/architecture.mdvedocs/decisions.md - Local development için seeded demo kullanıcılar yalnızca geliştirme amaçlıdır