A reusable internal platform I architected to bring shared lifecycle, validation, integration and interaction patterns to IT operations across five business domains, reflecting a data-engineering-rooted, platform-first approach to software design.

Contents

Introduction

This platform brings a shared lifecycle, validation, integration and interaction model to IT operations across five business domains: DNS, firewall, folder permissions, procurement, and employee onboarding. It replaces what were five disconnected ad-hoc forms and email threads with one architecture that every domain plugs into: one lifecycle model, one validation approach, one integration layer to an external service-management system, one interaction pattern. What makes it different is the perspective behind it: a request is treated as structured, traceable business knowledge with a lifecycle and a history, not a page with a submit button, a view shaped by a background in data engineering before moving into DevOps and platform engineering. I designed the platform architecture and have built the majority of its implementation.

Business Challenge

Before this platform existed, IT operations ran as five unrelated processes, DNS, firewall, folder permissions, procurement, onboarding, each its own ad-hoc form or email thread: individually solvable, but symptomatic of a deeper architectural gap.

  • No shared entity or lifecycle model, so "status" and "history" meant something different in every domain.
  • No traceability into the external service-management system: a request's real-world outcome depended on someone remembering to check a separate tool.
  • Validation and duplicate-detection logic reimplemented per domain instead of shared.
  • Real dependencies between domains left to manual coordination: a server request implying DNS and firewall setup, an onboarding implying hardware and software, with no structural link between them.

The underlying problem wasn't that any one process was broken; it was the absence of a common platform for all of them to sit on.

My Role

Business & Domain Analysis. I translate operational IT processes, DNS management, network access, procurement, employee onboarding, into structured, testable domain models, starting from what the business needs to track before any code is written.

Platform & Architecture. I designed the pattern this platform reuses across every domain: persistent entities with explicit lifecycles, a shared audit trail, a shared service-management integration, and a clear boundary between platform-owned and externally-synced data (see Architecture, below). This foundation, and how it evolves as new domains are added, is my responsibility.

Software Engineering. I build the Django application logic, forms, services and integrations across all domains, and maintain the shared components, validation, normalization, duplicate-detection and document generation that every domain depends on, backed by an extensive automated test suite, including the entity-centric interactions under User Experience. Frontend work is part of this, secondary to the domain and backend architecture.

DevOps & Operations. Beyond development, I operate this platform: containerized builds across development, test and production, environment and configuration management, CI/CD tooling, and controlled rollout of integrations and authentication capabilities. I also contributed to the authorization model and its ongoing evolution.

Architecture

The platform is built on one recurring idea: model the business concept, not the form. Every request domain, DNS, firewall, folder permissions, procurement, employee lifecycle, is a variation on the same underlying pattern rather than a bespoke screen.

  • Persistent entities with explicit lifecycles. A request is a first-class object moving through defined states (draft, submitted, updated, resolved), not just a row rendered by a form, which is what makes it auditable, reportable and safe to automate around later.

  • Pages as projections, forms as mutations. Views read from the entity; only a dedicated service layer writes to it, keeping business logic out of templates and routing every mutation through the same validation and audit mechanism.

  • A versioned audit trail as a first-class concept. Every domain stores a full version history with a human-readable diff of each edit: if you can't reconstruct why a state changed, the lifecycle model is incomplete.

  • Approval as a lifecycle of its own. A business request, its approval and its eventual fulfilment are related, but they are not the same lifecycle. For requests requiring authorization, the platform opens a dedicated approval case against a specific request version. Approval proceeds through explicit, sequential stages whose responsible actors are resolved from domain policy before a decision is made. Only after the approval lifecycle reaches its final decision does the consuming domain continue into fulfilment. This keeps approval reusable across domains without turning the platform into a generic workflow engine.

