A full-stack web application built with Django REST Framework (backend) and React + TypeScript (frontend), containerized with Docker.
- Prerequisites
- Quick Start
- Testing the System
- Project Structure
- Common Commands
- Troubleshooting
- Technology Stack
- Architecture & Design
- AI/Classification Approach
- Scaling, Testing & Monitoring
- Future Improvements
- Summary
- Docker (version 20.10+) and Docker Compose (version 2.0+)
Optional (for local development without Docker):
- Node.js 18+, Python 3.12+, PostgreSQL 16+
git clone https://github.com/mudasir45/smart-comments-app.git
cd smart-comments-appCreate a .env file in the root directory:
POSTGRES_DB=smartcomments
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=db
BACKEND_PORT=8000
FRONTEND_PORT=3000
VITE_API_URL=http://localhost:8000
SECRET_KEY=django-insecure-%s8am=+@tuaj%g-8!6=7nu7t78etof27882qj4a30&m3t(vf19)
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0docker compose up --buildIn a new terminal:
docker compose exec backend python manage.py migrate
docker compose exec backend python manage.py createsuperuser- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- Django Admin: http://localhost:8000/admin
- Health Check: http://localhost:8000/api/health/
To test the comment classification logic, we've provided a comprehensive set of test comments in test_comments.md. This file contains:
- Safe Comments: Examples that should NOT be flagged (polite, normal comments)
- Flagged Comments: Examples that SHOULD be flagged, organized by trigger type:
- Profanity examples
- Excessive capitalization
- Spam keywords
- Multiple violations (high confidence)
- Repeated characters
- Excessive links
-
Via Django Admin:
- Go to http://localhost:8000/admin/comments/comment/add/
- Copy comments from
test_comments.md - The flagged status is set automatically based on classification
-
Via API (see
test_comments.mdfor curl examples):curl -X POST http://localhost:8000/api/posts/1/comments/ \ -H "Content-Type: application/json" \ -d '{"text": "Great article!", "author": "Alice"}'
-
Via Frontend:
- Navigate to any post detail page
- Submit comments through the comment form
- Check the Moderator View to see flagged comments
For detailed instructions and examples, see test_comments.md.
smart-comments-app/
βββ backend/ # Django backend
β βββ comments/ # Comments app
β β βββ migrations/ # Database migrations
β β βββ tests/ # Test suite
β β β βββ test_classifier.py
β β β βββ test_views.py
β β βββ admin.py # Django admin configuration
β β βββ classifier.py # Comment classification logic
β β βββ models.py # Post and Comment models
β β βββ serializers.py # DRF serializers
β β βββ urls.py # URL routing
β β βββ views.py # API views
β βββ smartcomments/ # Project settings
β β βββ settings.py
β β βββ urls.py
β β βββ wsgi.py
β βββ manage.py
β βββ requirements.txt
β βββ Dockerfile
βββ frontend/ # React + TypeScript frontend
β βββ src/
β β βββ components/ # React components
β β β βββ CommentForm.tsx
β β β βββ CommentList.tsx
β β β βββ ModeratorView.tsx
β β β βββ PostDetail.tsx
β β β βββ PostForm.tsx
β β β βββ PostList.tsx
β β βββ services/ # API service layer
β β β βββ api.ts
β β βββ types/ # TypeScript types
β β β βββ index.ts
β β βββ App.tsx
β β βββ App.css
β β βββ index.css
β β βββ main.tsx
β βββ package.json
β βββ vite.config.ts
β βββ Dockerfile
βββ docker-compose.yml # Docker orchestration
βββ test_comments.md # Test comments for classification
βββ .env # Environment variables (create this)
# Start services
docker compose up -d
# View logs
docker compose logs -f
# Stop services
docker compose down
# Rebuild
docker compose build --no-cache# Migrations
docker compose exec backend python manage.py migrate
docker compose exec backend python manage.py makemigrations
# Create superuser
docker compose exec backend python manage.py createsuperuser
# Django shell
docker compose exec backend python manage.py shell# Find process using port
lsof -i :3000 # or :8000, :5432
# Change port in docker-compose.yml or kill the process# Check database status
docker compose ps
docker compose logs db
# Wait for database to be ready
docker compose up db- Verify
VITE_API_URL=http://localhost:8000in.env - Check backend is running:
curl http://localhost:8000/api/health/ - Check CORS settings in
backend/smartcomments/settings.py
docker compose down -v
docker compose build --no-cache
docker compose upBackend: Django 6.0.1, Django REST Framework 3.16.1, PostgreSQL 16
Frontend: React 19.2.0, TypeScript 5.9.3, Vite 7.2.4, Axios 1.13.2
DevOps: Docker, Docker Compose
Three-tier architecture: React frontend β Django REST API β PostgreSQL. Simple and straightforward.
Backend Choices:
- Django REST Framework: Easy serialization, validation, and API structure. Heavy but works well.
- PostgreSQL: Reliable, good indexing. Using composite indexes on
(post, created_at)and(flagged, created_at)for fast queries. - ViewSets for standard CRUD, custom APIViews for comment creation and flagged comments endpoint.
- Classification runs synchronously during comment creation - simple but could be async later.
Frontend Choices:
- React + TypeScript: Type safety catches bugs early. Functional components with hooks.
- Component structure: Separate components for list/detail/forms - easy to maintain.
- Axios service layer: Centralized API calls with interceptors for error handling.
- No Redux - local state is enough for this scope.
Classification System:
- Rule-based approach (no ML yet). Fast, predictable, easy to debug.
- Modular design in
classifier.py- each rule is separate, easy to extend or replace. - Confidence scoring (0.0-1.0) with threshold at 0.6.
- Designed to swap in ML models later without changing the interface.
Currently using rule-based classification - checks for offensive words, spam keywords, excessive caps, repeated characters, and too many links. Works well for MVP.
Why rules first?
- No training data needed
- Fast (<5ms per comment)
- Deterministic and debuggable
- Good baseline before adding ML complexity
Migration path to ML:
The classify_comment() function returns a ClassificationResult dict with label, confidence, and reason. Any ML model can plug into this same interface.
Practical migration:
- Phase 1: Keep fast rules (caps, links), replace semantic checks (offensive words) with a simple ML model (scikit-learn TF-IDF + Naive Bayes)
- Phase 2: Fine-tune a transformer model (BERT/RoBERTa) when you have labeled data from moderator actions
- Phase 3: Deploy ML model as async task (Celery) if it's slow, or as external service if you need independent scaling
When to switch to ML:
- When rules miss too many edge cases
- When you have labeled data from moderators
- When you need context understanding (sarcasm, cultural nuances)
Backend: Django is stateless - run multiple instances behind a load balancer. Use Redis for caching frequently accessed posts and comment counts.
Database:
- Read replicas for list views (reads are more common than writes)
- Connection pooling (PgBouncer)
- Partitioning comments table by date if it gets huge (>10M rows)
Frontend: Build static assets, serve via CDN. Already using Vite for code splitting.
Caching strategy:
- Cache post lists for 15-30 minutes
- Cache flagged comments count for 5 minutes
- Invalidate on new comments/posts
Current coverage: ~75% (strong on classifier, decent on API views)
Unit tests: Classifier rules, API endpoints, edge cases. See backend/comments/tests/.
What's missing:
- Integration tests (full request cycle)
- Frontend component tests
- E2E tests for critical flows
- Load testing (use Locust or k6 to test classification performance under load)
Recommendation: Add integration tests for comment creation β classification β flagged view flow. Frontend tests can come later if needed.
Current: Basic health check endpoint at /api/health/ that checks database connectivity.
Production setup should include:
- APM: Sentry for error tracking (Django + React)
- Metrics: Prometheus + Grafana for:
- Request rate and latency (p95, p99)
- Classification performance (time, accuracy)
- Database query times
- Error rates
- Logging: Structured JSON logs (ELK stack or Datadog)
- Alerts: Error rate > 1%, latency > 500ms p95, database connection pool exhaustion
Key metrics to watch:
- Classification false positive rate (moderator reviews)
- Comment creation rate
- API response times
- Database query performance
Quick wins (1-2 weeks):
- User authentication (JWT) - anonymous comments are fine for MVP but real users enable better features
- Rate limiting - prevent spam/abuse
- Comment editing/deletion - users should fix typos
- Markdown support - better formatting than plain text
Medium term (1-2 months):
- ML classification - when rules aren't enough, fine-tune BERT/RoBERTa with moderator-labeled data
- Moderation workflow - approve/reject/ban actions, not just flagging
- Nested comments/replies - better conversations
- Full-text search - find comments by content
Long term (3-6 months):
- Multi-language support - expand beyond English
- Recommendation system - show best comments first
- Image/media in comments - richer discussions
- Microservices split - if team grows or services need independent scaling
Technical debt:
- Increase test coverage to >90% (especially integration tests)
- Add API documentation (Swagger/OpenAPI)
- Better error handling with structured error codes
- Security audit (XSS prevention, input sanitization)
- Performance optimization (database query audit, Redis caching layer)
This is a solid MVP with clean architecture and a clear path forward. The rule-based classifier works well for now, and the modular design makes it easy to swap in ML models when needed. The system can handle moderate scale (100K+ comments) with the current setup, and scaling strategies are straightforward.
What's good:
- Fast classification, predictable results
- Clear migration path to ML/AI
- Scalable foundation (indexes, pagination)
- Good test coverage for critical paths
- Production-ready Docker setup
What needs work:
- More comprehensive testing (integration, e2e)
- Monitoring/observability in production
- User authentication for real-world use
- ML integration when rules hit limits
Happy Coding! π