---
since: 1.2.1
---
# DjangoPlay — Integration Architecture
DjangoPlay uses integration boundaries to connect the application with
identity services, reusable platform components, infrastructure services, and
external providers.
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
```mermaid
flowchart TD
APP["DjangoPlay Application"]
subgraph INTERNAL["DjangoPlay Internal Integrations"]
ISSUE["GenericIssueTracker Integration
paystream.integrations.issuetracker"]
ISSUE_ID["DjangoPlay Identity Resolver"]
ISSUE_POLICY["Visibility / RBAC Policy"]
ISSUE_SERVICE["Issue Query / Mutation Services"]
ISSUE_EVENTS["IssueTracker Signals
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
Identity Service"]
EMAIL["SMTP / Email Provider"]
R2["Cloudflare R2
Asset Storage / CDN"]
AI["AI Providers"]
XAI["xAI"]
OPENAI["OpenAI"]
OPENROUTER["OpenRouter"]
CUSTOM["Custom / Local
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
```text
DJANGOPLAY
│
┌───────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Internal Identity / External
Integrations Application Services
│ │ │
│ ▼ ├── SMTP / Email
│ AuthX ├── Cloudflare R2
│ └── AI Providers
│
▼
GenericIssueTracker
│
┌─────┼─────────────┐
│ │ │
▼ ▼ ▼
Identity RBAC Services
Resolver / Policy / Queries
│ │ │
└─────┼─────────────┘
│
▼
GenericIssueTracker
Domain API
```
## Integration 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:
```text
paystream.integrations.issuetracker
```
integration layer.
The integration provides the DjangoPlay-specific behavior required to use the
generic package without modifying the package itself.
```text
DjangoPlay
│
▼
paystream.integrations.issuetracker
│
▼
GenericIssueTracker
```
GenericIssueTracker 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.
```text
GenericIssueTracker Integration
│
┌───────┼──────────────┬───────────────┐
│ │ │ │
▼ ▼ ▼ ▼
Identity Access Mutation Query
Resolver / RBAC Services Services
│ │ │ │
└───────┼──────────────┴───────────────┘
│
▼
GenericIssueTracker
```
The 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:
```text
users.services.issuetracker_identity_resolver
```
The resolver adapts DjangoPlay's authenticated user model to the identity
contract expected by GenericIssueTracker.
Conceptually:
```text
DjangoPlay User
│
▼
DjangoPlay IssueTracker Identity Resolver
│
▼
GenericIssueTracker Identity Contract
```
The identity contract includes information such as:
* User ID
* Email
* 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:
```text
IssueVisibilityService
```
The service applies role-based visibility rules for internal issues.
```text
Authenticated Identity
│
▼
IssueVisibilityService
│
├── Superuser override
├── Allowed role check
└── Public / reporter visibility
│
▼
Visible Issue Queryset
```
Internal 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:
```text
IssueMutationService
```
The 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.
```text
DjangoPlay UI / API
│
▼
IssueMutationService
│
├── Identity resolution
├── DjangoPlay policy checks
├── Validation
│
▼
GenericIssueTracker
│
└── Domain operation
```
## GenericIssueTracker Query Services
DjangoPlay also provides integration-level query services.
```text
IssueQueryService
│
├── Base queryset
├── Visibility filtering
├── Status filtering
├── Priority filtering
└── Deterministic ordering
│
▼
GenericIssueTracker Issue
```
The 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.
```text
Browser
│
▼
DjangoPlay IssueTracker UI
│
▼
paystream.integrations.issuetracker.views.ui
│
▼
Integration Services
│
▼
GenericIssueTracker
```
The 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.
```text
REST Client
│
▼
DjangoPlay IssueTracker API
│
▼
paystream.integrations.issuetracker.views.api.v1
│
▼
GenericIssueTracker
```
The 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:
```text
issue_created
issue_updated
issue_deleted
issue_commented
issue_status_changed
```
DjangoPlay subscribes to these events through:
```text
paystream.integrations.issuetracker.signals
```
The integration converts relevant IssueTracker activity into DjangoPlay
internal domain events.
```text
GenericIssueTracker
│
▼
IssueTracker Signal
│
▼
DjangoPlay Integration Signal Handler
│
▼
DjangoPlay Domain Event
│
▼
Audit / Observability Subscribers
```
The 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:
```text
genericissuetracker.Issue
genericissuetracker.IssueComment
genericissuetracker.IssueAttachment
```
The 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:
```text
IssueLabelBootstrapService
```
which ensures required labels exist during application startup.
Examples include:
```text
bug-internal
bug-public
```
The label definitions are maintained by the DjangoPlay integration rather than
being hard-coded into GenericIssueTracker.
```text
DjangoPlay Integration
│
▼
IssueLabelBootstrapService
│
▼
GenericIssueTracker Labels
```
## GenericIssueTracker 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.
```text
DjangoPlay Helpdesk
│
│ migration / synchronization
▼
GenericIssueTracker Issue
```
Support-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.
```text
DjangoPlay
│
▼
AuthX
│
└── Identity / Authentication
```
Authentication 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.
```text
AuthX
│
▼
DjangoPlay Authentication
│
▼
DjangoPlay User Context
│
▼
GenericIssueTracker Identity Resolver
```
## Email Integration
DjangoPlay communicates with an SMTP or email provider for transactional email.
```text
DjangoPlay
│
▼
SMTP / Email Provider
│
▼
Recipient
```
Email 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.
```text
DjangoPlay / Frontend Packaging
│
▼
Cloudflare R2
│
▼
CDN Delivery
```
R2 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.
```text
DjangoPlay
│
▼
aicore
│
▼
Provider Registry
│
├── xAI
├── OpenAI
├── OpenRouter
└── Custom / Local
│
├── Ollama
└── vLLM
```
The 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.
```text
DjangoPlay Application
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Internal Identity External
Integrations Services Providers
│ │ │
▼ ▼ ├── SMTP
GenericIssueTracker AuthX ├── R2
└── AI
```
This 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:
```text
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 configuration
```
GenericIssueTracker 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:
```text
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 isolated
```
The 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:
```text
DjangoPlay
│
├── PostgreSQL
├── Redis
└── AuthX
```
Additional integrations can be enabled when required:
```text
Optional
├── Google SSO
├── SMTP
├── Cloudflare R2
├── AI provider
└── CDN workflow
```
GenericIssueTracker is part of the DjangoPlay application integration when the
IssueTracker functionality is installed and enabled.
## Integration Boundaries
The resulting architecture can be summarized as:
```text
DJANGOPLAY
│
┌───────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Internal Identity External
Integrations Service Providers
│ │ │
▼ ▼ ┌───────┼────────┐
GenericIssueTracker AuthX │ │ │
│ SMTP R2 AI
┌──────┼──────┐ │
│ │ │ ┌─────┼─────┐
Identity RBAC Services xAI OpenAI Custom
Resolver Policy / Queries │
│
OpenRouter
```
## Architectural Principles
The integration architecture follows these principles:
1. **Integrations have explicit boundaries.**
2. **Reusable packages remain generic and do not contain DjangoPlay-specific
business policy.**
3. **DjangoPlay-specific adapters translate application concepts into reusable
package contracts.**
4. **GenericIssueTracker owns issue-domain behavior; DjangoPlay owns its
integration policy and presentation.**
5. **Identity resolution is adapted through a dedicated DjangoPlay resolver.**
6. **Authorization and visibility remain DjangoPlay application concerns.**
7. **IssueTracker domain events are adapted into DjangoPlay internal events
without coupling the reusable package to DjangoPlay infrastructure.**
8. **External provider credentials remain isolated to their respective
integrations.**
9. **AI provider implementations are accessed through a provider abstraction.**
10. **External integrations should be replaceable without rewriting core
application workflows.**
11. **Optional integrations should not become mandatory dependencies for
unrelated application functionality.**
12. **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.
```text
DjangoPlay
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
Reusable Identity External
Packages Services Providers
│ │ │
▼ ▼ ▼
GenericIssueTracker AuthX SMTP / R2 / AI
```
The 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.