POS Gateway - Models

Location: api/nextango/apps/pos_gateway/models.py Last Updated: 2026-07-09

Overview

POS Gateway models track real-time terminal sessions, temporary inventory holds, manager approval workflows, and gateway performance data. None of these models sync to Sanity. They are born from operational events at the terminal (a login, a scan, an approval request), not authored in the CMS, so Django owns them outright.


TerminalSession

An active POS terminal session, created on employee PIN login and updated on every heartbeat and logout.

Base class: AuditableMixin, SoftDeleteMixin

FieldTypeDescription
terminal_idCharField, uniqueUnique terminal identifier (e.g. STORE001-POS02)
userForeignKey to UserEmployee currently logged into the terminal
storeForeignKey to StoreStore the terminal belongs to
statusCharField (choices)active, inactive, suspended, expired
login_timeDateTimeFieldWhen the session started
last_activityDateTimeFieldLast API call or WebSocket message
logout_timeDateTimeField, nullableWhen the user logged out
auth_tokenTextFieldJWT access token for this session
refresh_tokenTextField, nullableReserved for a future refresh flow; not currently issued or read anywhere in the gateway
expires_atDateTimeFieldWhen auth_token expires
capabilitiesJSONFieldTerminal hardware/software capabilities, set to an empty dict at session creation
configurationJSONFieldTerminal-specific settings, set to an empty dict at session creation
transaction_countPositiveIntegerFieldNumber of transactions created through this session
avg_response_timeFloatField, nullableReserved for a future performance metric; not currently written by any gateway code path
last_heartbeatDateTimeFieldLast WebSocket heartbeat or session refresh

is_active() returns True when status is active, expires_at is in the future, and the row is not soft-deleted. update_activity() bumps last_activity to now.

A row is created (or refreshed via update_or_create) by PosGatewayAuthenticationClient._create_terminal_session on login. See Authentication and Serializers for the TerminalLoginSerializer that validates the login request, and Services for TransactionGatewayService, which increments transaction_count.


InventoryReservation

Model for a temporary hold on inventory while a customer checks out, intended to prevent two terminals from selling the last unit of a SKU at the same time.

Base class: AuditableMixin, SoftDeleteMixin

FieldTypeDescription
reservation_idCharField, uniqueUnique reservation identifier
terminal_sessionForeignKey to TerminalSessionTerminal that created the reservation
product_variant_idCharFieldProduct variant identifier
skuCharFieldProduct SKU
quantityPositiveIntegerFieldUnits reserved
statusCharField (choices)reserved, committed, released, expired
reserved_atDateTimeFieldWhen the reservation was created
expires_atDateTimeFieldWhen the reservation auto-expires
committed_atDateTimeField, nullableWhen inventory was actually deducted
released_atDateTimeField, nullableWhen the reservation was released back to inventory
transaction_idCharField, nullableAssociated SaleTransaction ID once payment completes

is_active() returns True when status is reserved, expires_at is in the future, and the row is not soft-deleted.

No code path in the current gateway creates InventoryReservation rows. Inventory holds for POS sales are handled by the transactions app's own reservation and adjustment services when line items are created, not by this model. The class remains defined and admin-registered but unwritten; treat any reservation UI or reporting built against this table as forward-looking, not live.


ManagerApprovalRequest

A request for manager sign-off on a sensitive terminal action (discount, void, return, price override, cash drawer access, refund).

Base class: AuditableMixin, SoftDeleteMixin

FieldTypeDescription
request_idCharField, uniqueUnique approval request identifier
terminal_sessionForeignKey to TerminalSessionTerminal that raised the request
request_typeCharField (choices)discount, void, return, price_override, cash_drawer, refund
statusCharField (choices)pending, approved, denied, expired, cancelled
amountDecimalField, nullableDollar amount for financial approval types
reasonTextFieldCashier's explanation for the request
detailsJSONFieldAdditional request-type-specific context
requested_atDateTimeFieldWhen the request was created
expires_atDateTimeFieldWhen the request auto-expires (10 minutes after creation)
approved_byForeignKey to User, nullable, SET_NULLManager who approved or denied the request
approved_atDateTimeField, nullableWhen the manager responded
approval_reasonTextField, blankManager's explanation, required when denying
requested_byForeignKey to User, nullable, SET_NULLCashier who raised the request: the terminal session's authenticated user at request time, recorded explicitly so the requester survives independent of terminal_session.user changing later
transaction_idCharField, nullableAssociated SaleTransaction ID, null for non-transaction requests such as cash drawer access

is_pending() returns True when status is pending, expires_at is in the future, and the row is not soft-deleted.

Created by ManagerApprovalGatewayService.request_approval(), which populates both terminal_session and requested_by from the same session. See Services and Consumers for the WebSocket-driven approval flow, and Serializers for ManagerApprovalRequestSerializer.


GatewayPerformanceMetric

A time-series row for gateway performance data (response time, transaction count, error rate, cache hit rate, WebSocket connection count).

Base class: AuditableMixin

FieldTypeDescription
terminal_sessionForeignKey to TerminalSession, nullableTerminal the metric applies to, if any
storeForeignKey to StoreStore the metric applies to
metric_typeCharField (choices)response_time, transaction_count, error_rate, cache_hit_rate, websocket_connections
valueFloatFieldMetric value
timestampDateTimeFieldWhen the metric was recorded
endpointCharField, blankEndpoint the metric was captured against
operationCharField, blankOperation name
metadataJSONFieldAdditional context

No code path in the current gateway writes GatewayPerformanceMetric rows. HealthCheckView returns cache hit rate and average response time as static placeholder values rather than querying this table. The model is defined and admin-registered but has no writer anywhere in the codebase; treat it as scaffolded for a metrics pipeline that has not been built yet.


  • Authentication: JWT terminal login and session validation
  • Serializers: request/response validation for these models
  • Services: business logic that creates and updates these rows
  • Views: REST endpoints backed by these models
  • Consumers: WebSocket handling of TerminalSession and ManagerApprovalRequest state

Was this page helpful?