Files
project-managment/PLAN.md
T
sankalp 0357d78939 chore(root): remove DRF stack and update configuration
This change removes unused DRF-related dependencies, updates .env.sample and .gitignore to reflect new configuration, and adds a comprehensive project architecture plan (PLAN.md). It simplifies the stack and prepares the codebase for a modular, permission‑driven design.

New Features
- Added detailed PLAN.md outlining project structure, apps, permissions, and tech stack.
Enhancements
- Cleaned up .env.sample by removing obsolete environment variables.
- Updated .gitignore to exclude generated directories and track migrations properly.
Bug Fixes
- No bug fixes included in this commit.
2026-05-27 23:33:00 +05:45

13 KiB

Django Project Architecture Plan

Overview

This project is a modular Django-based project management and business operations platform with:

  • Role-based access control
  • Project management
  • Private kanban workflows
  • Issue tracking
  • Ticketing system
  • Finance & payroll
  • Activity tracking
  • HTMX + Alpine.js frontend architecture

Project Structure

myproject/
├── config/               # settings, urls, wsgi
├── apps/
│   ├── accounts/         # CustomUser, role system
│   ├── projects/         # Project, Membership
    │   ├── finance/          # Invoice, Payment, Expense, Payroll
│   ├── kanban/           # Board, Column, Card (private per user)
    │   ├── issues/           # Issue, Comment, Label, Status
    │   ├── tickets/          # Ticket, FeatureRequest
    │   └── activity/         # ActivityLog, progress aggregation
    ├── templates/
    │   ├── base.html
    │   ├── partials/         # HTMX partial templates
    │   └── components/       # Alpine.js UI components
    └── static/
    ```

    ---

# Actors

## Admin
    - Full system access
    - Manage users, projects, finance, tickets, and reports
    - Read-only access to aggregated kanban progress

## Client
    - View own projects
    - Create/view tickets
    - View invoices and payments
    - Comment on issues

## Team Member
    - Work on assigned issues
    - Access own kanban board
    - View assigned projects
    - Access payroll information

    ---

# Django Apps Breakdown

## 1. accounts

### Responsibilities
    - Authentication
    - Authorization
    - Role management
    - Project memberships

### Main Models

    ```python
    class CustomUser(AbstractUser):
        ROLE_CHOICES = [
        ("admin", "Admin"),
        ("client", "Client"),
        ("member", "Team Member"),
        ]

        role = models.CharField(max_length=20, choices=ROLE_CHOICES)
    ```

    ```python
    class ProjectMembership(models.Model):
        user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    project = models.ForeignKey("projects.Project", on_delete=models.CASCADE)
        joined_at = models.DateTimeField(auto_now_add=True)
        ```

        ---

## 2. projects

### Responsibilities
        - Core project management
        - Team assignment
        - Project lifecycle

### Main Models

        ```python
        class Project(models.Model):

            class Status(models.TextChoices):
                PLANNING = "planning"
                ACTIVE = "active"
                REVIEW = "review"
                DONE = "done"

                name = models.CharField(max_length=255)
    client = models.ForeignKey(
            "accounts.CustomUser",
            on_delete=models.CASCADE,
            related_name="client_projects"
            )

status = models.CharField(
        max_length=20,
        choices=Status.choices,
        default=Status.PLANNING
        )

    members = models.ManyToManyField(
            "accounts.CustomUser",
            through="accounts.ProjectMembership"
            )
    ```

    ---

## 3. finance

### Responsibilities
    - Invoices
    - Payments
    - Expenses
    - Payroll management

### Main Models

## Invoice

    ```python
    class Invoice(models.Model):

        class Status(models.TextChoices):
            PENDING = "pending"
            PAID = "paid"
            OVERDUE = "overdue"

            project = models.ForeignKey("projects.Project", on_delete=models.CASCADE)
            client = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE)

    amount = models.DecimalField(max_digits=10, decimal_places=2)
    due_date = models.DateField()
