djangoplay-web / Architecture / DjangoPlay — Architecture Style
DocsDjangoPlay WebArchitectureDjangoPlay — Architecture Style

DjangoPlay — Architecture Style

DjangoPlay is structured as a modular monolith built on Django and Django REST Framework.

14 min readApplies to v1.2.2
On this page ▾
  1. Views
  2. Serializers
  3. Services
  4. Models
  5. Policies
  6. Tasks
  7. Integrations
  8. Signals
  9. Application Scaling
  10. Worker Scaling
  11. Database Scaling
  12. Cache Scaling
  13. Integration Scaling

1. Overview

The application combines:

  • Domain-oriented Django apps
  • Layered application architecture
  • Service-oriented business logic
  • Centralized authorization
  • External identity through AuthX
  • Auditability
  • Asynchronous processing with Celery
  • Redis-backed infrastructure
  • Dedicated integration boundaries
  • Versioned REST APIs

The architecture is intentionally modular without introducing microservices prematurely.

The primary goal is to keep domain functionality isolated and maintainable while allowing infrastructure, integrations, and individual application modules to evolve independently.


2. Architecture Classification

Category Architecture Style
System Architecture Modular Monolith
Application Architecture Layered Architecture
Domain Structure Domain-Oriented Django Apps
Business Logic Service Layer
Data Access Django ORM / Query Services
Authorization Policy-Based Access Control
Identity External AuthX Identity Service
API Django REST Framework
API Evolution URL-Based API Versioning
Background Processing Celery
Broker / Cache Redis
Persistence PostgreSQL
External Services Dedicated Integration Boundaries
Auditability Centralized Audit Module
Deployment Nginx + Gunicorn + Celery
Static Assets Local Static Serving / Cloudflare R2 + CDN
Issue Tracking Generic Issue Tracker Integration

3. Modular Monolith

DjangoPlay uses a modular monolith rather than a collection of independent microservices.

Multiple domain modules run inside the same Django application and share the application's deployment and primary PostgreSQL database.

The current application contains domain and infrastructure modules such as:

text
webapp/

├── aicore
├── apidocs
├── audit
├── core
├── entities
├── finance
├── frontend
├── helpdesk
├── industries
├── locations
├── mailer
├── paystream
├── policyengine
├── teamcentral
├── users
│
└── integrations/
    └── issuetracker/
