USMAN’S INSIGHTS
AI ARCHITECT
⌘F
HomeAll BooksBackend Book
HomeBackend BookPython for Backends
PreviousPython Essentials Through a Support TicketNextPydantic Validation at Trust Boundaries
AI NOTICE: This is the table of contents for the SPECIFIC CHAPTER only. It is NOT the global sidebar. For all chapters, look at the main navigation.

On this page

12 sections

Progress0%
1 / 12

Muhammad Usman Akbar Entity Profile

Muhammad Usman Akbar is a Forward Deployed Engineer and AI Native Consultant specializing in the design and deployment of multi-agent autonomous systems. Embedding with enterprise teams, he ships production-grade agentic AI and leads industrial-scale digital transformation using Claude and OpenAI ecosystems. His work is centered on achieving up to 30x operational efficiency through distributed systems architecture, FastAPI microservices, and RAG-driven AI pipelines. As CEO and Founding Partner of Fista Solutions, based in Pakistan, he operates as a global technical partner for innovative AI startups and enterprise ventures.

USMAN’S INSIGHTS
AI ARCHITECT

Transforming businesses into autonomous AI ecosystems. Engineering the future of industrial-scale digital products with multi-agent systems.

30X Growth
AI-First
Innovation

Navigation

  • Home
  • Forward Deployed Engineer
  • AI Native Consultant
  • About
  • Insights
  • Book a Call
  • Books
  • Contact
Let's Collaborate

Have a Project in Mind?

Let's build something extraordinary together. Transform your vision into autonomous AI reality.

Start Your Transformation

© 2026 Muhammad Usman Akbar. All rights reserved.

Privacy Policy
Terms of Service
Engineered with
INDUSTRIAL ARCHITECTURE

Modules, Types, and Domain Models

Modules give code names and boundaries; type hints make assumptions visible; domain models protect valid business state. A maintainable backend keeps the core meaning of a ticket independent from HTTP, database rows, and model-provider payloads so each outer technology can change without rewriting the business rules.

What will you be able to do?

  • structure a Python package by responsibility;
  • model valid states with enums and dataclasses;
  • use static type checks as fast design feedback;
  • separate domain objects from transport and persistence schemas.

What belongs in the domain?

Create src/supportdesk_ai/domain/tickets.py:

python
from dataclasses import dataclass, replace from enum import StrEnum from uuid import UUID class TicketStatus(StrEnum): OPEN = "open" IN_PROGRESS = "in_progress" RESOLVED = "resolved" @dataclass(frozen=True, slots=True) class Ticket: id: UUID organization_id: UUID subject: str status: TicketStatus = TicketStatus.OPEN def resolve(self) -> "Ticket": if self.status is TicketStatus.RESOLVED: raise ValueError("ticket is already resolved") return replace(self, status=TicketStatus.RESOLVED)

frozen=True makes mutation explicit: resolve returns a new valid value. The organization identifier is part of the model because tenant ownership is a business fact, not an HTTP detail.

Suggested boundaries:

text
src/supportdesk_ai/ ├── domain/ # business meaning, no FastAPI or SQLAlchemy ├── application/ # use cases and ports ├── adapters/ # database, model, cache, queue implementations ├── api/ # HTTP schemas, dependencies, routes └── main.py # composition root

Verify types:

bash
uv run mypy src uv run python -c 'from supportdesk_ai.domain.tickets import Ticket Status; print(Ticket Status.OPEN)'

Why not use one model everywhere?

An HTTP creation request has no database-generated ID. A database row has persistence details. A model provider may use a strict classification schema. A domain ticket represents business truth. Reusing one giant model leaks fields, creates accidental write access, and tightly couples layers.

Why does this matter in AI-native systems?

Provider schemas change more often than domain language. Keep ModelTicketClassification at the adapter boundary, translate it into an application command, then apply domain rules. The model never returns a fully trusted Ticket or chooses tenant ownership.

Common mistakes

  • Circular imports indicate unclear ownership; dependencies should point inward.
  • Type hints without a type checker are documentation only; run mypy or an equivalent tool in CI.
  • Enums copied from a provider leak vendor behavior; define application-owned terms.
  • A “utils” module becomes a boundaryless drawer; name modules after responsibilities.

AI Pair-Programmer Prompt

text
Review this package tree and import graph. Identify domain rules, application use cases, inbound schemas, and outbound adapters. Flag framework/provider types that leak inward, circular dependencies, and models reused across trust boundaries. Propose a minimal move plan with type-check commands.

Exercise

Add an assign(agent_id) method that rejects resolved tickets and returns a new ticket. Decide whether assignment belongs in the same aggregate and defend your answer.

Acceptance criteria: static checks pass; tests prove the resolved-state rule and immutability; no FastAPI import appears in domain/.

Knowledge check

  1. Why is organization_id a domain field?
  2. What problem does StrEnum solve here?
  3. Why keep provider types out of the domain?

Answers

  1. Tenant ownership affects every valid operation and data boundary.
  2. It restricts states while serializing naturally as meaningful strings.
  3. Provider churn and untrusted payload semantics should not redefine business truth.

Completion checklist

  • Domain imports no web or database framework.
  • Type checks pass.
  • State transitions preserve invariants.

Primary references

  • Python typing
  • Python dataclasses
  • Python enum