status = models.CharField(max_length=20, choices=Status.choices)
    ```

## Payment

    ```python
    class Payment(models.Model):
    invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE)
    paid_at = models.DateTimeField()
    method = models.CharField(max_length=100)
    ```

## Expense

    ```python
    class Expense(models.Model):
        project = models.ForeignKey("projects.Project", on_delete=models.CASCADE)
        raised_by = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE)

    amount = models.DecimalField(max_digits=10, decimal_places=2)
category = models.CharField(max_length=100)
    ```

## TeamPayment

    ```python
    class TeamPayment(models.Model):
    member = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE)
    period = models.DateField()
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    ```

    ---

## 4. kanban

### Responsibilities
    - Personal task management
    - Progress tracking
    - Drag-and-drop workflow

### Privacy Rules
    - Each board belongs to one user
    - Members cannot access others' boards
    - Admin sees only aggregated progress

### Main Models

## Board

    ```python
    class Board(models.Model):
        owner = models.ForeignKey(
                "accounts.CustomUser",
                on_delete=models.CASCADE
                )

        project = models.ForeignKey(
                "projects.Project",
                null=True,
                blank=True,
                on_delete=models.CASCADE
                )
        ```

## Column

        ```python
        class Column(models.Model):
    board = models.ForeignKey(Board, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    order = models.PositiveIntegerField()
    ```

## Card

    ```python
    class Card(models.Model):
        column = models.ForeignKey(Column, on_delete=models.CASCADE)

    title = models.CharField(max_length=255)
description = models.TextField(blank=True)

    due_date = models.DateField(null=True, blank=True)
order = models.PositiveIntegerField()
    ```

### Secure QuerySet Pattern

    ```python
    class BoardQuerySet(models.QuerySet):

        def for_user(self, user):
            return self.filter(owner=user)
            ```

            ---

## 5. issues

### Responsibilities
            - Bug tracking
            - Feature tracking
            - Task assignment
            - Internal discussion

### Main Models

## Issue

            ```python
            class Issue(models.Model):

                class Status(models.TextChoices):
                    OPEN = "open"
                    IN_PROGRESS = "in_progress"
                    RESOLVED = "resolved"
                    CLOSED = "closed"

                    class Priority(models.TextChoices):
                        LOW = "low"
                        MEDIUM = "medium"
                        HIGH = "high"

                        project = models.ForeignKey("projects.Project", on_delete=models.CASCADE)

                        reporter = models.ForeignKey(
                                "accounts.CustomUser",
                                on_delete=models.CASCADE,
                                related_name="reported_issues"
                                )

                        assignee = models.ForeignKey(
                                "accounts.CustomUser",
                                null=True,
                                blank=True,
                                on_delete=models.SET_NULL,
                                related_name="assigned_issues"
                                )

    status = models.CharField(max_length=20, choices=Status.choices)
priority = models.CharField(max_length=20, choices=Priority.choices)
    ```

## IssueComment

    ```python
    class IssueComment(models.Model):
        issue = models.ForeignKey(Issue, on_delete=models.CASCADE)
    author = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE)
        body = models.TextField()
        ```

        ---

## 6. tickets

### Responsibilities
        - Client support
        - Feature requests
        - Bug reporting

### Main Models

        ```python
        class Ticket(models.Model):

            class TicketType(models.TextChoices):
                BUG = "bug"
                FEATURE = "feature_request"
                SUPPORT = "support"

                class Status(models.TextChoices):
                    NEW = "new"
                    ACKNOWLEDGED = "acknowledged"
                    IN_PROGRESS = "in_progress"
                    DONE = "done"
                    REJECTED = "rejected"

                    creator = models.ForeignKey(
                            "accounts.CustomUser",
                            on_delete=models.CASCADE
                            )

                    project = models.ForeignKey(
                            "projects.Project",
                            null=True,
                            blank=True,
                            on_delete=models.CASCADE
                            )

    ticket_type = models.CharField(max_length=30, choices=TicketType.choices)
