AI-powered construction and interior progress tracking platform
SyteScan is a full-stack, AI-powered platform that automates construction and interior progress tracking. Users define a checklist of required objects for a project (e.g., furniture, appliances, fixtures), upload site images, and receive instant AI-driven analysis showing which items have been installed and what percentage of the project is complete.
Target users: Construction project managers, interior designers, site inspectors, and facility auditors who need objective, photo-based progress reporting without manual walkthroughs.
Core value: Replaces subjective manual inspection with repeatable, confidence-scored object detection backed by YOLOv8, delivering completion percentages and requirement-level traceability from uploaded images.
┌─────────────────────────────────────────────────────────┐
│ Browser │
│ Next.js 14 (React + TypeScript) │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │
│ │ Project │ │ Image │ │ Progress Dashboard │ │
│ │ Form │ │ Upload │ │ (Charts + Tables) │ │
│ └────┬─────┘ └────┬─────┘ └──────────┬───────────┘ │
└───────┼─────────────┼───────────────────┼──────────────┘
│ REST/JSON │ multipart/form │ REST/JSON
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ FastAPI Backend (Python 3.11) │
│ ┌────────────┐ ┌────────────┐ ┌──────────────────┐ │
│ │ Projects │ │ Upload │ │ Progress │ │
│ │ Router │ │ Router │ │ Router │ │
│ └─────┬──────┘ └─────┬──────┘ └────────┬─────────┘ │
│ │ │ │ │
│ ┌─────▼───────────────▼──────────────────▼──────────┐ │
│ │ Service Layer │ │
│ │ ProjectService │ UploadService │ ProgressService │ │
│ └────────────────────────┬───────────────────────── ┘ │
│ │ │
│ ┌────────────────────────▼────────────┐ │
│ │ DetectionService │ │
│ │ YOLOv8 (Ultralytics) │ │
│ └────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ SQLAlchemy │ │ File System │ │
│ │ ORM │ │ (uploads/) │ │
│ └──────┬──────┘ └──────────────┘ │
└─────────┼───────────────────────────────────────────────┘
▼
┌─────────────────────┐
│ SQLite (dev) │
│ PostgreSQL (prod) │
└─────────────────────┘
| Component | Responsibility |
|---|---|
| Next.js Frontend | Multi-step workflow UI: project creation → image upload → dashboard |
| FastAPI Backend | REST API, request validation, business logic orchestration |
| DetectionService | Loads YOLOv8 model, runs inference, normalizes detections |
| ProgressService | Compares detections against requirements, computes completion % |
| UploadService | Validates files, persists to disk, triggers detection pipeline |
| ProjectService | CRUD operations for project and requirement records |
| PerformanceMonitor | In-process metrics collection (CPU, memory, request stats) |
| Layer | Technology | Version |
|---|---|---|
| Frontend Framework | Next.js | 14.0.0 |
| UI Library | React | 18 |
| Language (Frontend) | TypeScript | 5 |
| Styling | Tailwind CSS | 3.3 |
| Charts | Recharts | 2.15 |
| Forms | react-hook-form | 7.47 |
| Notifications | react-hot-toast | 2.6 |
| Backend Framework | FastAPI | 0.104.1 |
| Language (Backend) | Python | 3.11 |
| ASGI Server | Uvicorn | 0.24.0 |
| ORM | SQLAlchemy | 2.0.23 |
| Validation | Pydantic / pydantic-settings | 2.5.0 / 2.1.0 |
| Object Detection | Ultralytics YOLOv8 | ≥8.0.206 |
| Image Processing | Pillow | ≥10.2.0 |
| ML Framework | PyTorch | (via Ultralytics) |
| Database (dev) | SQLite | — |
| Database (prod) | PostgreSQL | — |
| Containerization | Docker + Docker Compose | — |
| Frontend Hosting | Vercel | — |
| Backend Hosting | Render | — |
| Frontend Tests | Vitest + Testing Library | 0.34 / 13.4 |
| Backend Tests | pytest + pytest-asyncio | 7.4.3 / 0.21.1 |
- AI Object Detection — YOLOv8 inference on uploaded images; supports Nano through Extra-Large model variants (configurable via
YOLO_MODEL) - Requirements-Based Progress Tracking — Define a checklist of required objects per project; system matches detections with synonym resolution (e.g.,
sofa↔couch,tv↔television) - Completion Percentage — Auto-calculated as (detected requirements / total requirements) × 100
- Multi-Image Upload — Accepts JPEG/PNG; up to 10 MB per file; processes all images in a single request
- Detection Dashboard — Interactive pie chart (completion vs. remaining), bar chart (detection count per requirement), and tabular requirement analysis with per-item confidence scores
- Per-Endpoint Metrics — Built-in
PerformanceMonitortracks request counts, response times, and error rates - Health & Readiness Endpoints —
/health,/health/detailed(with system metrics),/metrics,/model-info - Structured Logging — Request/response logging middleware with configurable log level
- Docker-First Deployment — Single
docker-compose up --buildfor full-stack local or production deployment - Module-Oriented Home Screen — Extensible UI supporting multiple future modules (Floor Plan Generation, Interior Designer — currently placeholders)
SyteScan/
├── backend/ # Python FastAPI application
│ ├── main.py # Application entry point; registers routers, middleware, lifespan
│ ├── requirements.txt # Runtime dependencies
│ ├── app/
│ │ ├── api/ # Route handlers (thin controllers)
│ │ │ ├── projects.py # CRUD endpoints for projects
│ │ │ ├── upload.py # Image upload and detection retrieval
│ │ │ └── progress.py # Progress calculation endpoint
│ │ ├── services/ # Business logic
│ │ │ ├── detection_service.py # YOLOv8 inference + object filtering
│ │ │ ├── progress_service.py # Requirement matching + % calculation
│ │ │ ├── project_service.py # Project CRUD logic
│ │ │ └── upload_service.py # File persistence + detection pipeline
│ │ ├── models/
│ │ │ └── project.py # SQLAlchemy ORM models (Project, Requirement, Detection)
│ │ ├── schemas/
│ │ │ ├── project.py # Pydantic request/response schemas
│ │ │ └── upload.py # Upload-specific schemas
│ │ ├── database/
│ │ │ └── connection.py # SQLAlchemy engine, session factory, table creation
│ │ ├── middleware/
│ │ │ ├── error_handler.py # Global exception handlers
│ │ │ └── logging.py # Request/response logging middleware
│ │ ├── monitoring/
│ │ │ └── metrics.py # In-process performance monitor
│ │ ├── config.py # Pydantic Settings; reads from .env
│ │ └── exceptions.py # Custom exception classes
│ └── tests/ # Backend test suite
│ ├── test_project_api.py
│ ├── test_upload_api.py
│ ├── test_progress_api.py
│ ├── test_detection_service.py
│ ├── test_progress_service.py
│ ├── test_project_service.py
│ ├── test_upload_service.py
│ ├── test_database.py
│ ├── test_schemas.py
│ └── test_e2e_workflow.py
│
├── src/ # Next.js 14 frontend (App Router)
│ ├── app/
│ │ ├── page.tsx # Home screen: module selection cards
│ │ ├── layout.tsx # Root layout with ToastProvider
│ │ ├── globals.css
│ │ └── projects/
│ │ ├── new/page.tsx # Step 1: project creation form
│ │ └── [id]/
│ │ ├── upload/page.tsx # Step 2: image upload
│ │ └── dashboard/page.tsx # Step 3: progress dashboard
│ ├── components/
│ │ ├── ProjectForm.tsx # Project name + requirements input
│ │ ├── ImageUpload.tsx # Drag-and-drop / file picker
│ │ ├── ErrorBoundary.tsx
│ │ ├── ui/ # Reusable UI primitives
│ │ │ ├── LoadingSpinner.tsx
│ │ │ ├── ProgressBar.tsx
│ │ │ ├── StatusIndicator.tsx
│ │ │ ├── WorkflowStepper.tsx
│ │ │ └── PageTransition.tsx
│ │ └── providers/
│ │ └── ToastProvider.tsx
│ ├── hooks/
│ │ └── useErrorHandler.ts
│ ├── lib/
│ │ └── api.ts # Typed API client (fetch wrapper)
│ ├── types/
│ │ └── project.ts # Shared TypeScript interfaces
│ └── test/ # Frontend test suite (Vitest)
│
├── Dockerfile.backend # Multi-stage Python image
├── Dockerfile.frontend # Multi-stage Node.js image (standalone output)
├── docker-compose.yml # Orchestration for local + production
├── Makefile # Developer shortcuts
├── next.config.js
├── tailwind.config.js
├── tsconfig.json
├── vitest.config.ts
├── .env.example # Environment variable template
└── docs/ # Architecture and supplementary docs
| Tool | Minimum Version |
|---|---|
| Node.js | 18 |
| Python | 3.11 |
| pip | 23+ |
| Docker | 24+ (optional, for containerized setup) |
| Docker Compose | 2.x (optional) |
# Clone the repository
git clone https://github.com/SaiAvinashPatoju/SyteScan.git
cd SyteScan
# Install all dependencies (frontend + backend virtualenv)
make setup# Frontend
npm install
# Backend
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cd ..docker-compose buildCopy the template and fill in values before running:
cp .env.example .env| Variable | Default | Description |
|---|---|---|
NEXT_PUBLIC_API_URL |
http://localhost:8000 |
Backend API base URL |
| Variable | Default | Required in Prod | Description |
|---|---|---|---|
DATABASE_URL |
sqlite:///./sytescan.db |
✅ (use PostgreSQL) | SQLAlchemy connection string |
UPLOAD_DIR |
./uploads |
✅ | Directory for uploaded images |
SECRET_KEY |
dev-secret-key-change-in-production |
✅ | Application secret key |
CORS_ORIGINS_STR |
http://localhost:3000 |
✅ | Comma-separated allowed origins |
LOG_LEVEL |
INFO |
— | DEBUG, INFO, WARNING, ERROR |
YOLO_MODEL |
yolov8n.pt |
— | YOLOv8 model variant (see model info) |
DETECTION_CONFIDENCE |
0.5 |
— | Minimum confidence threshold (0–1) |
MAX_FILE_SIZE |
10485760 |
— | Max upload size in bytes (10 MB) |
MAX_WORKERS |
4 |
— | Uvicorn worker processes |
REQUEST_TIMEOUT |
300 |
— | Request timeout in seconds |
⚠️ Assumption:SECRET_KEYis currently used for configuration identification. JWT or session-based auth is not yet implemented.
# Terminal 1 — Frontend (http://localhost:3000)
make run-frontend
# or: npm run dev
# Terminal 2 — Backend (http://localhost:8000)
make run-backend
# or: cd backend && venv/bin/uvicorn main:app --reloadmake deploy-local
# or:
docker-compose up --build -d
# Verify
curl http://localhost:8000/health
curl http://localhost:3000make help # List all available Make targets
make health # Check running service health
make db-reset # Delete SQLite database (recreated on next start)
make clean # Remove build artifacts and cachesInteractive Swagger UI is available at http://localhost:8000/docs when the backend is running.
| Method | Path | Description |
|---|---|---|
POST |
/api/projects/ |
Create a new project |
GET |
/api/projects/ |
List all projects |
GET |
/api/projects/{project_id} |
Get a project by ID |
| Method | Path | Description |
|---|---|---|
POST |
/api/projects/{project_id}/upload |
Upload images; triggers YOLOv8 inference |
GET |
/api/projects/{project_id}/images |
List uploaded images |
GET |
/api/projects/{project_id}/detections |
Get raw detection results |
| Method | Path | Description |
|---|---|---|
GET |
/api/projects/{project_id}/progress |
Completion % + requirement matches |
| Method | Path | Description |
|---|---|---|
GET |
/health |
Basic health check |
GET |
/health/detailed |
Health + system + application metrics |
GET |
/metrics |
Request stats, error rates, endpoint metrics |
GET |
/model-info |
Loaded YOLOv8 model details |
curl -X POST http://localhost:8000/api/projects/ \
-H "Content-Type: application/json" \
-d '{
"name": "Living Room Inspection",
"requirements": ["chair", "couch", "tv", "dining table", "lamp"]
}'Response:
{
"id": "3f7a2b1e-...",
"name": "Living Room Inspection",
"requirements": ["chair", "couch", "tv", "dining table", "lamp"],
"created_at": "2025-01-01T10:00:00Z"
}curl -X POST http://localhost:8000/api/projects/{project_id}/upload \
-F "files=@room1.jpg" \
-F "files=@room2.jpg"curl http://localhost:8000/api/projects/{project_id}/progressResponse:
{
"project_id": "3f7a2b1e-...",
"completion_percentage": 60.0,
"requirement_matches": [
{ "requirement": "chair", "detected": true, "confidence": 0.87, "count": 2 },
{ "requirement": "couch", "detected": true, "confidence": 0.91, "count": 1 },
{ "requirement": "tv", "detected": true, "confidence": 0.79, "count": 1 },
{ "requirement": "dining table", "detected": false, "confidence": null, "count": 0 },
{ "requirement": "lamp", "detected": false, "confidence": null, "count": 0 }
],
"detection_summary": {
"total_objects_detected": 12,
"unique_objects": ["chair", "couch", "bottle", "tv"],
"average_confidence": 0.824
}
}A GitHub Actions pipeline is defined at .github/workflows/ci.yml and runs on push/PR to main and develop.
| Job | Trigger | Steps |
|---|---|---|
| lint | All pushes/PRs | ESLint (frontend), Ruff + Flake8 (backend) |
| test-frontend | After lint | npm test (Vitest) + Codecov upload |
| test-backend | After lint | pytest --tb=short -v + Codecov upload |
| build-docker | After both test jobs | Builds sytescan-frontend and sytescan-backend Docker images (not pushed) |
| security | All pushes/PRs | Trivy filesystem vulnerability scan (CRITICAL/HIGH) |
- Create a Web Service and connect the GitHub repository.
- Configure build and start commands:
Build Command: pip install -r backend/requirements.txt Start Command: cd backend && uvicorn main:app --host 0.0.0.0 --port $PORT - Add environment variables (see table above). Use a Render-managed PostgreSQL instance for
DATABASE_URL.
- Import the repository into Vercel (auto-detects Next.js).
- Set environment variable:
NEXT_PUBLIC_API_URL=https://your-backend.onrender.com - Push to
maintriggers automatic deployment.
# Build images
docker-compose build
# Start in detached mode
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose downSee DEPLOYMENT.md for a complete Nginx configuration covering frontend proxying, API routing, large-file upload handling, and SSL/TLS setup.
| Model | Params | Speed | Accuracy | Recommended For |
|---|---|---|---|---|
yolov8n.pt |
~3.2M | Fastest | Lowest | Free-tier hosting (default) |
yolov8s.pt |
~11.2M | Fast | Good | Development / light prod |
yolov8m.pt |
~25.9M | Medium | Better | Standard production |
yolov8l.pt |
~43.7M | Slow | High | High-accuracy requirements |
yolov8x.pt |
~68.2M | Slowest | Highest | GPU-accelerated environments |
Set YOLO_MODEL=yolov8s.pt (or higher) in production for improved detection accuracy.
# Run all unit and component tests (Vitest)
npm test
# Watch mode
npm run test:watch
# End-to-end workflow test
npm run test:e2e
# All tests
npm run test:allcd backend
source venv/bin/activate
# Run full test suite
pytest
# Verbose output
pytest -v
# Specific test file
pytest tests/test_progress_service.pyOr via Make:
make test # Frontend + backend
make test-frontend
make test-backend
make test-e2e| Layer | Test Files | Scope |
|---|---|---|
| Frontend | src/test/ (4 files) |
Unit tests for components, page rendering, E2E workflow |
| Backend | backend/tests/ (10 files) |
API endpoints, services, schemas, database, E2E workflow |
| Endpoint | Returns |
|---|---|
GET /health |
{"status": "healthy", "timestamp": "..."} |
GET /health/detailed |
Status + CPU %, memory %, disk %, avg response time, error counts |
GET /metrics |
Per-endpoint request counts, avg/min/max response times, error rates |
- Format:
%(asctime)s - %(name)s - %(levelname)s - %(message)s - Levels:
DEBUG(development) →INFO/WARNING(production) - Middleware: Every request and response is logged with method, path, and status code
- Structured context: Service-layer functions log operation outcomes with project IDs
PerformanceMonitor (singleton at app/monitoring/metrics.py) tracks:
- Rolling window of last 1,000 request durations
- Per-endpoint hit count, total time, and error count
- System resource snapshot on demand (via
psutil)
Health thresholds:
| Metric | Warning Threshold |
|---|---|
| CPU usage | > 80% |
| Memory usage | > 85% |
| Disk usage | > 90% |
| Average response time | > 5 s |
| Concern | Implementation |
|---|---|
| Input validation | Pydantic schemas enforce types, lengths, and ranges on all request bodies |
| SQL injection | SQLAlchemy ORM parameterizes all queries |
| File upload safety | Extension whitelist (.jpg, .jpeg, .png), 10 MB size cap |
| CORS | Configurable CORS_ORIGINS_STR; wildcard (*) should be restricted in production |
| Non-root container | Both Dockerfiles create and run as unprivileged users (appuser / nextjs) |
| Secret management | Secrets loaded from environment variables via pydantic-settings; .env is gitignored |
| PyTorch model loading | Safe globals mechanism used for YOLOv8 deserialization (PyTorch 2.6+ compatible) |
⚠️ Assumption: No authentication or authorization layer is currently implemented. All API endpoints are publicly accessible. For production deployments with sensitive data, an auth layer (e.g., API keys, OAuth2) should be added.
❗ Needs verification: Rate limiting is noted in deployment docs as an nginx responsibility but is not enforced at the application level.
- Fork the repository and create a feature branch:
git checkout -b feature/your-feature-name
- Install dependencies:
make setup - Make changes, ensuring:
- Backend tests pass:
make test-backend - Frontend tests pass:
make test-frontend - No linting errors:
make lint
- Backend tests pass:
- Commit with a descriptive message following conventional commits.
- Open a pull request against
main.
Please review CONTRIBUTING.md and CODE_OF_CONDUCT.md before submitting.
For security vulnerabilities, follow the responsible disclosure process in SECURITY.md.
| Status | Feature |
|---|---|
| ✅ Active | Progress Analyzer (AI object detection + completion tracking) |
| 🔜 Planned | Floor Plan Generation — automatically produce architectural floor plans from site images |
| 🔜 Planned | Interior Designer — AI-powered room design and furniture placement recommendations |
| 🔜 Planned | Authentication & multi-tenant project isolation |
| ✅ Active | GitHub Actions CI/CD pipeline (lint → test → Docker build → security scan) |
| 🔜 Planned | Async job queue for long-running detection tasks |
| 🔜 Planned | Redis caching for detection results |
| 🔜 Planned | GPU acceleration support for YOLOv8 inference |
| 🔜 Planned | Custom model training pipeline integration |
MIT License — Copyright © 2025 Sai Avinash Patoju. See LICENSE for full terms.