Skip to content
chiltepin

Generated from: “Who does what with the ticketing system — customers, agents, the payment provider — and which features depend on others?

Ticketing system — actors and feature dependencies

Written by an agent from the skill, validated by chiltepin check, rendered by the renderer — shown as generated, 13 September 2026.

DOCUMENTDRAFT

Ticketing system — actors and feature dependencies

Who does what with the ticketing system, and which feature needs which.

SECTION 01 · Note

Assumptions

Note
Three actors: the customer buys and manages seats, the support agent handles refunds and reissues, and the payment provider (Stripe) authorizes and refunds card charges. Event organizers and venue staff are out of scope. Every purchase is paid by card; there is no invoice flow.

Actors and their use cases

The customer never touches money directly. Every purchase includes a card payment that the payment provider completes, and the provider is the only actor that can confirm or fail a charge. The support agent approves refunds and reissues tickets, but never creates a purchase.

SECTION 02 · Use cases
USE CASE
Use-case diagram: Ticketing, 3 actors, 10 use casesTicketingBrowse eventsReserve seatsBuy ticketsPay by cardConfirm chargeRequest refundApprove refundReverse chargeReissue ticketTransfer ticketCustomerSupport agentSYSPayment provider123456
1«include» holds seats 10 min2«include»3«include»4«extend» over 200 EUR5«include»6«extend» lost or damaged
Legenduse caseexternal systemassociation«include»«extend»

Refunds under 200 EUR run without an agent. Above that line the request waits for an approval, and the charge reversal runs only after the approval.

Which feature depends on which

The dependency order is the order features can ship. Seat reservation works without payment, so a free-event mode is possible. Payment does not work without reservation: a charge with no held seat cannot be fulfilled. Refunds sit at the top of the stack and need every module below them.

SECTION 03 · Comparison
FeatureNeedsOwner actorStatus
Browse eventsCustomerLive
Reserve seatsBrowse eventsCustomerLive
Buy ticketsReserve seats, Pay by cardCustomerLive
Pay by cardConfirm chargePayment providerLive
Transfer ticketBuy ticketsCustomerBeta
Request refundBuy tickets, Reverse chargeCustomerLive
Approve refundRequest refundSupport agentLive
Reissue ticketBuy tickets, Approve refundSupport agentPlanned

The Needs column lists direct dependencies only. Transitive ones follow from the rows above.

Module dependencies in the codebase

Each feature above lives in one module. Dependencies point downward: refunds and tickets use payments, payments imports the provider client through a port, and nothing depends upward on refunds. A change to catalog reaches every module; a change to refunds reaches none.

SECTION 04 · Packages

Ticketing modules

PACKAGES
Package diagram: 6 packages, 7 dependenciesrefundsrequestapprovalreversalticketspurchasetransferreissuepaymentschargeconfirmreverseseatingholdreleaseallocatecatalogeventsvenuespricespsp-client«external»stripe-adapter1234567
1«use» reads the purchase2«use» requests reversal3«use» holds and allocates seats4«use» charges the card5«import» reads seat maps6«import» reads prices7«import» port only
Legendpackagedependency«import»import«use»use

The psp-client package is the only place the provider SDK appears. Swapping the provider changes one adapter and no use case.

View the Markdown
```meta
title: Ticketing system — actors and feature dependencies
subtitle: Who does what with the ticketing system, and which feature needs which.
tag: DRAFT
```

```callout
tone: note
title: Assumptions
body: "Three actors: the customer buys and manages seats, the support agent handles refunds and reissues, and the payment provider (Stripe) authorizes and refunds card charges. Event organizers and venue staff are out of scope. Every purchase is paid by card; there is no invoice flow."
```

## Actors and their use cases

The customer never touches money directly. Every purchase includes a card payment that the payment provider completes, and the provider is the only actor that can confirm or fail a charge. The support agent approves refunds and reissues tickets, but never creates a purchase.

