Abstract base class and factory function for the Axion ticket provider system.
The ticket provider pattern decouples ticket operations from their backing
store. Callers work against ObjTicketProvider and never need to know
whether operations target the internal database, Asana, or both.
Configuration in config.yaml determines which concrete provider is
instantiated at runtime:
homechoice:
ticket:
provider: sync # internal | asana | sync
asana_project: "" # Asana project GID (required for asana/sync)
+---------------------+
| ObjTicketProvider | (ABC)
|---------------------|
| + create() |
| + update() |
| + change_status() |
| + assign() |
| + add_comment() |
| + get_ticket() |
| + list_tickets() |
| + close() |
| + resolve() |
| + escalate() |
+---------------------+
^ ^ ^
| | |
+-----------+ +---+---+ +-----------+
| | | |
+-------+-------+ +-----+-----+ +------+------+
| ObjTicket | | ObjTicket | | ObjTicket |
| Internal | | Asana | | Sync |
|---------------| |-----------| |-------------|
| ObjTicket | | ObjService| | Internal + |
| (data_ticket) | | Asana API | | Asana |
+---------------+ +-----------+ +-------------+
All operations go to data_ticket via ObjTicket. This is the default
provider when no ticket.provider config key is set.
All operations go to Asana via ObjServiceAsana. Ticket statuses are
mapped to Asana project sections; priorities are mapped to tag names.
Status-to-section mapping:
| TicketStatus | Asana Section |
|---|---|
| NEW | New |
| TRIAGED | Triaged |
| IN_PROGRESS | In Progress |
| ON_HOLD | On Hold |
| ESCALATED | Escalated |
| RESOLVED | Resolved |
| CLOSED | Closed |
| CANCELLED | Cancelled |
Dual-write provider. Every operation is committed to the internal
database first, then a best-effort sync pushes the change to Asana.
If the Asana call fails, the internal operation still succeeds and a
warning is logged.
The def_asana_sync table (managed by ObjServiceAsana) stores the
guid (internal) to gid (Asana) mapping.
Extra methods:
sync_to_asana(guid) -- push a local ticket to Asanasync_from_asana(asana_gid) -- pull an Asana task into internal DBfrom ObjTicketProvider import get_provider
provider = get_provider(db=0)
result = provider.create(subject="Server down")
get_provider() reads ticket.provider from config.yaml and returns
the matching implementation.
Every provider method returns a dict containing at minimum:
| Key | Type | Description |
|---|---|---|
guid |
str | Ticket identifier (guid or Asana gid) |
status |
str | Current ticket status |
provider |
str | Provider name (internal/asana/sync) |
Additional keys may be present depending on the operation (e.g.
comment_guid, assigned_to, asana_gid).