DjangoPlay — Integration Architecture
DjangoPlay uses integration boundaries to connect the application with identity services, reusable platform components, infrastructure services, and external providers.
On this page ▾
- Architecture
- Integration Flow
- Integration Categories
- GenericIssueTracker Integration
- GenericIssueTracker Integration Boundary
- Identity Integration
- GenericIssueTracker Authorization
- GenericIssueTracker Mutation Services
- GenericIssueTracker Query Services
- GenericIssueTracker UI
- GenericIssueTracker API
- GenericIssueTracker Events
- GenericIssueTracker Audit Boundary
- GenericIssueTracker Labels
- GenericIssueTracker and Helpdesk
- AuthX Integration
- Email Integration
- Cloudflare R2 Integration
- AI Provider Integration
- Integration Isolation
- Integration Responsibility
- Configuration Boundaries
- Failure Isolation
- Local Development
- Integration Boundaries
- Architectural Principles
- Architectural Principle
The integration architecture separates:
- Internal reusable Django integrations
- External identity and service providers
- AI provider integrations
- Storage and CDN integrations
- Email integrations
- Application-specific adapters and policies
The goal is to keep provider-specific and integration-specific behavior outside the core application workflows.
Architecture
flowchart TD
APP["DjangoPlay Application"]
subgraph INTERNAL["DjangoPlay Internal Integrations"]
ISSUE["GenericIssueTracker Integration<br/>paystream.integrations.issuetracker"]
ISSUE_ID["DjangoPlay Identity Resolver"]
ISSUE_POLICY["Visibility / RBAC Policy"]
ISSUE_SERVICE["Issue Query / Mutation Services"]
ISSUE_EVENTS["IssueTracker Signals<br/>Domain Events / Audit"]
ISSUE --> ISSUE_ID
ISSUE --> ISSUE_POLICY
ISSUE --> ISSUE_SERVICE
ISSUE --> ISSUE_EVENTS
ISSUE_ID --> APP
ISSUE_POLICY --> APP
ISSUE_SERVICE --> APP
ISSUE_EVENTS --> APP
end
subgraph EXTERNAL["External Integrations"]
AUTHX["AuthX<br/>Identity Service"]
EMAIL["SMTP / Email Provider"]
R2["Cloudflare R2<br/>Asset Storage / CDN"]
AI["AI Providers"]
XAI["xAI"]
OPENAI["OpenAI"]
OPENROUTER["OpenRouter"]
CUSTOM["Custom / Local<br/>Ollama / vLLM"]
AI --> XAI
AI --> OPENAI
AI --> OPENROUTER
AI --> CUSTOM
end
APP --> AUTHX
APP --> EMAIL
APP --> R2
APP --> AI
ISSUE_SERVICE --> AUTHX
ISSUE_EVENTS --> APP
classDef application fill:#e5f6f1,stroke:#159a7a,stroke-width:2px,color:#075d4b
classDef internal fill:#fff2d9,stroke:#d89b18,stroke-width:2px,color:#76520b
classDef external fill:#eeeeff,stroke:#5a55c9,stroke-width:2px,color:#403b91
classDef provider fill:#f5f3ed,stroke:#777777,stroke-width:1px,color:#444444
class APP application
class ISSUE,ISSUE_ID,ISSUE_POLICY,ISSUE_SERVICE,ISSUE_EVENTS internal
class AUTHX,EMAIL,R2,AI external
class XAI,OPENAI,OPENROUTER,CUSTOM provider
`Integration Flow
DJANGOPLAY
│
┌───────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Internal Identity / External
Integrations Application Services
│ │ │
│ ▼ ├── SMTP / Email
│ AuthX ├── Cloudflare R2
│ └── AI Providers
│
▼
GenericIssueTracker
│
┌─────┼─────────────┐
│ │ │
▼ ▼ ▼
Identity RBAC Services
Resolver / Policy / Queries
│ │ │
└─────┼─────────────┘
│
▼
GenericIssueTracker
Domain APIIntegration Categories
DjangoPlay integrations fall into two primary categories.
| Category | Examples | Responsibility |
|---|---|---|
| Internal / Reusable Integration | GenericIssueTracker | Integrates reusable Django platform capabilities into DjangoPlay |
| External Service Integration | AuthX | Identity and authentication services |
| External Service Integration | SMTP / Email Provider | Transactional email delivery |
| External Service Integration | Cloudflare R2 | Asset storage and CDN workflow |
| External Service Integration | AI Providers | LLM inference and model catalog services |
Internal integrations are still kept behind explicit adapter boundaries so that the host application does not become tightly coupled to reusable package internals.
GenericIssueTracker Integration
GenericIssueTracker is a reusable Django issue-tracking package integrated into DjangoPlay through the dedicated:
paystream.integrations.issuetrackerintegration layer.
The integration provides the DjangoPlay-specific behavior required to use the generic package without modifying the package itself.
DjangoPlay
│
▼
paystream.integrations.issuetracker
│
▼
GenericIssueTrackerGenericIssueTracker provides the reusable issue-tracking domain and API capabilities, while DjangoPlay provides application-specific integration behavior.
GenericIssueTracker Integration Boundary
The DjangoPlay integration layer contains several responsibilities.
GenericIssueTracker Integration
│
┌───────┼──────────────┬───────────────┐
│ │ │ │
▼ ▼ ▼ ▼
Identity Access Mutation Query
Resolver / RBAC Services Services
│ │ │ │
└───────┼──────────────┴───────────────┘
│
▼
GenericIssueTrackerThe integration therefore adapts DjangoPlay application concepts to the generic package rather than duplicating the package's domain logic.
Identity Integration
DjangoPlay provides a dedicated identity resolver:
users.services.issuetracker_identity_resolverThe resolver adapts DjangoPlay's authenticated user model to the identity contract expected by GenericIssueTracker.
Conceptually:
DjangoPlay User
│
▼
DjangoPlay IssueTracker Identity Resolver
│
▼
GenericIssueTracker Identity ContractThe identity contract includes information such as:
- User ID
- Authentication state
- Superuser state
- Role code
The integration remains read-only with respect to identity resolution.
GenericIssueTracker therefore does not need to understand DjangoPlay's internal user or employment-profile implementation.
GenericIssueTracker Authorization
DjangoPlay applies its own application-level authorization policies to the GenericIssueTracker integration.
The integration includes an explicit visibility service:
IssueVisibilityServiceThe service applies role-based visibility rules for internal issues.
Authenticated Identity
│
▼
IssueVisibilityService
│
├── Superuser override
├── Allowed role check
└── Public / reporter visibility
│
▼
Visible Issue QuerysetInternal issue access is controlled through the configured allowed roles rather than through implicit role hierarchy.
This keeps authorization policy in DjangoPlay instead of embedding DjangoPlay-specific policy into GenericIssueTracker.
GenericIssueTracker Mutation Services
DjangoPlay provides an integration-level mutation service:
IssueMutationServiceThe service coordinates operations such as:
- Issue creation
- Comment creation
- Attachment handling
- Identity resolution
- Anonymous reporting policy
- Visibility checks
- Validation
- Issue lifecycle operations
The service delegates domain operations to GenericIssueTracker rather than reimplementing the issue lifecycle.
DjangoPlay UI / API
│
▼
IssueMutationService
│
├── Identity resolution
├── DjangoPlay policy checks
├── Validation
│
▼
GenericIssueTracker
│
└── Domain operationGenericIssueTracker Query Services
DjangoPlay also provides integration-level query services.
IssueQueryService
│
├── Base queryset
├── Visibility filtering
├── Status filtering
├── Priority filtering
└── Deterministic ordering
│
▼
GenericIssueTracker IssueThe query service keeps DjangoPlay-specific presentation and filtering requirements outside the reusable package.
GenericIssueTracker UI
DjangoPlay provides its own server-rendered IssueTracker UI.
The integration exposes UI routes separately from the package's reusable domain/API functionality.
Browser
│
▼
DjangoPlay IssueTracker UI
│
▼
paystream.integrations.issuetracker.views.ui
│
▼
Integration Services
│
▼
GenericIssueTrackerThe UI includes functionality for:
- Issue listing
- Issue creation
- Issue detail
- Comments
- Attachments
- Status handling
- Authentication/session handling
The UI therefore remains a DjangoPlay concern.
GenericIssueTracker API
DjangoPlay exposes the GenericIssueTracker functionality through its own integration API boundary.
REST Client
│
▼
DjangoPlay IssueTracker API
│
▼
paystream.integrations.issuetracker.views.api.v1
│
▼
GenericIssueTrackerThe integration contains DjangoPlay-specific serializers and API views while reusing the generic package's domain and serializer capabilities where appropriate.
GenericIssueTracker Events
GenericIssueTracker emits domain signals such as:
issue_created
issue_updated
issue_deleted
issue_commented
issue_status_changedDjangoPlay subscribes to these events through:
paystream.integrations.issuetracker.signalsThe integration converts relevant IssueTracker activity into DjangoPlay internal domain events.
GenericIssueTracker
│
▼
IssueTracker Signal
│
▼
DjangoPlay Integration Signal Handler
│
▼
DjangoPlay Domain Event
│
▼
Audit / Observability SubscribersThe signal integration deliberately avoids coupling the GenericIssueTracker domain model directly to DjangoPlay's audit or event infrastructure.
GenericIssueTracker Audit Boundary
IssueTracker models are registered with DjangoPlay's audit tracking system.
The integration tracks objects such as:
genericissuetracker.Issue
genericissuetracker.IssueComment
genericissuetracker.IssueAttachmentThe integration therefore connects IssueTracker activity to DjangoPlay's existing audit infrastructure without placing audit persistence logic inside the reusable package.
GenericIssueTracker Labels
DjangoPlay maintains its own application-specific IssueTracker labels.
The integration provides:
IssueLabelBootstrapServicewhich ensures required labels exist during application startup.
Examples include:
bug-internal
bug-publicThe label definitions are maintained by the DjangoPlay integration rather than being hard-coded into GenericIssueTracker.
DjangoPlay Integration
│
▼
IssueLabelBootstrapService
│
▼
GenericIssueTracker LabelsGenericIssueTracker and Helpdesk
DjangoPlay also integrates existing Helpdesk functionality with GenericIssueTracker.
Migrated or synchronized Helpdesk records can reference corresponding GenericIssueTracker issues.
The architecture therefore allows the reusable IssueTracker domain to act as the common issue representation while legacy/application-specific Helpdesk workflows remain in DjangoPlay.
DjangoPlay Helpdesk
│
│ migration / synchronization
▼
GenericIssueTracker IssueSupport-ticket-synchronized issues can remain available for internal traceability without necessarily being presented as ordinary issues on the public IssueTracker board.
AuthX Integration
AuthX is DjangoPlay's external identity service.
DjangoPlay
│
▼
AuthX
│
└── Identity / AuthenticationAuthentication architecture is documented separately.
The integration boundary is responsible for communication with AuthX while DjangoPlay retains application-level authorization.
GenericIssueTracker uses DjangoPlay's identity resolver rather than directly implementing its own authentication integration.
AuthX
│
▼
DjangoPlay Authentication
│
▼
DjangoPlay User Context
│
▼
GenericIssueTracker Identity ResolverEmail Integration
DjangoPlay communicates with an SMTP or email provider for transactional email.
DjangoPlay
│
▼
SMTP / Email Provider
│
▼
RecipientEmail operations may originate from:
- Web requests
- Application services
- Celery background tasks
The provider remains external to DjangoPlay.
Cloudflare R2 Integration
Cloudflare R2 provides object storage for the frontend CDN workflow.
DjangoPlay / Frontend Packaging
│
▼
Cloudflare R2
│
▼
CDN DeliveryR2 is optional for ordinary local development when frontend assets are served locally.
The integration becomes active when the CDN asset workflow is enabled.
AI Provider Integration
DjangoPlay's aicore application uses a provider abstraction rather than
coupling application logic directly to one LLM provider.
DjangoPlay
│
▼
aicore
│
▼
Provider Registry
│
├── xAI
├── OpenAI
├── OpenRouter
└── Custom / Local
│
├── Ollama
└── vLLMThe provider registry allows the application to switch providers without changing the higher-level chat workflow.
Provider credentials remain server-side where the provider integration requires them.
BYOK flows are handled separately by aicore and are scoped according to its
security model.
Integration Isolation
DjangoPlay keeps integration-specific behavior outside the core application layers.
DjangoPlay Application
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Internal Identity External
Integrations Services Providers
│ │ │
▼ ▼ ├── SMTP
GenericIssueTracker AuthX ├── R2
└── AIThis allows each integration boundary to own:
- Provider-specific configuration
- Request/response adaptation
- Authentication credentials
- Integration-specific policy
- Error handling
- Mapping between external and internal representations
Integration Responsibility
| Integration | Type | DjangoPlay Responsibility | External / Reusable Responsibility |
|---|---|---|---|
| GenericIssueTracker | Reusable internal package | Identity adapter, RBAC, visibility, UI/API integration, services, events, labels | Issue domain, lifecycle, reusable API capabilities |
| AuthX | External service | Authentication integration and application context | Identity authority, credentials, JWT issuance |
| SMTP / Email | External service | Email composition and delivery orchestration | Message transport and delivery |
| Cloudflare R2 | External service | Asset packaging/upload workflow | Object storage |
| AI Providers | External services | Provider registry, chat orchestration, access controls | Model inference and provider APIs |
Configuration Boundaries
Integration credentials and settings remain associated with the integration that consumes them.
Examples include:
AuthX
├── AuthX service URL
├── Service credentials
└── JWT verification configuration
Email
└── SMTP credentials
Cloudflare R2
├── Endpoint
├── Access key
├── Secret key
└── Bucket configuration
AI
├── Provider configuration
├── API keys
└── Custom provider configurationGenericIssueTracker itself is primarily configured through DjangoPlay's
GENERIC_ISSUETRACKER_* settings and the integration's application-level
services and policies.
Failure Isolation
Integration boundaries should prevent provider-specific failures from unnecessarily propagating through unrelated application functionality.
For example:
AI Provider Failure
│
▼
aicore integration
X
│
└── Core authentication remains available
R2 Failure
│
▼
CDN asset workflow
X
│
└── Core Django application remains available
GenericIssueTracker Failure
│
▼
IssueTracker integration
X
│
└── Unrelated DjangoPlay applications remain isolatedThe exact failure behavior depends on the calling workflow and whether the operation is synchronous or asynchronous.
Local Development
Local development does not require every integration to be active.
A minimal runtime can use:
DjangoPlay
│
├── PostgreSQL
├── Redis
└── AuthXAdditional integrations can be enabled when required:
Optional
├── Google SSO
├── SMTP
├── Cloudflare R2
├── AI provider
└── CDN workflowGenericIssueTracker is part of the DjangoPlay application integration when the IssueTracker functionality is installed and enabled.
Integration Boundaries
The resulting architecture can be summarized as:
DJANGOPLAY
│
┌───────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Internal Identity External
Integrations Service Providers
│ │ │
▼ ▼ ┌───────┼────────┐
GenericIssueTracker AuthX │ │ │
│ SMTP R2 AI
┌──────┼──────┐ │
│ │ │ ┌─────┼─────┐
Identity RBAC Services xAI OpenAI Custom
Resolver Policy / Queries │
│
OpenRouterArchitectural Principles
The integration architecture follows these principles:
- Integrations have explicit boundaries.
- Reusable packages remain generic and do not contain DjangoPlay-specific business policy.
- DjangoPlay-specific adapters translate application concepts into reusable package contracts.
- GenericIssueTracker owns issue-domain behavior; DjangoPlay owns its integration policy and presentation.
- Identity resolution is adapted through a dedicated DjangoPlay resolver.
- Authorization and visibility remain DjangoPlay application concerns.
- IssueTracker domain events are adapted into DjangoPlay internal events without coupling the reusable package to DjangoPlay infrastructure.
- External provider credentials remain isolated to their respective integrations.
- AI provider implementations are accessed through a provider abstraction.
- External integrations should be replaceable without rewriting core application workflows.
- Optional integrations should not become mandatory dependencies for unrelated application functionality.
- Integration failures should remain isolated wherever the workflow permits.
Architectural Principle
DjangoPlay treats integrations as boundaries between the application and capabilities that are either reusable or externally provided.
DjangoPlay
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
Reusable Identity External
Packages Services Providers
│ │ │
▼ ▼ ▼
GenericIssueTracker AuthX SMTP / R2 / AIThe integration layer adapts these capabilities to DjangoPlay without allowing provider-specific implementation details or reusable-package assumptions to spread throughout the application.
This keeps DjangoPlay modular while allowing reusable platform components such as GenericIssueTracker to evolve independently.