Explicit stages, assignments and immutable decisions. Each approval stage records who is authorized to decide before the decision occurs. A completed decision becomes part of the audit history rather than a mutable status flag. Where more than one actor is eligible for a stage, the domain policy determines the permitted assignment while the approval lifecycle records who actually made the decision and what happened next.

  • A hard boundary between owned and externally-synced data, feeding one normalized view. Platform data and data synchronized from an external service-management system live in separate schemas, a data-engineering habit as much as a Django one: source-of-truth and reconciled data should never share a table.

    Internal request entity → external ticket → status and lifecycle events → normalized timeline on the detail page
    

    This is what lets the detail page present external progress as one coherent picture rather than a raw feed; its user-facing form is the service-management timeline (see User Experience).

  • Reusable services over duplicated logic. Duplicate-request detection, normalization and PDF generation are each implemented once and consumed by every domain: more upfront design per service, but improving one improves every domain at once.

  • Explicit relationships instead of hidden coordination. Where one domain's request implies work in another domain, that dependency is modelled directly rather than left to someone creating a second request manually. Infrastructure provisioning, for example, can imply related network changes, while employee onboarding can imply equipment or software provisioning. The long-term direction is a fuller employee-lifecycle model in which related operational resources can be traced back to the business event that created the need for them.

  • Lifecycle transitions triggered by actors outside the platform. An assigned approver does not necessarily need to become a permanent platform user merely to make one decision. The platform can expose an assigned decision through a secure, scoped interaction channel while still routing the action through the same approval service, authorization rules, transaction boundary and audit history. The interaction mechanism is therefore only a way to deliver the decision; the approval stage and its assignment remain the source of truth.

Individually, several of these choices cost more than "just build the form." The bet is that platform thinking, one lifecycle model, one validation layer, one integration point, compounds: each new domain gets cheaper to add, and each shared-service improvement pays off everywhere at once.

User Experience

The platform is organized around dedicated workspaces per business entity, not a collection of forms: list pages track open requests, detail pages hold everything known about an entity, forms only create or modify it, and available actions depend on the entity's lifecycle state.

Detail Page

The detail page is the operational workspace for an entity, not a rendering of database fields. Depending on lifecycle state, a user can edit, delete or copy it, review its version history, download a PDF, and follow links to related entities it produced or depends on. These actions belong to the entity: what a user can do there reflects what it currently allows.

History

Every entity carries a complete version history as part of its detail page, not an administrative log tucked away separately: a user can always answer what changed, who changed it, when, and why, letting a user or auditor reconstruct a decision without asking someone to remember it.

Service-Management Timeline

The detail page also carries a second kind of history: the service-management timeline. Version history explains how the platform's own record changed; the timeline explains how the request progressed after it entered an external operational system, presenting status changes and relevant communication as one chronological narrative.

Before this existed, understanding where a request stood meant reconstructing information across the original request, emails, ticket updates and direct communication. The timeline collapses that onto one page. Showing this reliably is primarily an integration problem rather than a UI problem: it requires a stable relationship between the internal entity and the external record, a normalized status vocabulary, structurally separated source data, and graceful degradation when the external system is unavailable.

Delegated Approval

Two-Stage Approval

For requests that require authorization, submission does not immediately mean fulfilment. The platform creates an approval lifecycle tied to the submitted request version. Decisions proceed sequentially through two explicitly assigned stages, with responsibility resolved according to the policy of the consuming domain. Downstream processing only begins after the required approval path has completed.

The framework is shared rather than reimplemented inside each module. Individual business domains provide the request being approved and the policy needed to resolve responsible actors. The approval capability handles stages, assignments, decisions, auditability and notifications. This allows different business domains to retain their own lifecycles while sharing the same approval mechanics.

Delegated Decision Channel

Approvers do not necessarily need a permanent platform account. An assigned actor can receive a secure, scoped decision link and make the required decision without becoming a regular platform user. The link does not bypass the approval model: it authorizes only the assigned interaction and feeds the result through the same service and audit trail as an authenticated platform action.

approval = domain capability
delegated link = interaction mechanism

That should not be conflated.

Copy

Users frequently need to submit a request that differs only slightly from one already submitted, the same firewall rule for a new environment, the same equipment set for a new hire. Rebuilding that from a blank form is repetitive and error-prone; starting from an existing, valid entity and adjusting only what's different reduces both.

PDF