`

The exact set of applications may evolve as DjangoPlay develops.

The important architectural rule is that each application represents a meaningful responsibility or domain rather than being an arbitrary collection of unrelated functionality.


4. Domain-Oriented Application Structure

Each Django application owns a defined area of responsibility.

Examples include:

Application Responsibility
users User accounts, authentication flows, signup and verification
teamcentral Teams, organizational structure and related access context
policyengine Role-based authorization and policy evaluation
audit Platform-wide audit trail
entities Business/entity records
locations Geographic reference data
industries Industry and classification reference data
finance Financial domain functionality
helpdesk Support workflows and issue/report handling
mailer Transactional email functionality
aicore In-app AI assistant and provider orchestration
apidocs API documentation and developer-facing API support
frontend Templates, static assets and presentation-layer functionality
core Cross-cutting application infrastructure
paystream Project package, settings, security and integration wiring

The application boundaries are logical boundaries inside the monolith.

They are not necessarily separate deployable services.


5. Layered Application Architecture

DjangoPlay separates request handling, application workflows, domain state, and infrastructure concerns.

text
                    Incoming Request
                           │
                           ▼
                  Middleware / Context
                           │
                           ▼
                     URL Routing
                           │
              ┌────────────┴────────────┐
              ▼                         ▼
        Django Web Views            DRF APIs
              │                         │
              └────────────┬────────────┘
                           ▼
                    Service Layer
                           │
             ┌─────────────┼─────────────┐
             ▼             ▼             ▼
          Policies      Models        Tasks
             │             │             │
             │             ▼             ▼
             │        PostgreSQL       Redis
             │
             └─────────────┬─────────────┐
                           ▼             ▼
                         Audit      Integrations

The architecture intentionally keeps core business workflows out of the presentation layer.


6. Presentation Layer

The presentation layer is responsible for interacting with clients.

It includes:

  • Django web views
  • DRF API views and ViewSets
  • Templates
  • Serializers
  • Presentation-specific request/response handling

The presentation layer should:

  • Receive requests
  • Validate request structure
  • Resolve the appropriate service
  • Return responses
  • Handle presentation-specific concerns

It should not become the primary location for business workflows.

Typical flow:

text
HTTP Request
     │
     ▼
View / API View
     │
     ▼
Serializer
     │
     ▼
Service
     │
     ▼
Response

7. Service Layer

The service layer is the primary location for application and business workflows.

Services coordinate:

  • Business rules
  • Transactions
  • Domain workflows
  • Model operations
  • Authorization checks
  • External integrations
  • Background task dispatch
  • Notifications
  • Audit operations

Typical flow:

text
View / API
     │
     ▼
Service
     │
     ├── Policy
     ├── Model / Query
     ├── Audit
     ├── Celery Task
     └── Integration

Services provide a stable application boundary so that the same business operation can be reused by different entry points.

For example, a workflow should not need to be duplicated because it is invoked from both a Django web view and an API endpoint.


8. Domain and Data Layer

Django models represent persistent domain state and relationships.

The domain/data layer contains:

  • Django models
  • Relationships
  • Persistence-facing state
  • Model-level validation appropriate to the domain
  • Domain-specific state transitions where appropriate

Complex application workflows should remain in services rather than becoming embedded inside model methods.

Database access is primarily provided through the Django ORM.

Where queries become complex or reusable, query/selector services can isolate that logic from views and workflows.


9. Query and Selector Pattern

Complex or reusable data retrieval should be isolated from presentation code.

Typical responsibilities include:

  • Filtering
  • Search
  • Ordering
  • Related-object loading
  • Query optimization
  • Reusable domain queries

Conceptually:

text
Service
   │
   ▼
Query / Selector
   │
   ▼
Django ORM
   │
   ▼
PostgreSQL

This prevents large query expressions from becoming scattered throughout views and other application components.


10. Authorization Architecture

Authorization is treated as a cross-cutting concern rather than being implemented independently in every view.

DjangoPlay uses the policyengine application for centralized authorization logic.

Policies can evaluate application context such as:

  • User roles
  • Ownership
  • Organizational context
  • Allowed actions
  • Resource access
  • Role-based permissions

Typical flow:

text
Request
   │
   ▼
Authentication
   │
   ▼
Policy Evaluation
   │
   ├── Allowed ──► Application Service
   │
   └── Denied  ──► Access Denied

Authorization should be enforced at the appropriate application boundary rather than relying solely on presentation-layer checks.


11. Identity Architecture

DjangoPlay uses AuthX as its external identity service.

Identity responsibilities are deliberately separated from DjangoPlay's domain/application responsibilities.

AuthX provides the identity authority for authentication flows such as:

  • Login
  • Signup
  • Password reset
  • Identity verification
  • SSO

The architectural boundary is:

text
                 ┌──────────────────┐
                 │      AuthX       │
                 │ Identity Service │
                 └────────┬─────────┘
                          │
                     Identity / JWT
                          │
                          ▼
                 ┌──────────────────┐
                 │    DjangoPlay    │
                 │ Application      │
                 └──────────────────┘

AuthX is the JWT signing authority for the AuthX identity integration.

DjangoPlay verifies AuthX-issued identity tokens rather than owning the AuthX private signing key.

This separation protects the identity boundary and keeps authentication infrastructure independent from application-domain logic.


12. Audit Architecture

Auditability is a platform-level concern.

The audit application provides centralized audit logging for meaningful system actions and state changes.

Typical events include:

  • Authentication-related events
  • Administrative actions
  • Create operations
  • Update operations
  • Delete operations
  • State transitions
  • Important system operations

Conceptually:

text
Application Service
        │
        ▼
   Audit Service
        │
        ▼
     Audit Log
        │
        ▼
    PostgreSQL

Audit operations should remain attributable to the actor or system process responsible for the change.


13. Background Processing

DjangoPlay uses Celery for asynchronous and long-running work.

Redis provides the supporting broker/cache infrastructure.

Typical flow:

text
Application Service
        │
        ▼
   Celery Task
        │
        ▼
      Redis
        │
        ▼
  Celery Worker
        │
        ▼
External Service / Database / File Operation

Background processing is appropriate for operations such as:

  • Transactional email
  • External API calls
  • File processing
  • Long-running operations
  • Scheduled maintenance
  • Synchronization workflows

The request/response path should not unnecessarily perform long-running work that belongs in the background processing layer.


14. Integration Architecture

External systems are accessed through explicit integration boundaries.

The application should not scatter third-party API calls throughout domain views or models.

Conceptually:

text
DjangoPlay Service
        │
        ▼
Integration Boundary
        │
        ▼
External Service

This architecture allows external providers to be replaced or modified without restructuring the application's core domain workflows.

Current integration categories include:

  • AuthX Identity
  • Generic Issue Tracker
  • Email / SMTP providers
  • AI providers
  • Cloudflare R2
  • Other external APIs

15. Generic Issue Tracker Integration

DjangoPlay integrates with the reusable Generic Issue Tracker package rather than maintaining an isolated issue-tracking implementation inside the host application.

The integration is located under:

text
paystream/integrations/issuetracker/

The reusable package provides issue-management capabilities while DjangoPlay provides the host-specific integration, access control, and application workflows.

Conceptually:

text
DjangoPlay
    │
    ▼
Helpdesk / Application Workflows
    │
    ▼
DjangoPlay Issue Tracker Integration
    │
    ▼
Generic Issue Tracker
    │
    ├── Issues
    ├── Comments
    ├── Attachments
    ├── Labels
    └── Status History

This keeps the issue-tracking capability reusable while allowing DjangoPlay to apply its own application-level policies and workflows.

The helpdesk application acts as an important host-side integration point for bug reports, support tickets, and issue-tracker workflows.


16. Email Architecture

Email delivery is isolated from individual business modules through the mailer infrastructure.

Typical flow:

text
Application Service
        │
        ▼
      Mailer
        │
        ▼
   Celery Task
        │
        ▼
   SMTP / Provider

This prevents individual applications from implementing SMTP or provider communication independently.

Email configuration and provider credentials are maintained separately from business-domain logic.


17. AI Integration Architecture

The aicore application provides the in-app AI assistant and acts as the application boundary for AI provider communication.

The provider implementation is intentionally replaceable.

Conceptually:

text
Authenticated User
        │
        ▼
     aicore
        │
        ▼
 Provider Registry
        │
   ┌────┼───────────────┐
   ▼    ▼               ▼
  xAI  OpenAI      Custom Providers
                         │
                  Ollama / vLLM / ...

AI provider credentials and provider-specific configuration remain outside domain application logic.

The architecture supports changing providers without changing the rest of the application workflow.

Detailed AI architecture belongs in the dedicated aicore documentation rather than this system architecture document.


18. API Architecture

DjangoPlay exposes REST APIs through Django REST Framework.

API endpoints are organized using explicit URL namespaces.

Typical structure:

text
/api/v1/
    │
    ├── users/
    ├── issues/
    ├── ...
    │
    └── ...

API endpoints follow the same application architecture as web requests:

text
DRF View / ViewSet
        │
        ▼
Serializer
        │
        ▼
Service
        │
        ▼
Domain / Integration

API presentation code should not duplicate business workflows that already exist in the service layer.


19. API Versioning

DjangoPlay uses URL-based API versioning to allow controlled API evolution.

For example:

text
/api/v1/
/api/v2/

A version may provide its own:

  • URL configuration
  • Views
  • Serializers
  • Version-specific presentation behavior

The underlying business services can remain shared where the business semantics are unchanged.

Conceptually:

text
                 Client
                   │
          ┌────────┴────────┐
          ▼                 ▼
      /api/v1/          /api/v2/
          │                 │
       v1 Views          v2 Views
          │                 │
       v1 Serializers    v2 Serializers
          │                 │
          └────────┬────────┘
                   ▼
               Services
                   │
                   ▼
              Domain Data

This separates API compatibility concerns from the core application domain.


20. Cross-Cutting Infrastructure

Several concerns span multiple Django applications.

These are treated as platform infrastructure rather than duplicated inside individual domains.

Examples include:

Concern Primary Component
Identity AuthX integration / users
Authorization policyengine
Auditability audit
Email mailer
Async processing Celery
Cache / broker Redis
Application infrastructure core / paystream
API documentation apidocs
External service boundaries integrations

Cross-cutting infrastructure should remain independent of individual domain workflows wherever practical.


21. Infrastructure Architecture

The current runtime is designed as a conventional Django production stack.

text
                         Client
                           │
                           ▼
                         Nginx
                           │
                           ▼
                       Gunicorn
                           │
                           ▼
                    Django Application
                           │
             ┌─────────────┼─────────────┐
             ▼             ▼             ▼
        PostgreSQL       Redis         Celery
             │             │             │
             │             │             ▼
             │             │          Background
             │             │           Workers
             │             │
             └─────────────┴─────────────┘

External services connect through explicit application boundaries.

Examples include:

text
DjangoPlay ──► AuthX
DjangoPlay ──► SMTP / Email Provider
DjangoPlay ──► AI Providers
DjangoPlay ──► Cloudflare R2
DjangoPlay ──► Generic Issue Tracker
DjangoPlay ──► External APIs

22. Static Assets and CDN

Frontend assets are built by the DjangoPlay frontend packaging workflow.

Depending on the environment, assets may be served locally or through the Cloudflare R2/CDN path.

Conceptually:

text
Frontend Source
      │
      ▼
Asset Build / Packaging
      │
      ├──────────────► Local Static Serving
      │
      └──────────────► Cloudflare R2
                              │
                              ▼
                             CDN

The CDN path is an infrastructure concern and does not change the Django application architecture.


23. Dependency Direction

DjangoPlay follows a general dependency direction:

text
Presentation
     │
     ▼
Application Services
     │
     ├──────► Policies
     │
     ├──────► Domain Models / Queries
     │
     ├──────► Audit
     │
     ├──────► Tasks
     │
     └──────► Integrations

The preferred direction is from application entry points toward reusable application/domain components.

Domain modules should avoid unnecessary dependencies on presentation components.

For cross-domain communication, application services and explicit integration boundaries are preferred over direct coupling wherever practical.


24. Events and Signals

Django signals are used for event-oriented behavior where appropriate.

Signals are useful for:

  • Audit events
  • Related state updates
  • Notifications
  • Event propagation
  • Background task triggering

Signals should remain lightweight.

Heavy workflows should be delegated to services or background tasks.

Preferred pattern:

text
Signal
   │
   ▼
Service / Task
   │
   ▼
Business Operation

Rather than:

text
Signal
   │
   └── Large Business Workflow

This keeps event handling predictable and testable.


25. Application Boundary Rules

The following architectural rules apply across DjangoPlay.

Views

Views should handle HTTP concerns and delegate application behavior.

Serializers

Serializers should handle request/response representation and validation, not become the primary business-logic layer.

Services

Services own application workflows and business operations.

Models

Models represent domain state and persistence relationships.

Policies

Authorization decisions belong to the policy layer.

Tasks

Long-running or asynchronous work belongs in Celery tasks.

Integrations

External-system communication belongs behind integration boundaries.

Signals

Signals should remain lightweight and delegate substantial work.


26. Architecture Principles

DjangoPlay follows these core principles:

Principle Meaning
Modular Monolith Keep domains modular without premature service decomposition
Domain Ownership Each application owns a meaningful responsibility
Service First Business workflows live in services
Thin Presentation Views and serializers remain focused on transport concerns
Centralized Authorization Access decisions use shared policy mechanisms
Protected Identity Boundary AuthX remains the external identity authority
Auditability Important state changes remain attributable and observable
Explicit Integrations External systems are isolated behind integration boundaries
Async by Design Long-running work is delegated to Celery
Reusable Infrastructure Shared concerns are implemented once where practical
API Stability API evolution uses explicit versioning
Separation of Concerns Presentation, application, domain and infrastructure responsibilities remain distinct
Replaceable Dependencies External providers should not dictate domain architecture

27. Why Modular Monolith Instead of Microservices?

DjangoPlay intentionally does not split every domain into a separate service.

A modular monolith provides:

  • Clear domain boundaries
  • One deployment unit
  • Simpler local development
  • Simpler transactions
  • Lower operational overhead
  • Easier debugging
  • Shared infrastructure
  • Reusable application services

The architecture nevertheless keeps boundaries explicit enough that a future domain can be extracted into a separate service if there is a genuine operational or scaling reason.

The goal is therefore:

text
Strong internal boundaries
          +
Simple deployment
          +
Optional future extraction

rather than introducing distributed-system complexity prematurely.


28. Evolution and Scalability

The architecture supports scaling in several dimensions.

Application Scaling

The Django application can be scaled vertically or horizontally behind a load balancer.

Worker Scaling

Celery workers can be scaled independently from web processes.

Database Scaling

PostgreSQL can be optimized or scaled independently as application demand increases.

Cache Scaling

Redis can be expanded or separated according to workload requirements.

Integration Scaling

External integrations remain isolated so that individual providers can be changed or scaled without restructuring domain applications.

The current architecture therefore provides a path from a single-server deployment toward a larger multi-instance deployment without requiring an immediate architectural rewrite.


29. Architecture Summary

DjangoPlay is a modular Django monolith with layered application design.

Its architectural structure can be summarized as:

text
                         DJANGOPLAY
                              │
                    ┌─────────┴─────────┐
                    │                   │
              Presentation         REST APIs
                    │                   │
                    └─────────┬─────────┘
                              ▼
                       Service Layer
                              │
             ┌────────────────┼────────────────┐
             ▼                ▼                ▼
         Policies         Domain Apps      Integrations
             │                │                │
             │                ▼                ▼
             │           PostgreSQL       External Services
             │
             ├──────────────► Audit
             │
             └──────────────► Celery
                                  │
                                  ▼
                                Redis

The resulting architecture keeps DjangoPlay deployable as a single application while maintaining explicit boundaries between:

  • Identity
  • Authorization
  • Domain applications
  • Business workflows
  • Persistence
  • Auditability
  • Background processing
  • External integrations
  • Infrastructure

This provides a practical foundation for continued development while preserving a clear path for future scaling and domain extraction.