```usecase
system: Ticketing
actors:
  - { id: customer, name: Customer, kind: person, side: left }
  - { id: agent, name: Support agent, kind: person, side: left }
  - { id: psp, name: Payment provider, kind: system, side: right }
cases:
  - { id: browse, name: Browse events }
  - { id: reserve, name: Reserve seats }
  - { id: buy, name: Buy tickets }
  - { id: pay, name: Pay by card }
  - { id: confirm, name: Confirm charge }
  - { id: refund, name: Request refund }
  - { id: approve, name: Approve refund }
  - { id: reverse, name: Reverse charge }
  - { id: reissue, name: Reissue ticket }
  - { id: transfer, name: Transfer ticket }
links:
  - customer -> browse
  - customer -> reserve
  - customer -> buy
  - customer -> refund
  - customer -> transfer
  - agent -> approve
  - agent -> reissue
  - psp -> confirm
  - psp -> reverse
relations:
  - { from: buy, to: reserve, kind: include, label: holds seats 10 min }
  - { from: buy, to: pay, kind: include }
  - { from: pay, to: confirm, kind: include }
  - { from: refund, to: approve, kind: extend, label: over 200 EUR }
  - { from: approve, to: reverse, kind: include }
  - { from: reissue, to: buy, kind: extend, label: lost or damaged }
```

Refunds under 200 EUR run without an agent. Above that line the request waits for an approval, and the charge reversal runs only after the approval.

## Which feature depends on which

The dependency order is the order features can ship. Seat reservation works without payment, so a free-event mode is possible. Payment does not work without reservation: a charge with no held seat cannot be fulfilled. Refunds sit at the top of the stack and need every module below them.

```table
columns: [Feature, Needs, Owner actor, Status]
rows:
  - [Browse events, "—", Customer, { v: Live, tone: pos }]
  - [Reserve seats, Browse events, Customer, { v: Live, tone: pos }]
  - [Buy tickets, "Reserve seats, Pay by card", Customer, { v: Live, tone: pos }]
  - [Pay by card, Confirm charge, Payment provider, { v: Live, tone: pos }]
  - [Transfer ticket, Buy tickets, Customer, { v: Beta, tone: warn }]
  - [Request refund, "Buy tickets, Reverse charge", Customer, { v: Live, tone: pos }]
  - [Approve refund, Request refund, Support agent, { v: Live, tone: pos }]
  - [Reissue ticket, "Buy tickets, Approve refund", Support agent, { v: Planned, tone: muted }]
note: "The Needs column lists direct dependencies only. Transitive ones follow from the rows above."
```

## Module dependencies in the codebase

Each feature above lives in one module. Dependencies point downward: `refunds` and `tickets` use `payments`, `payments` imports the provider client through a port, and nothing depends upward on `refunds`. A change to `catalog` reaches every module; a change to `refunds` reaches none.

```pkg
title: Ticketing modules
dir: TB
packages:
  - { id: refunds, col: 1, row: 1, name: refunds, contains: [request, approval, reversal] }
  - { id: tickets, col: 2, row: 1, name: tickets, contains: [purchase, transfer, reissue] }
  - { id: payments, col: 2, row: 2, name: payments, contains: [charge, confirm, reverse] }
  - { id: seating, col: 1, row: 2, name: seating, contains: [hold, release, allocate] }
  - { id: catalog, col: 1, row: 3, name: catalog, contains: [events, venues, prices] }
  - { id: psp, col: 2, row: 3, name: psp-client, contains: [stripe-adapter], stereotype: external }
deps:
  - { from: refunds, to: tickets, kind: use, label: reads the purchase }
  - { from: refunds, to: payments, kind: use, label: requests reversal }
  - { from: tickets, to: seating, kind: use, label: holds and allocates seats }
  - { from: tickets, to: payments, kind: use, label: charges the card }
  - { from: seating, to: catalog, kind: import, label: reads seat maps }
  - { from: payments, to: catalog, kind: import, label: reads prices }
  - { from: payments, to: psp, kind: import, label: port only }
```

The `psp-client` package is the only place the provider SDK appears. Swapping the provider changes one adapter and no use case.