Every domain can render its entity as a PDF, a portable document archivable, emailable, or reviewable outside the platform: one shared rendering service used by every domain, not a one-off feature.

Engineering Principles

This project reflects a small set of principles I apply broadly, not only here:

  • Model business concepts, not forms. A form is an interface; the entity behind it is what's worth designing.

  • Persistent entities over temporary requests. If something matters to the business, it should have an identity and a history, not just a submission timestamp.

  • Workflows over page logic. Business rules belong in services that encode a lifecycle, not scattered across views and templates.

  • Separate business, approval and fulfilment lifecycles. A request being submitted, a decision being authorized and the work being carried out are different business facts. Modelling them separately prevents approval state, external-system state and request state from collapsing into one ambiguous status field.

  • Abstract the stable capability, not every workflow. The reusable component is approval, not a generic BPM engine. Domain-specific business rules and downstream fulfilment remain with their own modules.

  • Reusable services over duplicated code. The same validation, normalization or integration logic should exist exactly once, regardless of how many domains use it.

  • Explicit relationships over hidden dependencies. If one business process depends on another, that dependency should be code, not institutional memory.

  • Platform thinking over isolated features. The right question isn't "how do I build this form," it's "what does this form have in common with the last four, and how do I build that once."

Together, these principles are what let one architecture carry five business domains: a data-engineering perspective on application design, fragmented processes turned into one coherent model, and interaction design, the detail page, history, timeline, copy and PDF, following directly from that model rather than styled on top of it.

Selected Capabilities

  • Unified entity workspace: each detail page combines current data, lifecycle status, related entities, actions, version history, a service-management timeline and PDF export in one place.

  • Structured lifecycle and audit-trail management across DNS, firewall, folder-permission, procurement and employee-lifecycle requests, with full change history, not just current state.

  • Workflow-driven request processing spanning five business domains from a single architecture.

  • Reusable domain components: shared validation, duplicate-detection, service-management integration and document-generation services used across all request types.

  • Cross-domain entity relationships: requests can explicitly create or reference related work in other operational domains, replacing manual coordination with traceable relationships.

  • Reusable two-stage approval framework: sequential approval with explicit actor assignment, immutable decisions, audit history, notifications and delegated decision channels for actors who do not require permanent platform access.

  • Separated request, approval and fulfilment lifecycles: approval remains an independent platform capability while downstream integration and operational fulfilment stay owned by the consuming business domain.

  • Deployment-ready, containerized architecture, operated across development, test and production, with an automated test suite on the order of a thousand tests.

Lessons Learned

This project reinforced a few things I now treat as defaults rather than options:

  • Domain modelling pays for itself. Time spent getting the lifecycle and entity relationships right up front was cheaper than retrofitting audit trails or cross-domain links onto a plain form.
  • Lifecycle-aware design scales better than feature-aware design. Adding a sixth domain is a smaller task than adding a second feature would have been to a codebase built as isolated forms, since it reuses almost everything the first five already established.
  • Good UX follows from the domain model; it isn't a separate design pass. Once entities, lifecycles and relationships were modelled correctly, the detail-page workspace, history view and timeline fell out of that model rather than needing a fresh design pass.
  • A data background is an asset, not just an origin story. Thinking in structured data, traceability and consistency before writing application code has produced simpler systems than starting from the UI inward.
  • Platform engineering is a mindset, not a job title. Whether the label on a given day is "Django developer" or "DevOps engineer," the question is the same: is this a one-off, or a pattern worth building once and reusing.

Start from the entity and its lifecycle, not the screen; build the shared layer before the fifth form needs it, not after.

Confidentiality

This case study focuses on general engineering principles, architectural patterns and lessons learned from building an internal IT operations platform. Company-identifying information, internal URLs, employee or colleague data, ticket contents, credentials, configuration details, infrastructure specifics, internal project references and other sensitive operational information are intentionally omitted.

The purpose of this case study is to explain the engineering approach behind the platform, domain modelling, lifecycle design, reusable capabilities, traceability and integration boundaries rather than to document the internal environment in which it operates.

← All Projects