status = models.CharField(max_length=30, choices=Status.choices)
    ```

### Access Rules
    - Only admin and client can create tickets
    - Team members can only view assigned tickets
    - Tickets may be converted into issues

    ---

## 7. activity

### Responsibilities
    - Audit logging
    - Timeline tracking
    - Progress aggregation

### Main Models

    ```python
    class ActivityLog(models.Model):
        actor = models.ForeignKey(
                "accounts.CustomUser",
                on_delete=models.CASCADE
                )

        verb = models.CharField(max_length=255)

content_type = models.ForeignKey(
        ContentType,
        on_delete=models.CASCADE
        )

object_id = models.PositiveIntegerField()

timestamp = models.DateTimeField(auto_now_add=True)
    ```

### Rules
    - Members cannot view other members' activity logs
    - Admin dashboard uses aggregated activity metrics

    ---

# Frontend Stack

## HTMX
    Use HTMX for:
    - Kanban drag-and-drop persistence
    - Ticket status updates
    - Issue comments
    - Live search
    - Partial rendering
    - Inline updates

## Alpine.js
    Use Alpine.js for:
    - Modal state
    - Dropdowns
    - Tabs
    - Confirm dialogs
    - Inline edit toggles

## Suggested Drag-and-Drop Pattern

    - Use Sortable.js for drag UI
    - Trigger HTMX POST request on drag end
    - Persist new ordering server-side

    ---

# Permission Pattern

    Instead of Django object permissions, use reusable helper functions and view mixins.

## Example

    ```python
    class ProjectMemberRequired(LoginRequiredMixin):

        def dispatch(self, request, *args, **kwargs):

            project = get_object_or_404(
                    Project,
                    pk=kwargs["pk"]
                    )

            if not project.members.filter(
                    pk=request.user.pk
                    ).exists():
                raise PermissionDenied

                return super().dispatch(request, *args, **kwargs)
    ```

    ---

# Access Control Matrix

    | Module            | Admin          | Client               | Team Member         |
    |------------------|----------------|----------------------|---------------------|
    | Kanban Board     | Progress only  | No access            | Own board only      |
    | Issues           | Full           | View + comment       | Assigned only       |
    | Tickets/Features | Full           | Create + view own    | View assigned       |
    | Finance          | Full           | Own invoices         | Own payroll         |
    | Projects         | Full           | View own project     | Assigned project    |

    ---

# Suggested Folder Layout

    ```text
    core/
    ├── accounts
    ├── projects
    ├── notifications
    └── activity

    features/
    ├── kanban
    ├── issues
    └── tickets

    finance/
    ├── invoices
    ├── payments
    ├── expenses
    └── payroll

    templates/
    ├── base
    ├── components
    ├── partials
    └── pages
    ```

    ---

# Recommended Tech Stack

## Backend
    - Django
- Django REST Framework (optional API layer)
    - PostgreSQL
    - Redis
    - Celery

## Frontend
    - HTMX
    - Alpine.js
    - Tailwind CSS
    - django-tailwind-cli

## Infrastructure
    - Nginx
    - Gunicorn
    - Docker
    - GitHub Actions CI/CD

    ---

# Future Improvements

    - Real-time notifications with Django Channels
    - WebSocket activity feed
    - Time tracking
    - Project analytics dashboard
    - File attachments
    - Email automation
    - AI-assisted issue summaries
    - Multi-tenant architecture

    ---

# Final Notes

    This architecture keeps:
    - Apps modular
    - Permissions predictable
    - HTMX interactions clean
    - Kanban privacy secure
    - Finance isolated
    - Features scalable

    The structure is optimized for:
    - Long-term maintainability
    - Team collaboration
    - Incremental feature expansion
    - Clear domain separation