Add comprehensive project description, feature list, and environment variable reference to improve onboarding and self‑documentation.
417 lines
15 KiB
Markdown
417 lines
15 KiB
Markdown
# Project Management
|
|
|
|
A full-featured, open-source project management system built with Django. It helps teams organize, track, and manage their work through an intuitive Kanban board interface with ticket tracking, epics, and real-time collaboration features.
|
|
|
|
Whether you're running a software development team, a creative agency, or any project-driven organization, this tool replaces spreadsheets and scattered to-do lists with a centralized platform. Teams can create projects with custom ticket prefixes, organize work into epics, track progress with Kanban boards, and stay updated with in-app and email notifications. The built-in role-based access (superadmin, manager, member) ensures the right people have the right permissions.
|
|
|
|
External stakeholders can view project dashboards via shareable read-only links without creating accounts. The UI is fully customizable with 19 color themes, sidebar or top navigation, and dark/light mode preferences — all stored per user.
|
|
|
|
The application follows a modern Django architecture with REST API endpoints (documented via Swagger), JWT authentication, Google OAuth, and a task queue for background processing. It ships with Docker Compose for production-ready MySQL + gunicorn deployment, comprehensive demo data seeding, and a GitHub Actions CI pipeline.
|
|
|
|
---
|
|
|
|
## Tech Stack
|
|
|
|
| Layer | Technology |
|
|
|-------|-----------|
|
|
| **Backend** | Django 6, Django REST Framework, SimpleJWT, Django Q2 |
|
|
| **Frontend** | HTMX, Alpine.js, Tailwind CSS v4 (via django-tailwind-cli) |
|
|
| **Database** | SQLite (dev) / MySQL 8.0 (prod) |
|
|
| **Task Queue** | Django Q2 (ORM broker, 2 workers) |
|
|
| **API Docs** | drf-spectacular (Swagger UI + OpenAPI schema) |
|
|
| **Admin** | django-jazzmin (themed admin panel) |
|
|
| **Auth** | JWT (access 1h / refresh 30d) + Google OAuth |
|
|
| **Package Manager** | [uv](https://github.com/astral-sh/uv) |
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
- **Projects** — create, manage, pin projects with colour labels, ticket prefixes, and member roles
|
|
- **Tickets** — full CRUD, bulk delete, Excel import/export, priority and status management
|
|
- **Epics** — group tickets into epics with progress tracking (% completion)
|
|
- **Kanban Board** — drag-and-drop ticket status columns per project
|
|
- **Notifications** — in-app and email notifications on ticket events (create, update, assign, comment)
|
|
- **User Management** — role-based access (superadmin / manager / member) with custom user model
|
|
- **External Access** — share a read-only dashboard link with external users via a secure token
|
|
- **Project Notes** — attach rich-text notes to projects
|
|
- **Google OAuth** — sign in with Google
|
|
- **Bulk Operations** — bulk delete tickets, bulk delete notes
|
|
- **Column Visibility** — show/hide columns on project detail and list views
|
|
- **Search & Filter** — search, filter by status/priority, paginated lists
|
|
- **UI Customization** — 19 color themes, sidebar/top navigation, dark/light mode
|
|
- **Site Branding** — custom logo, favicon, brand name, copyright name via admin
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
### Prerequisites
|
|
|
|
- Python 3.13+
|
|
- [uv](https://github.com/astral-sh/uv)
|
|
|
|
### 1. Clone & install
|
|
|
|
```bash
|
|
git clone https://github.com/S4NKALP/project-managment.git
|
|
cd project-managment
|
|
uv sync
|
|
```
|
|
|
|
### 2. Configure environment
|
|
|
|
```bash
|
|
cp .env.sample .env
|
|
```
|
|
|
|
Minimal `.env`:
|
|
|
|
```ini
|
|
DJANGO_SETTINGS_MODULE=config.settings.development
|
|
SECRET_KEY=your-secret-key
|
|
BASE_URL=http://localhost:8000
|
|
SITE_NAME=Project Management
|
|
```
|
|
|
|
### 3. Run migrations & create superuser
|
|
|
|
```bash
|
|
uv run python manage.py migrate
|
|
uv run python manage.py createcachetable
|
|
uv run python manage.py createsuperuser
|
|
```
|
|
|
|
### 4. Start development server
|
|
|
|
```bash
|
|
uv run python manage.py runserver
|
|
```
|
|
|
|
Open **http://localhost:8000** in your browser. Authenticated users are redirected to the dashboard.
|
|
|
|
### Seed demo data (optional)
|
|
|
|
```bash
|
|
uv run python manage.py seed_data # creates priorities + admin user
|
|
uv run python manage.py demo_data # creates rich demo content
|
|
```
|
|
|
|
---
|
|
|
|
## Using `just` (recommended)
|
|
|
|
Install [just](https://github.com/casey/just), a command runner. See all available commands:
|
|
|
|
```bash
|
|
just
|
|
```
|
|
|
|
### Development
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `just dev` | Run development server on 0.0.0.0:8000 |
|
|
| `just dev-server HOST="127.0.0.1" PORT="9000"` | Dev server with custom host/port |
|
|
| `just shell` | Django shell |
|
|
| `just shell-plus` | Django shell_plus (IPython) |
|
|
| `just dbshell` | Database shell |
|
|
|
|
### Database
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `just migrate` | Run all migrations |
|
|
| `just makemigrations` | Create migrations for all apps |
|
|
| `just makemigrations-app APP` | Create migrations for a specific app |
|
|
| `just showmigrations` | Show migration status |
|
|
| `just reset-db` | Flush DB, recreate migrations, migrate |
|
|
| `just clear-cache` | Clear database cache |
|
|
|
|
### Testing & Quality
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `just test` | Run Django tests |
|
|
| `just test-coverage` | Run pytest with coverage (HTML + terminal) |
|
|
| `just lint` | Ruff lint check |
|
|
| `just format` | Ruff format |
|
|
| `just style` | Lint + format |
|
|
| `just check` | Django system checks |
|
|
| `just check-deploy` | Security checks (production settings) |
|
|
| `just ci` | Full CI: ruff check + format check + manage.py check |
|
|
|
|
### Setup
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `just setup` | uv sync → migrations → createcachetable → superuser |
|
|
| `just setup-complete` | Same as setup + collectstatic |
|
|
|
|
### Production
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `just server` | Start gunicorn (1 worker) |
|
|
| `just server-prod WORKERS="4"` | Start gunicorn with N workers |
|
|
| `just server-watch` | Gunicorn with `--reload` |
|
|
|
|
### Package Management
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `just install PACKAGE` | uv add a package |
|
|
| `just install-dev PACKAGE` | uv add --dev a package |
|
|
| `just remove PACKAGE` | uv remove a package |
|
|
| `just pin-deps` | Sync pyproject.toml from uv.lock |
|
|
| `just clean` | Remove Python cache, coverage, pytest cache |
|
|
|
|
---
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
project-managment/
|
|
├── config/ # Django configuration
|
|
│ ├── settings/
|
|
│ │ ├── base.py # Shared settings (shared by dev & prod)
|
|
│ │ ├── development.py # Dev overrides (SQLite, DEBUG=True)
|
|
│ │ └── production.py # Prod overrides (MySQL, HTTPS, HSTS)
|
|
│ ├── urls.py # Root URL configuration
|
|
│ ├── wsgi.py
|
|
│ └── asgi.py
|
|
│
|
|
├── src/ # Application code
|
|
│ ├── accounts/ # Custom User model, auth, Google OAuth
|
|
│ ├── projects/ # Projects & members API
|
|
│ ├── tickets/ # Tickets, statuses, priorities API
|
|
│ ├── epics/ # Epics API
|
|
│ ├── notes/ # Project notes API
|
|
│ ├── notifications/ # In-app & email notifications
|
|
│ ├── external/ # External token-based read-only access
|
|
│ └── dashboard/ # All HTML-rendering views
|
|
│ ├── views/ # Dashboard widgets & charts
|
|
│ ├── list_views/ # Paginated list views
|
|
│ ├── page_views/ # CRUD page views (create/edit forms)
|
|
│ ├── board_views/ # Kanban board views
|
|
│ ├── context_processors.py # Template context injection
|
|
│ └── filters.py # Ticket/project filter sets
|
|
│
|
|
├── templates/ # Django/Jinja HTML templates
|
|
│ ├── auth/ # Login page
|
|
│ ├── base.html # Base layout (nav, theme, modals)
|
|
│ ├── dashboard/ # Dashboard page, partials
|
|
│ ├── projects/ # Project detail, form, list, board
|
|
│ ├── tickets/ # Ticket detail, form, list
|
|
│ ├── epics/ # Epic overview, form
|
|
│ ├── notifications/ # Notification list, dropdown
|
|
│ ├── settings/ # UI settings (theme, nav, items per page)
|
|
│ ├── users/ # User profile, list, form
|
|
│ └── components/ # Reusable modals, rich text editor
|
|
│
|
|
├── static/ # Static files (CSS, JS, images)
|
|
├── manage.py
|
|
├── pyproject.toml # Dependencies, ruff config, project metadata
|
|
├── justfile # Task runner commands
|
|
├── Dockerfile # Production container (Python 3.13-slim)
|
|
├── docker-compose.yml # MySQL + app services
|
|
├── docker-entrypoint.sh # Runs migrations on container start
|
|
└── .env.sample # Environment variable template
|
|
```
|
|
|
|
---
|
|
|
|
## API Documentation
|
|
|
|
When running in development mode:
|
|
|
|
| Endpoint | Description |
|
|
|----------|-------------|
|
|
| `http://localhost:8000/api/docs/` | Swagger UI (drf-spectacular) |
|
|
| `http://localhost:8000/api/schema/` | OpenAPI 3 schema (YAML) |
|
|
|
|
### Key API routes
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `POST` | `/api/auth/login/` | JWT login (returns access + refresh tokens) |
|
|
| `POST` | `/api/auth/token/refresh/` | Refresh access token |
|
|
| `GET` | `/api/auth/me/` | Current user profile |
|
|
| `GET/POST` | `/api/projects/` | List / create projects |
|
|
| `GET/PUT/PATCH/DELETE` | `/api/projects/<id>/` | Project detail |
|
|
| `GET/POST` | `/api/projects/<id>/members/` | Project members |
|
|
| `GET/POST` | `/api/tickets/` | List / create tickets |
|
|
| `GET/PUT/PATCH/DELETE` | `/api/tickets/<id>/` | Ticket detail |
|
|
| `PATCH` | `/api/tickets/<id>/move/` | Move ticket between statuses |
|
|
| `GET/POST` | `/api/epics/` | List / create epics |
|
|
| `GET/POST` | `/api/notes/` | List / create notes |
|
|
| `GET/POST` | `/api/notifications/` | List notifications |
|
|
| `GET` | `/api/projects/stats/` | Aggregate project statistics |
|
|
|
|
---
|
|
|
|
## UI Customization
|
|
|
|
### Color Themes (19 themes)
|
|
|
|
Users can choose their accent color from 19 options via the UI Settings page (`/settings/ui/`):
|
|
|
|
| Name | Hex | Preview |
|
|
|------|-----|---------|
|
|
| Blue | `#3b82f6` | Default |
|
|
| Emerald | `#10b981` | |
|
|
| Green | `#22c55e` | |
|
|
| Indigo | `#6366f1` | |
|
|
| Orange | `#f97316` | |
|
|
| Purple | `#a855f7` | |
|
|
| Red | `#ef4444` | |
|
|
| Rose | `#f43f5e` | |
|
|
| Sky | `#0ea5e9` | |
|
|
| Teal | `#14b8a6` | |
|
|
| Violet | `#8b5cf6` | |
|
|
| Amber | `#f59e0b` | |
|
|
| Yellow | `#eab308` | |
|
|
| Pink | `#ec4899` | |
|
|
| Cyan | `#06b6d4` | |
|
|
| Lime | `#84cc16` | |
|
|
| Slate | `#64748b` | |
|
|
| Gray | `#6b7280` | |
|
|
| Zinc | `#71717a` | |
|
|
|
|
### Navigation Layout
|
|
|
|
- **Sidebar** (default) — vertical nav on the left
|
|
- **Top** — horizontal nav bar at the top
|
|
|
|
### Dark / Light Mode
|
|
|
|
Per-user dark/light mode preference, persisted in localStorage.
|
|
|
|
---
|
|
|
|
## Docker Deployment
|
|
|
|
### Build & run
|
|
|
|
```bash
|
|
docker compose up --build
|
|
```
|
|
|
|
This starts:
|
|
- **MySQL 8.0** (`db` service) with persistent volume
|
|
- **Django app** (`app` service) behind gunicorn on port 8000
|
|
|
|
### Services
|
|
|
|
| Service | Image | Port |
|
|
|---------|-------|------|
|
|
| `db` | mysql:8.0 | 3306 |
|
|
| `app` | (builds from Dockerfile) | 8000 |
|
|
|
|
The app container automatically runs migrations on startup via `docker-entrypoint.sh`.
|
|
|
|
---
|
|
|
|
## CI / CD
|
|
|
|
GitHub Actions workflow (`.github/workflows/ci.yml`) runs on every push/PR to `main` and `develop`:
|
|
|
|
| Job | Steps |
|
|
|-----|-------|
|
|
| **Lint** | `ruff check` + `ruff format --check` |
|
|
| **Test** | Django system check → pending migration check → `manage.py test --verbosity=2` |
|
|
| **Security** | `manage.py check --deploy` |
|
|
|
|
---
|
|
|
|
## Management Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `python manage.py seed_data` | Seed priorities and admin user (idempotent) |
|
|
| `python manage.py demo_data` | Create comprehensive demo data (14 users, 8 projects, epics, tickets, comments, notifications) |
|
|
| `python manage.py demo_data --clear` | Clear existing demo data before re-seeding |
|
|
|
|
---
|
|
|
|
## Environment Variables Reference
|
|
|
|
| Variable | Default | Required | Description |
|
|
|----------|---------|----------|-------------|
|
|
| `DJANGO_SETTINGS_MODULE` | — | Yes | `config.settings.development` or `config.settings.production` |
|
|
| `SECRET_KEY` | — | Yes | Django secret key (used in prod) |
|
|
| `ALLOWED_HOSTS` | `localhost,127.0.0.1` | No | Comma-separated allowed hostnames |
|
|
| `BASE_URL` | `http://localhost:8000` | Yes | Base URL for email links and redirects |
|
|
| `SITE_NAME` | `Project Management` | No | Displayed in UI, emails, and page titles |
|
|
| `TIME_ZONE` | `Asia/Kathmandu` | No | Server timezone |
|
|
|
|
### Database (Production)
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `DB_NAME` | `project_management` | MySQL database name |
|
|
| `DB_USER` | `project_user` | MySQL user |
|
|
| `DB_PASSWORD` | `project_password` | MySQL password |
|
|
| `DB_HOST` | `localhost` | MySQL host |
|
|
| `DB_PORT` | `3306` | MySQL port |
|
|
|
|
### Email (Production)
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `EMAIL_HOST` | `smtp.gmail.com` | SMTP server |
|
|
| `EMAIL_PORT` | `587` | SMTP port |
|
|
| `EMAIL_USE_TLS` | `True` | Enable TLS |
|
|
| `EMAIL_HOST_USER` | — | SMTP username |
|
|
| `EMAIL_HOST_PASSWORD` | — | SMTP password |
|
|
|
|
### Google OAuth
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `GOOGLE_CLIENT_ID` | — | Google OAuth client ID |
|
|
| `GOOGLE_CLIENT_SECRET` | — | Google OAuth secret |
|
|
| `GOOGLE_REDIRECT_URI` | `http://localhost:8000/api/auth/google/callback/` | OAuth callback URL |
|
|
|
|
### CORS
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `FRONTEND_URL` | `http://localhost:8000` | Allowed CORS origin (production) |
|
|
|
|
---
|
|
|
|
## Development Details
|
|
|
|
### Settings Profiles
|
|
|
|
| Profile | File | Database | Debug | Static Files |
|
|
|---------|------|----------|-------|--------------|
|
|
| Development | `config.settings.development` | SQLite (WAL mode) | `True` | Django static |
|
|
| Production | `config.settings.production` | MySQL | `False` | Whitenoise (compressed, manifest) |
|
|
|
|
### Authentication
|
|
|
|
- JWT tokens via `djangorestframework-simplejwt` (access: 1h, refresh: 30d, rotating)
|
|
- Session-based auth for browser (Django's `SessionMiddleware` + `cached_db` backend)
|
|
- Google OAuth for social login
|
|
- REST API uses `TokenAuthentication` (SimpleJWT) + `SessionAuthentication`
|
|
|
|
### Task Queue (Django Q2)
|
|
|
|
| Setting | Value |
|
|
|---------|-------|
|
|
| Workers | 2 |
|
|
| Timeout | 60s |
|
|
| Retry | 120s |
|
|
| Poll interval | 2s |
|
|
| Broker | ORM (database-backed) |
|
|
|
|
### Caching
|
|
|
|
Database-backed cache (`django_cache` table). Used for site branding (5 min TTL) and sessions (`cached_db` backend).
|
|
|
|
### Performance (Dev SQLite)
|
|
|
|
SQLite is configured with WAL mode, memory-mapped I/O, and performance pragmas for development.
|