A full-stack blog platform with AI-powered comment moderation built with Django REST Framework and React + TypeScript.
- π€ AI-Powered Classification: Optional OpenAI integration for nuanced content moderation
- π‘οΈ Rule-Based Fallback: Always-available pattern matching for banned words
- β‘ Real-Time Moderation: Comments auto-flagged on submission
- οΏ½ Moderator View: Dedicated interface for reviewing flagged content
- π³ Docker Ready: Complete containerization setup
- β Comprehensive Tests: 42 tests with 100% pass rate
- Framework: Django 5.2 + Django REST Framework
- Database: SQLite (dev), PostgreSQL-ready for production
- API Design: RESTful endpoints with nested resources
- Key Endpoints:
GET /api/posts/- List all postsGET /api/posts/{id}/- Get post with commentsPOST /api/posts/{id}/comments/- Add comment (auto-classified)
- Framework: React 18 with TypeScript for type safety
- Build Tool: Vite for fast development and optimized builds
- Routing: React Router for client-side navigation
- API Client: Axios with environment-aware URLs
- Pages:
/- Posts list with preview/posts/:id- Post detail with comments/moderator- Flagged comments review (bonus feature)
The platform supports dual classification modes with automatic fallback:
# Uses OpenAI GPT-4o-mini for context-aware moderation
classify_comment_ai(text: str) -> boolFeatures:
- Context-aware detection (understands sarcasm, nuance)
- Multi-language support
- ~500ms latency, ~$0.0002 per comment
- Requires OpenAI API key
# Pattern matching for banned words and heuristics
classify_comment_rule_based(text: str) -> boolFeatures:
- Banned words detection
- Excessive caps (>50% uppercase)
- Excessive punctuation (>5 marks)
- <1ms latency, zero cost
- No external dependencies
Why Dual Mode?
- AI: Nuanced, context-aware, handles edge cases
- Rules: Fast, reliable, works offline as fallback
- Graceful Degradation: System never fails if AI is unavailable
- Cost Control: Use AI only when needed
See AI_CLASSIFIER.md for complete documentation.
Backend (Terminal 1):
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
python manage.py migrate
python manage.py runserverBackend runs at http://127.0.0.1:8000
Optional - Enable AI Classification:
# Add to your environment or .env file
export USE_AI_CLASSIFIER=True
export OPENAI_API_KEY='sk-...'Frontend (Terminal 2):
cd frontend
npm install
npm run devFrontend runs at http://localhost:5173
docker compose up --build- Backend:
http://localhost:8000 - Frontend:
http://localhost:3000
See DOCKER.md for detailed Docker documentation.
Run the comprehensive test suite (42 tests):
cd backend
python manage.py test
# Run with coverage
coverage run --source='.' manage.py test
coverage reportTest Coverage:
- β 13 rule-based classifier tests
- β 11 AI classifier tests (with mocking)
- β 4 fallback mechanism tests
- β 14 API integration tests
All tests pass with proper error handling and fallback verification.
Problem: Blocking API calls for expensive operations
Solution: Use Celery + Redis for background tasks
@shared_task
def classify_comment_async(comment_id):
comment = Comment.objects.get(id=comment_id)
comment.flagged = ml_classifier.predict(comment.text)
comment.save()Benefits:
- Non-blocking API responses
- Retry failed classifications
- Horizontal scaling of workers
Current: Rule-based (fast, transparent)
Future: Fine-tuned transformer model
from transformers import pipeline
classifier = pipeline(
"text-classification",
model="unitary/toxic-bert"
)
def classify_comment_ml(text: str) -> bool:
result = classifier(text)[0]
return result['label'] == 'toxic' and result['score'] > 0.7Benefits:
- Context-aware detection
- Multi-language support
- Continuous improvement with feedback
Add User Roles:
User: Can post commentsModerator: Can review/approve flagged commentsAdmin: Full access
from rest_framework.permissions import IsAuthenticated
class ModeratorOnlyPermission(BasePermission):
def has_permission(self, request, view):
return request.user.role == 'moderator'- Indexing: Add indexes on
post_id,created_at,flagged - Caching: Redis cache for frequently accessed posts
- Read Replicas: Separate read/write databases
- Pagination: Limit query results (already implemented in DRF)
- Load Balancer: Nginx/HAProxy for multiple app servers
- CDN: CloudFlare for static assets
- Monitoring: Sentry for errors, Prometheus for metrics
- Auto-scaling: Kubernetes for container orchestration
- Comment Moderation Actions: Approve/reject buttons in moderator view
- User Authentication: JWT tokens with Django SimpleJWT
- Real ML Model: Fine-tune BERT on hate speech dataset
- Pagination: Implement on frontend for large post lists
- Search: Full-text search on posts/comments with PostgreSQL
- Rate Limiting: Prevent spam with Django Ratelimit
- Email Notifications: Alert moderators of flagged comments
- Comment Editing: Allow users to edit within 5 minutes
- Rich Text: Markdown support for post bodies
- Analytics Dashboard: Metrics on flagged comments, trends
- Real-time Updates: WebSocket for live comment feeds
- Multi-language: i18n for internationalization
- Accessibility: ARIA labels, keyboard navigation
- Mobile App: React Native with shared API
- A/B Testing: Experiment with different classification thresholds
assessment/
βββ backend/ # Django REST API
β βββ config/ # Django settings
β βββ posts/ # Posts app (models, views, serializers)
β βββ comments/ # Comments app (models, serializers)
β βββ classifier/ # Classification logic
β βββ manage.py
β βββ requirements.txt
βββ frontend/ # React + TypeScript
β βββ src/
β β βββ api/ # API client
β β βββ pages/ # Route components
β β βββ types/ # TypeScript interfaces
β β βββ App.tsx # Main app with routing
β β βββ main.tsx # Entry point
β βββ package.json
β βββ vite.config.ts
βββ docker-compose.yml # Container orchestration
βββ DOCKER.md # Docker documentation
βββ README.md # This file
| Decision | Choice | Rationale |
|---|---|---|
| Backend Framework | Django REST Framework | Batteries-included, great ORM, admin panel |
| Frontend Framework | React + TypeScript | Component reusability, type safety |
| Database | SQLite β PostgreSQL | Easy local dev, production-ready migration |
| Classification | Rule-based | Fast, transparent, no training data needed |
| API Design | REST | Simple, well-understood, good tooling |
| Testing | Django TestCase | Built-in, comprehensive, fast |
| Containerization | Docker + Compose | Consistent environments, easy deployment |
GET /api/posts/Response:
[
{
"id": 1,
"title": "First Post",
"body": "Post content...",
"comments": [
{
"id": 1,
"text": "Great post!",
"author": "Alice",
"created_at": "2026-01-12T10:00:00Z",
"flagged": false
}
]
}
]POST /api/posts/{id}/comments/
Content-Type: application/json
{
"text": "This is my comment",
"author": "Bob"
}Response:
{
"id": 2,
"text": "This is my comment",
"author": "Bob",
"created_at": "2026-01-12T10:05:00Z",
"flagged": false,
"post": 1
}This is a hiring challenge submission. For production use, consider:
- Adding proper authentication
- Implementing rate limiting
- Using a production WSGI server (Gunicorn)
- Setting up CI/CD pipeline
- Adding monitoring and logging
MIT License - feel free to use for learning purposes.
Built with β€οΈ as a hiring challenge to demonstrate full-stack skills, API design, and production mindset.