Architecture Module Structure - onouyek/MailApe GitHub Wiki

Module Structure

Code organization and dependencies in MailApe.

Project Structure

MailApe/
├── django/                 # Main Django application
│   ├── config/            # Project configuration
│   ├── mailinglist/       # Core mailing list functionality
│   ├── user/              # User management
│   ├── templates/         # Shared templates
│   └── manage.py          # Django management script
├── cloudformation/        # AWS infrastructure templates
├── apache/               # Web server configuration
├── scripts/              # Setup and deployment scripts
├── packer/               # Machine image configuration
├── ubuntu/               # System configuration files
└── requirements.*.txt    # Python dependencies

Django Application Structure

config/ - Project Configuration

config/
├── __init__.py
├── celery.py              # Celery configuration
├── common_settings.py     # Shared settings
├── development_settings.py # Development environment
├── production_settings.py  # Production environment
├── urls.py               # Main URL routing
└── wsgi.py               # WSGI application

Purpose: Central configuration and project-wide settings.

Source: config/

mailinglist/ - Core Application

mailinglist/
├── __init__.py
├── admin.py              # Django admin configuration
├── apps.py               # App configuration
├── emails.py             # Email sending logic
├── factories.py          # Test data factories
├── forms.py              # Django forms
├── migrations/           # Database migrations
├── mixins.py             # Reusable view mixins
├── models.py             # Data models
├── permissions.py        # API permissions
├── serializers.py        # API serializers
├── tasks.py              # Celery tasks
├── templates/            # App-specific templates
├── tests.py              # Test cases
├── urls.py               # URL routing
└── views.py              # View logic

Purpose: Core mailing list functionality including models, views, and background tasks.

Source: mailinglist/

user/ - User Management

user/
├── __init__.py
├── admin.py              # User admin configuration
├── apps.py               # App configuration
├── migrations/           # Database migrations
├── models.py             # User models (if extending)
├── templates/            # User-related templates
├── tests.py              # User tests
├── urls.py               # User URL routing
└── views.py              # Authentication views

Purpose: User authentication, registration, and profile management.

Source: user/

Module Dependencies

graph TD
    Config[config] --> ML[mailinglist]
    Config --> User[user]
    Config --> Django[Django Framework]
    
    ML --> Models[Django Models]
    ML --> DRF[Django REST Framework]
    ML --> Celery[Celery Tasks]
    ML --> Templates[Django Templates]
    
    User --> Auth[Django Auth]
    User --> Forms[Django Forms]
    
    Celery --> Redis[Redis]
    Models --> PostgreSQL[(PostgreSQL)]

Key Module Interactions

mailinglist.models → mailinglist.tasks

Models trigger Celery tasks on save:

def save(self, ...):
    is_new = self._state.adding
    super().save(...)
    if is_new:
        tasks.send_confirmation_email_to_subscriber.delay(self.id)

Source: models.py#L57-61

mailinglist.views → mailinglist.mixins

Views use mixins for authorization:

class MailingListDetailView(LoginRequiredMixin, UserCanUseMailingList, DetailView):
    model = MailingList

Source: views.py#L41-42

mailinglist.tasks → mailinglist.emails

Tasks delegate to email functions:

@shared_task
def send_confirmation_email_to_subscriber(subscriber_id):
    subscriber = Subscriber.objects.get(id=subscriber_id)
    emails.send_confirmation_email(subscriber)

Source: tasks.py#L6-11

Configuration Modules

Settings Hierarchy

graph TD
    Common[common_settings.py] --> Dev[development_settings.py]
    Common --> Prod[production_settings.py]
    
    Common --> Base["Base Django Settings"]
    Dev --> DevDB["SQLite/PostgreSQL (local)"]
    Prod --> ProdDB["AWS RDS PostgreSQL"]

URL Configuration

# config/urls.py
urlpatterns = [
    path("admin/", admin.site.urls),
    path("user/", include(user.urls, namespace="user")),
    path("mailinglist/", include(mailinglist.urls, namespace="mailinglist")),
]

Source: urls.py#L22-26

Infrastructure Modules

CloudFormation Templates

  • infrastructure.yaml: Core AWS resources (RDS, SQS, Security Groups)
  • web_worker.yaml: EC2 instances and auto-scaling

Source: cloudformation/

Deployment Scripts

  • install_all_packages.sh: System package installation
  • configure_apache.sh: Web server setup
  • configure_celery.sh: Task queue configuration

Source: scripts/

Testing Organization

Test Structure

mailinglist/
├── tests.py              # Unit tests
├── factories.py          # Test data generation
└── migrations/           # Database schema tests

Test Dependencies

  • factory_boy: Model factories for test data
  • Django TestCase: Built-in testing framework
  • coverage: Code coverage analysis

Source: requirements.common.txt#L8

Third-Party Integration

Django Extensions

  • django-crispy-forms: Form rendering
  • django-markdownify: Markdown processing
  • django-celery-results: Task result storage

External Services

  • PostgreSQL: Data persistence
  • Redis: Task queue broker
  • AWS Services: Production infrastructure

Import Patterns

Lazy Imports in Tasks

Tasks use lazy imports to avoid circular dependencies:

@shared_task
def send_confirmation_email_to_subscriber(subscriber_id):
    from mailinglist.models import Subscriber  # Lazy import
    subscriber = Subscriber.objects.get(id=subscriber_id)

Source: tasks.py#L8-10

Namespace Organization

Apps use namespace routing for URL organization:

path("mailinglist/", include(mailinglist.urls, namespace="mailinglist"))

This creates URLs like /mailinglist/create/ with names like mailinglist:create.

Next Steps