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 installationconfigure_apache.sh
: Web server setupconfigure_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
- Data Flow - How data moves through modules
- Development Guides - Working with the codebase
- Testing Strategy - Testing approach and organization