A production-ready, full-stack project management application with strict organization-level data isolation. Built with Django, GraphQL, React, and TypeScript.
This application provides a complete project management solution where organizations can manage projects, tasks, and comments with complete data isolation. The system uses organization slug-based multi-tenancy to ensure no cross-organization data access.
project-management-system/
│
├── backend/ # Django + GraphQL API
│ ├── core/ # Django project configuration
│ ├── projects/ # Main application (models, schema, admin)
│ ├── manage.py
│ └── requirements.txt
│
└── frontend/ # React + TypeScript application
├── src/
│ ├── components/ # React components
│ ├── graphql/ # GraphQL queries
│ ├── lib/ # Apollo Client setup
│ └── types/ # TypeScript interfaces
├── package.json
└── vite.config.ts
- Django 4.2.7 - Web framework
- Graphene-Django 3.1.5 - GraphQL implementation
- PostgreSQL - Database
- Python 3.10+ - Programming language
- React 18.2 - UI framework
- TypeScript 5.2 - Type-safe JavaScript
- Bun - Fast package manager
- Vite - Build tool
- Apollo Client - GraphQL client
- TailwindCSS - Utility-first CSS
- shadcn/ui - Component library
cd backend
# Create virtual environment
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # macOS/Linux
# Install dependencies
pip install -r requirements.txt
# Setup environment variables
cp .env.example .env
# Edit .env with your database credentials
# Create database (PostgreSQL)
# CREATE DATABASE projectmanagement;
# Run migrations
python manage.py makemigrations
python manage.py migrate
# Create superuser (optional)
python manage.py createsuperuser
# Start server
python manage.py runserverBackend will be available at: http://localhost:8000
GraphQL playground: http://localhost:8000/graphql/
cd frontend
# Install Bun (if not installed)
# Windows: powershell -c "irm bun.sh/install.ps1 | iex"
# macOS/Linux: curl -fsSL https://bun.sh/install | bash
# Install dependencies
bun install
# Setup environment variables
cp .env.example .env
# Edit .env if needed
# Start development server
bun run devFrontend will be available at: http://localhost:3000
The application implements organization-level data isolation through:
- Every GraphQL query and mutation requires an
organizationSlugparameter - All database queries filter by organization
- Resolver-level validation ensures organization exists
- Cascading foreign keys maintain referential integrity
-
Organization Slug as Context
- Passed explicitly in every GraphQL operation
- Validates organization existence before processing
- Returns empty results for invalid organizations
-
Query-Level Filtering
# All queries filter by organization projects = Project.objects.filter(organization=org) tasks = Task.objects.filter(project__organization=org)
-
No Cross-Organization Access
- Impossible to query data from other organizations
- Even with valid IDs, organization check prevents access
- Frontend enforces organization context on all requests
In production, you would:
- Add JWT authentication
- Derive organization from authenticated user
- Remove explicit organization slug from client
- Middleware to set organization context automatically
- Primary tenant entity
- Unique slug for identification
- Contact email and metadata
- Belongs to an Organization
- Has multiple Tasks
- Tracks status (ACTIVE, COMPLETED, ON_HOLD)
- Due date tracking
- Belongs to a Project (and indirectly to Organization)
- Status tracking (TODO, IN_PROGRESS, DONE)
- Assignee via email
- Due date tracking
- Belongs to a Task
- Author via email
- Timestamped content
List Projects
query {
projects(organizationSlug: "acme-corp", status: "ACTIVE") {
id
name
taskCount
completedTasks
completionPercentage
}
}Get Project with Tasks
query {
project(id: "1", organizationSlug: "acme-corp") {
id
name
tasks {
id
title
status
}
}
}Create Project
mutation {
createProject(
organizationSlug: "acme-corp"
name: "Website Redesign"
status: "ACTIVE"
dueDate: "2024-12-31"
) {
success
project {
id
name
}
}
}Update Task Status
mutation {
updateTask(id: "1", organizationSlug: "acme-corp", status: "DONE") {
success
task {
id
status
}
}
}See backend/README.md for complete API documentation.
- Create, read, update projects
- Filter by status (Active, Completed, On Hold)
- Search projects by name
- Track task statistics and completion percentage
- Due date management
- Kanban-style board view
- Create and update tasks
- Status tracking (To Do, In Progress, Done)
- Assignee management via email
- Due date tracking
- Task comments/discussions
- Minimal, professional design
- Pure grayscale color scheme
- shadcn/ui components
- Responsive layout
- Loading and error states
- Optimistic UI updates
- No unnecessary colors
- Clean typography
- Ample whitespace
- Clear visual hierarchy
- Black (#000000) - Background
- White (#FFFFFF) - Primary text, buttons
- Gray scales - Borders, secondary text, hover states
- No other colors used
- Consistent shadcn/ui components
- Subtle transitions
- Clear interactive states
- Accessible by default
- Modify models in
backend/projects/models.py - Create migrations:
python manage.py makemigrations - Apply migrations:
python manage.py migrate - Update GraphQL schema in
backend/projects/schema.py - Test in GraphiQL:
http://localhost:8000/graphql/
- Define TypeScript types in
frontend/src/types/ - Create/update GraphQL queries in
frontend/src/graphql/ - Build React components in
frontend/src/components/ - Style with TailwindCSS utility classes
- Test in browser:
http://localhost:3000
# Example test structure
from django.test import TestCase
from projects.models import Organization, Project
class ProjectTestCase(TestCase):
def setUp(self):
self.org = Organization.objects.create(
name="Test Org",
slug="test-org"
)
def test_project_creation(self):
project = Project.objects.create(
organization=self.org,
name="Test Project"
)
self.assertEqual(project.organization, self.org)- Component testing with React Testing Library
- GraphQL mocking with Apollo MockedProvider
- Type safety with TypeScript strict mode
- Organization slug-based isolation
- CORS configured for development
- CSRF protection enabled
- SQL injection prevention (Django ORM)
- Authentication: JWT tokens
- Authorization: Role-based access control
- HTTPS: SSL/TLS encryption
- Rate Limiting: Prevent API abuse
- Input Validation: Sanitize all inputs
- Environment Variables: Secure credential management
- Database indexes on foreign keys
- Query optimization with select_related/prefetch_related
- Efficient resolver implementation
- Apollo Client caching
- Optimistic UI updates
- Code splitting with React lazy loading
- Vite build optimization
- PostgreSQL connection pooling
- Read replicas for query scaling
- Proper indexing strategy
- Stateless backend for horizontal scaling
- CDN for frontend assets
- Caching layer (Redis) for frequent queries
- GraphQL subscriptions for real-time updates
- Background job processing (Celery)
- Full-text search (Elasticsearch)
- File storage (S3/CloudFlare R2)
- Set up PostgreSQL database
- Configure environment variables
- Run migrations
- Collect static files:
python manage.py collectstatic - Use gunicorn/uwsgi for WSGI server
- Set up nginx for reverse proxy
- Build production bundle:
bun run build - Deploy
dist/folder to static hosting - Configure environment variables
- Set up CDN for assets
- Backend: Railway, Render, DigitalOcean, AWS
- Frontend: Vercel, Netlify, Cloudflare Pages
- Database: Supabase, Railway, managed PostgreSQL
- Verify PostgreSQL is running
- Check database credentials in
.env - Ensure database exists:
CREATE DATABASE projectmanagement;
- Check
CORS_ALLOWED_ORIGINSin backend settings - Verify frontend is using correct API URL
- Ensure both servers are running
- Check GraphiQL for query syntax
- Verify organization slug is valid
- Check backend logs for detailed errors
- Clear node_modules:
rm -rf node_modules && bun install - Check Bun version:
bun --version - Verify environment variables are set
- Python: PEP 8, black formatter
- TypeScript: ESLint, Prettier
- Git: Conventional commits
- Create feature branch
- Make changes with tests
- Update documentation
- Submit PR with clear description
This project is created for technical assessment purposes.
For questions or issues:
- Check documentation in
backend/README.mdandfrontend/README.md - Review GraphQL schema in GraphiQL
- Check browser console for frontend errors
- Review Django logs for backend errors
- Single endpoint for all operations
- Strong typing with schema
- Efficient data fetching
- Great developer experience
- Fast package installation
- Native TypeScript support
- Modern JavaScript runtime
- Better performance than npm/yarn
- Copy-paste components (full control)
- Built on Radix UI (accessible)
- TailwindCSS integration
- No runtime dependency
- URL-friendly identification
- Human-readable
- Easy to implement
- Simple multi-tenancy
- Real-time collaboration
- File attachments
- Activity timeline
- Advanced search and filtering
- Dashboard analytics
- Team member management
- Project templates
- Email notifications
- GraphQL subscriptions
- Comprehensive test suite
- CI/CD pipeline
- Docker support
- API documentation generation
- Performance monitoring
- Error tracking (Sentry)
- Django and Graphene-Django communities
- React and TypeScript teams
- shadcn for the excellent UI components
- TailwindCSS for utility-first CSS
Built with attention to detail, clean architecture, and production-ready practices.