┌─────────────────────────────────────────────────────────────────────────────┐
│ USER INTERFACE │
│ http://localhost:5176 │
└─────────────────────────────────────────────────────────────────────────────┘
│
│ React + TypeScript
│ Material-UI Components
│
┌───────────────┴───────────────┐
│ │
┌───────▼───────┐ ┌────────▼────────┐
│ UploadStatus │ │ AssistantChat │
│ Component │ │ Component │
│ │ │ │
│ • Show Report │ │ • Text Input │
│ • Download CSV│ │ • Consent Box │
│ • AI Button │ │ • Show Actions │
│ • AI Results │ │ • Apply Button │
└───────┬───────┘ └────────┬────────┘
│ │
│ useJobStatus() │ askAssistant()
│ (React Query) │ applyAssistantActions()
│ │
└──────────────┬───────────────┘
│
│ HTTP/REST API
│
┌──────────────────────────────────▼──────────────────────────────────────────┐
│ BACKEND API SERVER │
│ FastAPI - http://localhost:8000 │
│ │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ /api/v1/ │ │ /api/v1/ │ │ /api/v1/ │ │
│ │ upload │ │ jobs │ │ assistant │ │
│ │ │ │ │ │ │ │
│ │ • Upload CSV │ │ • Get Status │ │ • Ask AI │ │
│ │ • Enqueue Job │ │ • Poll Updates │ │ • Apply Actions│ │
│ └────────┬───────┘ └────────┬───────┘ └────────┬───────┘ │
│ │ │ │ │
│ │ │ ┌──────────▼──────────┐ │
│ │ │ │ llm_client.py │ │
│ │ │ │ │ │
│ │ │ │ • Build Context │ │
│ │ │ │ • Call Gemini AI │ │
│ │ │ │ • Parse JSON │ │
│ │ │ └──────────┬──────────┘ │
│ │ │ │ │
└───────────┼───────────────────┼────────────────────┼────────────────────────┘
│ │ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ REDIS │ │
│ │ port 6379 │ │
│ │ │ │
│ │ • Job Store │◄───────────┘
│ │ • Job Status │
│ │ • Celery Broker │
│ │ • Results Cache │
│ └─────────┬───────┘
│ │
│ │
▼ ▼
┌───────────────────────────────────────────────────────────────────────────┐
│ CELERY WORKER │
│ Background Task Processor │
│ │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ process_dataset │ │ apply_ai_actions │ │
│ │ (Original Task) │ │ (New AI Task) │ │
│ │ │ │ │ │
│ │ • Read CSV │ │ • Load Dataset │ │
│ │ • Drop Duplicates │ │ • Apply Actions │ │
│ │ • Generate Profile │ │ - drop_columns │ │
│ │ • Upload to MinIO │ │ - impute │ │
│ │ • Update Job Status │ │ - encode │ │
│ └────────┬────────────────┘ │ - scale │ │
│ │ │ - train_model │ │
│ │ │ • Generate New Report │ │
│ │ │ • Upload Artifacts │ │
│ │ │ • Update Job Status │ │
│ │ └────────┬────────────────┘ │
│ │ │ │
│ └────────────────┬───────────────┘ │
│ │ │
└────────────────────────────┼──────────────────────────────────────────────┘
│
│ actions.py (Executor)
│
┌────────▼────────┐
│ Data Transform │
│ • pandas ops │
│ • sklearn models │
│ • encoding │
│ • scaling │
└────────┬─────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ STORAGE LAYER │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ MinIO │ │ PostgreSQL │ │ File System │ │
│ │ port 9000-9001 │ │ port 5432 │ │ /tmp/uploads │ │
│ │ │ │ │ │ │ │
│ │ • HTML Reports │ │ • User Data │ │ • Temp CSV │ │
│ │ • CSV Files │ │ • Metadata │ │ • Shared Vol │ │
│ │ • AI Results │ │ • Audit Logs │ │ • Upload Buffer │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ EXTERNAL SERVICES │
│ │
│ ┌─────────────────────┐ │
│ │ Google Gemini AI │ │
│ │ gemini-2.0-flash │ │
│ │ │ │
│ │ • NLP Understanding │ │
│ │ • Action Generation │ │
│ │ • JSON Structured │ │
│ │ Output │ │
│ └─────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
Step 1: User Request
─────────────────────
User types: "Fill missing values and train a classifier on Survived"
│
▼
Frontend: AssistantChat.tsx captures input
│
▼
POST /api/v1/assistant
{
job_id: "abc-123",
prompt: "Fill missing values and train a classifier on Survived",
consent_send_sample: true,
sample_size: 20
}
Step 2: Backend Processing
───────────────────────────
Backend: assistant.py receives request
│
├─> Load job from Redis JobStore
├─> Read dataset CSV file
├─> Extract schema (columns, dtypes)
├─> Calculate summary stats (missing counts, etc.)
└─> Get 20 sample rows (if consent=true)
│
▼
Build context JSON:
{
schema: {columns: [...], dtypes: {...}, shape: [1000, 10]},
summary: {rows: 1000, missing_counts: {...}},
sample_rows: [{...}, {...}, ...]
}
│
▼
llm_client.py calls Gemini AI
│
▼
Google Gemini AI analyzes context
│
▼
Returns structured JSON:
{
explanation: "I'll impute missing values...",
actions: [
{type: "impute", params: {strategy: "median", columns: []}},
{type: "encode", params: {columns: ["Sex"], method: "onehot"}},
{type: "train_model", params: {task: "classification", target: "Survived", model: "RandomForest"}}
]
}
│
▼
Backend validates action types (whitelist check)
│
▼
Response sent to frontend
Step 3: User Review
───────────────────
Frontend displays:
• Explanation text
• Action chips (colored badges)
• JSON preview
│
▼
User clicks "Apply These Actions"
Step 4: Worker Execution
─────────────────────────
POST /api/v1/assistant/apply
{
job_id: "abc-123",
actions: [...],
run_name: "assistant-run"
}
│
▼
Backend validates and enqueues Celery task:
apply_ai_actions.delay(job_id, actions, run_name)
│
▼
Celery Worker picks up task:
│
├─> Load dataset from Redis job info
├─> Read CSV into pandas DataFrame
│
├─> For each action:
│ ├─> impute: df[col].fillna(df[col].median())
│ ├─> encode: pd.get_dummies(df, columns=[...])
│ ├─> train_model: RandomForestClassifier.fit(X, y)
│ └─> Log each operation
│
├─> Generate ydata-profiling report (HTML)
├─> Save transformed CSV
│
├─> Upload to MinIO:
│ ├─> {job_id}/ai/{report}.html
│ └─> {job_id}/ai/{cleaned}.csv
│
└─> Update Redis JobStore with ai_result:
{
status: "done",
ai_result: {
report_url: "http://localhost:8000/api/v1/artifacts/...",
cleaned_csv: "http://localhost:8000/api/v1/artifacts/...",
actions_applied: [...],
model_info: {score: 0.85, features: [...]}
}
}
Step 5: Results Display
───────────────────────
Frontend polls GET /api/v1/jobs/{id}/status every 2s
│
▼
Detects ai_result field populated
│
▼
Displays green "AI Assistant Results" box with:
• "X actions applied successfully"
• "View AI Report" button (opens iframe)
• "Download AI-Processed CSV" button
┌──────────────────────────────────────────────────────────────┐
│ FRONTEND LAYER │
│ │
│ Home.tsx │
│ └── UploadForm.tsx ──> useUpload() ──> POST /upload │
│ └── UploadStatus.tsx │
│ ├── useJobStatus() ──> GET /jobs/{id}/status │
│ ├── AssistantChat.tsx │
│ │ ├── askAssistant() ──> POST /assistant │
│ │ └── applyAssistantActions() ──> POST /apply │
│ └── Shows results (report iframe, CSV links) │
└──────────────────────────────────────────────────────────────┘
│
│ API Calls
▼
┌──────────────────────────────────────────────────────────────┐
│ BACKEND API LAYER │
│ │
│ main.py (FastAPI App) │
│ ├── upload.router (POST /api/v1/upload) │
│ ├── jobs.router (GET /api/v1/jobs/{id}/status) │
│ ├── artifacts.router (GET /api/v1/artifacts/{id}/*) │
│ └── assistant.router (POST /api/v1/assistant) │
│ (POST /api/v1/assistant/apply) │
│ │
│ assistant.py │
│ ├── Build context (schema + summary + sample) │
│ ├── Call llm_client.call_llm_for_actions() │
│ └── Validate and enqueue worker task │
│ │
│ llm_client.py │
│ └── Google Gemini API integration │
└──────────────────────────────────────────────────────────────┘
│
│ Redis Pub/Sub
▼
┌──────────────────────────────────────────────────────────────┐
│ WORKER LAYER │
│ │
│ tasks.py (Celery Worker) │
│ ├── process_dataset (original) │
│ │ └── Generate initial report │
│ └── apply_ai_actions (new) │
│ └── actions.py: apply_actions_to_dataframe() │
│ ├── drop_columns │
│ ├── impute (median/mean/mode/zero) │
│ ├── cast (int/float/datetime) │
│ ├── encode (onehot/label) │
│ ├── scale (standard/minmax) │
│ ├── feature_engineer │
│ └── train_model (RandomForest/Logistic/etc) │
└──────────────────────────────────────────────────────────────┘
│
│ Store/Retrieve
▼
┌──────────────────────────────────────────────────────────────┐
│ PERSISTENCE LAYER │
│ │
│ storage.py (JobStore) │
│ └── Redis: Shared job state between backend & worker │
│ │
│ MinIO S3: Object storage for artifacts │
│ ├── {job_id}/report.html │
│ ├── {job_id}/cleaned.csv │
│ ├── {job_id}/ai/report.html │
│ └── {job_id}/ai/cleaned.csv │
└──────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ PUBLIC INTERNET │
└─────────────────────────────────────────────────────────────┘
│
│ User Browser
▼
┌─────────────────────────────────────────────────────────────┐
│ SECURITY LAYER 1 │
│ CORS Middleware │
│ • Allows only: localhost:5173-5176 │
│ • Blocks all other origins │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SECURITY LAYER 2 │
│ Input Validation │
│ • Pydantic models validate all inputs │
│ • File type restrictions (CSV only) │
│ • Size limits enforced │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SECURITY LAYER 3 │
│ Privacy Controls │
│ • Sample data: consent required │
│ • Max 20 rows sent to AI │
│ • Only schema/stats by default │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SECURITY LAYER 4 │
│ Action Whitelisting │
│ • Only 7 predefined action types allowed │
│ • No arbitrary code execution │
│ • Server-side validation before execution │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ INTERNAL DOCKER NETWORK │
│ • Services communicate only within network │
│ • Redis/Postgres not exposed to internet │
│ • MinIO accessed only via backend proxy │
└─────────────────────────────────────────────────────────────┘
Frontend:
├── React 18
├── TypeScript 5
├── Material-UI v5
├── React Query v4 (data fetching)
├── React Router v6 (navigation)
├── Vite 6 (build tool)
└── MSW v2 (mocking - dev only)
Backend:
├── FastAPI (Python async web framework)
├── Uvicorn (ASGI server)
├── Pydantic v2 (validation)
├── google-genai (AI integration)
├── pandas (data processing)
├── ydata-profiling (report generation)
└── minio (S3 client)
Worker:
├── Celery 5.3 (task queue)
├── Redis (broker + results)
├── scikit-learn (ML models)
├── pandas + numpy (data ops)
└── joblib (model serialization)
Infrastructure:
├── Docker Compose (orchestration)
├── Redis 7 (cache + queue)
├── PostgreSQL 15 (database)
├── MinIO (S3-compatible storage)
└── Shared volumes (file access)
AI/ML:
├── Google Gemini 2.0 Flash (LLM)
├── RandomForest (classification/regression)
├── Logistic Regression (classification)
├── StandardScaler / MinMaxScaler (normalization)
└── One-Hot / Label Encoding (categorical)
Created: November 28, 2025
System: Production-Ready AI-Powered Data Analysis Platform