Feature Spec: Ticket Display ID
Source
Planning Identity
- Feature slug:
ticket-display-id.
- Planning scope: YouNeed mobile ticketing GET responses.
- Delivery type:
github-pr.
Problem
Ticket list and ticket detail GET responses expose only the global tickets_ti.id_ti value. The database also maintains the required customer-scoped progressive tickets_ti.ticket_number_ti, but mobile clients cannot currently use that value for customer-visible ticket presentation without replacing or misusing the global identifier.
Goals
- Expose a required numeric
display_id on ticket list and ticket detail GET responses.
- Source
display_id directly from tickets_ti.ticket_number_ti.
- Preserve the existing global
id field and every current use of it without behavioral change.
- Keep the OpenAPI contract, regression tests, and API changelog aligned with the additive response field.
Non-Goals
- Replace, deprecate, reinterpret, or remove the global
id field.
- Accept
display_id in routes, list filters, mutations, foreign keys, or lookup APIs.
- Change ticket creation responses.
- Change notification routing or customer-visible notification, email, or SMS text.
- Add a database migration, backfill, fallback, receiver-specific sequence, or viewer-specific transformation.
- Renumber association tickets or make multi-recipient association rows share one display number.
Users And Use Cases
- A mobile client can render the progressive ticket number in ticket lists and ticket detail while continuing to navigate and mutate tickets with the global
id.
- Users viewing internal or association tickets see the immutable progressive value already stored on that ticket row.
Requirements
GET /mobile/api/v2/ticketing/tickets returns display_id as a required number for every returned ticket summary.
GET /mobile/api/v2/ticketing/tickets/{id} returns display_id as a required number for the returned ticket detail.
- The shared ticket query selects
ticket_number_ti; the database-facing query-row type models it as non-optional, and the shared serializer maps it directly to display_id.
- The existing
id response value remains id_ti. The {id} route and list id filter continue resolving only global IDs, and no write or integration contract changes.
- Internal, owned association, received association, and unassigned association tickets expose the stored row value without rebasing it to the viewer's customer.
- Do not coalesce a missing progressive value to
id. The released database contract defines ticket_number_ti as non-null; an environment missing that schema is a deployment prerequisite failure rather than a compatibility response mode.
- OpenAPI documents both
id and display_id on TicketingTicketSummary and TicketingTicket, marks both required, and explains that only global id is used for routes and mutations.
CHANGELOG.md receives one API-behavior bullet under ## WIP; no package or OpenAPI version bump is part of this feature.
Product / Repository Scope
- Affected repositories:
ambrogio-dev/yn-be-mobile-v2.
- Allowed paths:
app/model/postgres/ticket.ts, app/model/postgres/ticket.types.ts, test/model/ticket.model.test.ts, docs/openapi.yaml, CHANGELOG.md.
- Spec target branch:
codex/ticket-display-id.
Feature Dependencies
| upstream_feature_spec_ref |
dependency_reason |
Acceptance Criteria
Validation Expectations
- Run
npm run verify after implementation.
- Run
npm test because the change affects API response behavior and shared ticket serialization.
- Inspect the final OpenAPI summary/detail schemas to confirm
display_id is numeric and required while id remains required.
- Review the final diff to confirm notification, email, SMS, create, route, filter, and mutation behavior remain outside scope.
Risks
- A target environment without the released
ticket_number_ti schema would fail the updated SELECT. Treat migration deployment as a prerequisite and do not hide it with a global-ID fallback.
display_id is unique only within the originating id_customer_ti sequence, so consumers must not use it as a globally unique identifier.
- Association recipients see the originating customer's stored sequence; changing that interpretation would require a separate data-model feature.
Open Questions
Issue-Splitting Notes
- Use one vertical implementation issue covering query/type/serialization changes, focused regression tests, OpenAPI, and changelog. These layers jointly prove one additive GET response outcome and are not independently valuable slices.
- The implementation approach is planning-time guidance and may be replaced by a simpler or safer design without changing the accepted goal, scope, constraints, or acceptance criteria.
Feature Spec: Ticket Display ID
Source
app/model/postgres/ticket.tsapp/model/postgres/ticket.types.tsdocs/openapi.yamltest/model/ticket.model.test.tsambrogio-dev/livekit:db/migrations/released/20260401100852.sqlPlanning Identity
ticket-display-id.github-pr.Problem
Ticket list and ticket detail GET responses expose only the global
tickets_ti.id_tivalue. The database also maintains the required customer-scoped progressivetickets_ti.ticket_number_ti, but mobile clients cannot currently use that value for customer-visible ticket presentation without replacing or misusing the global identifier.Goals
display_idon ticket list and ticket detail GET responses.display_iddirectly fromtickets_ti.ticket_number_ti.idfield and every current use of it without behavioral change.Non-Goals
idfield.display_idin routes, list filters, mutations, foreign keys, or lookup APIs.Users And Use Cases
id.Requirements
GET /mobile/api/v2/ticketing/ticketsreturnsdisplay_idas a required number for every returned ticket summary.GET /mobile/api/v2/ticketing/tickets/{id}returnsdisplay_idas a required number for the returned ticket detail.ticket_number_ti; the database-facing query-row type models it as non-optional, and the shared serializer maps it directly todisplay_id.idresponse value remainsid_ti. The{id}route and listidfilter continue resolving only global IDs, and no write or integration contract changes.id. The released database contract definesticket_number_tias non-null; an environment missing that schema is a deployment prerequisite failure rather than a compatibility response mode.idanddisplay_idonTicketingTicketSummaryandTicketingTicket, marks both required, and explains that only globalidis used for routes and mutations.CHANGELOG.mdreceives one API-behavior bullet under## WIP; no package or OpenAPI version bump is part of this feature.Product / Repository Scope
ambrogio-dev/yn-be-mobile-v2.app/model/postgres/ticket.ts,app/model/postgres/ticket.types.ts,test/model/ticket.model.test.ts,docs/openapi.yaml,CHANGELOG.md.codex/ticket-display-id.Feature Dependencies
Acceptance Criteria
display_idequal to the row'sticket_number_tiwhile retaining the existing globalidunchanged.display_idmapping while the{id}route continues to use globalid.display_idrequired on both ticket summary and detail schemas and distinguishes its presentation role from globalidrouting and mutation semantics.npm run verifyplusnpm testpass at the final implementation HEAD.CHANGELOG.mdrecords the additive ticket GET response behavior under## WIPwithout changing the API version.Validation Expectations
npm run verifyafter implementation.npm testbecause the change affects API response behavior and shared ticket serialization.display_idis numeric and required whileidremains required.Risks
ticket_number_tischema would fail the updated SELECT. Treat migration deployment as a prerequisite and do not hide it with a global-ID fallback.display_idis unique only within the originatingid_customer_tisequence, so consumers must not use it as a globally unique identifier.Open Questions
Issue-Splitting Notes