openapi: 3.0.0
paths:
  /notification-settings:
    get:
      operationId: NotificationSettingsController_get
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationSettingsResponseDto'
      tags:
        - notifications
    put:
      operationId: NotificationSettingsController_update
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationSettingsResponseDto'
      tags:
        - notifications
  /currency-rates:
    get:
      operationId: CurrencyRatesController_get
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CurrencyRatesResponseDto'
      tags:
        - currency
  /preferences:
    get:
      operationId: PreferencesController_get
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PreferencesResponseDto'
      tags:
        - preferences
    put:
      operationId: PreferencesController_update
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PreferencesResponseDto'
      tags:
        - preferences
  /notifications/feed:
    get:
      operationId: NotificationFeedController_feed
      parameters:
        - name: limit
          required: true
          in: query
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AuditEventResponseDto'
      tags:
        - notifications
  /notifications/activity:
    get:
      operationId: NotificationFeedController_activity
      parameters:
        - name: limit
          required: true
          in: query
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AuditEventResponseDto'
      tags:
        - notifications
  /audit-log:
    get:
      operationId: UserAuditController_list
      parameters:
        - name: limit
          required: true
          in: query
          schema:
            type: string
        - name: offset
          required: true
          in: query
          schema:
            type: string
        - name: steamAccountId
          required: true
          in: query
          schema:
            type: string
        - name: category
          required: true
          in: query
          schema:
            type: string
        - name: severity
          required: true
          in: query
          schema:
            type: string
        - name: since
          required: true
          in: query
          schema:
            type: string
        - name: search
          required: true
          in: query
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AuditEventResponseDto'
      tags:
        - notifications
  /auth/signup:
    post:
      operationId: AuthController_signup
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnerAuthResponseDto'
        '429':
          description: Signup is rate-limited per client.
      tags:
        - auth
  /auth/login:
    post:
      operationId: AuthController_login
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OwnerLoginDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnerAuthResponseDto'
        '429':
          description: Owner login is temporarily locked after repeated failures.
      tags:
        - auth
  /auth/password-reset/request:
    post:
      operationId: AuthController_requestPasswordReset
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasswordResetRequestDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasswordResetRequestResponseDto'
        '429':
          description: Password reset requests are rate-limited per client.
      tags:
        - auth
  /auth/password-reset/confirm:
    post:
      operationId: AuthController_confirmPasswordReset
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasswordResetConfirmDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasswordResetConfirmResponseDto'
      tags:
        - auth
  /auth/me:
    get:
      operationId: AuthController_me
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnerAuthResponseDto'
      tags:
        - auth
  /auth/logout:
    post:
      operationId: AuthController_logout
      parameters: []
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnerLogoutResponseDto'
      tags:
        - auth
  /auth/service/me:
    get:
      operationId: AuthController_getServiceAuth
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceAuthResponseDto'
      tags:
        - auth
  /auth/service-keys:
    get:
      operationId: AuthController_listServiceApiKeys
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ServiceApiKeyDto'
      tags:
        - auth
    post:
      operationId: AuthController_createServiceApiKey
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateServiceApiKeyDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreatedServiceApiKeyDto'
      tags:
        - auth
  /auth/service-keys/{id}/revoke:
    post:
      operationId: AuthController_revokeServiceApiKey
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceApiKeyDto'
      tags:
        - auth
  /health:
    get:
      operationId: HealthController_getHealth
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponseDto'
      tags:
        - health
  /health/ready:
    get:
      operationId: HealthController_getReadiness
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReadinessResponseDto'
        '503':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReadinessResponseDto'
      tags:
        - health
  /meta/error-codes:
    get:
      operationId: MetaController_getErrorCodes
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorCodesResponseDto'
      tags:
        - meta
  /meta/capabilities:
    get:
      operationId: MetaController_getCapabilities
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCapabilitiesResponseDto'
      tags:
        - meta
  /meta/limits:
    get:
      operationId: MetaController_getLimits
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TradingLimitsResponseDto'
      tags:
        - meta
  /meta/version:
    get:
      operationId: MetaController_getVersion
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiVersionResponseDto'
      tags:
        - meta
  /games:
    get:
      operationId: GameCatalogController_list
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GameResponseDto'
      tags:
        - games
  /steam-accounts:
    post:
      operationId: AccountsController_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSteamAccountDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SteamAccountResponseDto'
      tags:
        - steam-accounts
    get:
      operationId: AccountsController_list
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SteamAccountResponseDto'
      tags:
        - steam-accounts
  /steam-accounts/{steamAccountId}:
    get:
      operationId: AccountsController_get
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
      tags:
        - steam-accounts
    patch:
      operationId: AccountsController_update
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateSteamAccountDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SteamAccountResponseDto'
      tags:
        - steam-accounts
    delete:
      operationId: AccountsController_delete
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SteamAccountResponseDto'
      tags:
        - steam-accounts
  /steam-accounts/{steamAccountId}/secrets:
    post:
      operationId: AccountsController_upsertSecrets
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpsertSteamAccountSecretsDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SteamAccountSecretsStatusDto'
      tags:
        - steam-accounts
  /steam-accounts/{steamAccountId}/secrets/status:
    get:
      operationId: AccountsController_getSecretsStatus
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SteamAccountSecretsStatusDto'
      tags:
        - steam-accounts
  /steam-accounts/{steamAccountId}/audit-events:
    get:
      operationId: AccountsController_listAuditEvents
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
      tags:
        - steam-accounts
  /steam-accounts/{steamAccountId}/proxy:
    get:
      operationId: ProxyController_getProxy
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProxyProfileResponseDto'
      tags:
        - proxy
    put:
      operationId: ProxyController_upsertProxy
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpsertProxyProfileDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProxyProfileResponseDto'
      tags:
        - proxy
  /steam-accounts/{steamAccountId}/proxy/test:
    post:
      operationId: ProxyController_testProxy
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProxyTestResponseDto'
      tags:
        - proxy
  /steam-accounts/{steamAccountId}/market-state/items:
    post:
      operationId: MarketStateController_createItem
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMarketItemDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateMarketItemResponseDto'
      tags:
        - market-state
    get:
      operationId: MarketStateController_listItems
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MarketItemsPageResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/items/bulk-move:
    post:
      operationId: MarketStateController_bulkMoveItems
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkMoveMarketItemsDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkMoveMarketItemsResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/items/bulk-delete:
    post:
      operationId: MarketStateController_bulkDeleteItems
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkDeleteMarketItemsDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkDeleteMarketItemsResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/items/{itemId}/trade-state:
    patch:
      operationId: MarketStateController_patchItemTradeState
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: itemId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchTradeStateDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ItemTradeStateResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/items/{itemId}/cancel-buy-order:
    post:
      operationId: MarketStateController_cancelItemBuyOrder
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: itemId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/buy-orders/cancel-by-age:
    post:
      operationId: MarketStateController_cancelBuyOrdersByAge
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/listings/remove-all:
    post:
      operationId: MarketStateController_removeAllListings
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/items/{itemId}/remove-listings:
    post:
      operationId: MarketStateController_removeItemListings
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: itemId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/catalog:
    get:
      operationId: MarketStateController_listCatalogItems
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CatalogItemsPageResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/inventory/import:
    post:
      operationId: MarketStateController_importInventoryItems
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImportInventoryItemsDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImportInventoryItemsResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/catalog/add-to-account:
    post:
      operationId: MarketStateController_addCatalogItemsToAccount
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddCatalogItemsToAccountDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AddCatalogItemsToAccountResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/catalog/preview-add-to-account:
    post:
      operationId: MarketStateController_previewCatalogItemsForAccount
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddCatalogItemsToAccountDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AddCatalogItemsToAccountResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/import/settings:
    post:
      operationId: MarketStateController_importLegacySettings
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Object'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImportLegacySettingsResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/import/listings:
    post:
      operationId: MarketStateController_importListingsSnapshot
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImportListingsSnapshotDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImportListingsSnapshotResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/groups:
    post:
      operationId: MarketStateController_createGroup
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateGroupDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ItemGroupResponseDto'
      tags:
        - market-state
    get:
      operationId: MarketStateController_listGroups
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ItemGroupResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/groups/{groupId}:
    put:
      operationId: MarketStateController_updateGroup
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: groupId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateGroupDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ItemGroupResponseDto'
      tags:
        - market-state
    delete:
      operationId: MarketStateController_deleteGroup
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: groupId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeleteGroupResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/strategy-profiles:
    post:
      operationId: MarketStateController_createStrategyProfile
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateStrategyProfileDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StrategyProfileResponseDto'
      tags:
        - market-state
    get:
      operationId: MarketStateController_listStrategyProfiles
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/StrategyProfileResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/market-state/runtime-settings:
    put:
      operationId: MarketStateController_upsertRuntimeSettings
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpsertRuntimeSettingsDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RuntimeSettingsResponseDto'
      tags:
        - market-state
    get:
      operationId: MarketStateController_getRuntimeSettings
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RuntimeSettingsResponseDto'
      tags:
        - market-state
  /steam-accounts/{steamAccountId}/decisions/jobs:
    get:
      operationId: DecisionsController_listJobs
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DecisionJobResponseDto'
      tags:
        - decisions
  /steam-accounts/{steamAccountId}/decisions/jobs/{jobQueueId}/result:
    get:
      operationId: DecisionsController_getJobResult
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: jobQueueId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecisionJobResultResponseDto'
      tags:
        - decisions
  /steam-accounts/{steamAccountId}/decisions/jobs/{jobQueueId}/retry:
    post:
      operationId: DecisionsController_retryJob
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: jobQueueId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnqueueDecisionJobResponseDto'
      tags:
        - decisions
  /steam-accounts/{steamAccountId}/decisions/jobs/{jobQueueId}/cancel:
    post:
      operationId: DecisionsController_cancelJob
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: jobQueueId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecisionJobResponseDto'
      tags:
        - decisions
  /steam-accounts/{steamAccountId}/decisions/jobs/{jobQueueId}:
    get:
      operationId: DecisionsController_getJob
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: jobQueueId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecisionJobResponseDto'
      tags:
        - decisions
  /steam-accounts/{steamAccountId}/trading:
    get:
      operationId: RunnerController_getStatus
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RunnerStatusResponseDto'
      tags:
        - trading
  /steam-accounts/{steamAccountId}/trading/diagnostics:
    get:
      operationId: RunnerController_diagnostics
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
      tags:
        - trading
  /steam-accounts/{steamAccountId}/trading/start:
    post:
      operationId: RunnerController_start
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RunnerStartResponseDto'
      tags:
        - trading
  /steam-accounts/{steamAccountId}/trading/stop:
    post:
      operationId: RunnerController_stop
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RunnerStopResponseDto'
      tags:
        - trading
  /steam-accounts/{steamAccountId}/trading/tick:
    post:
      operationId: RunnerController_tick
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RunnerCycleResponseDto'
      tags:
        - trading
  /dashboard:
    get:
      operationId: AccountDashboardController_getOverview
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnerDashboardResponseDto'
      tags:
        - account-dashboard
  /steam-accounts/{steamAccountId}/dashboard:
    get:
      operationId: AccountDashboardController_getDashboard
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountDashboardResponseDto'
      tags:
        - account-dashboard
  /steam-accounts/{steamAccountId}/setup-status:
    get:
      operationId: AccountSetupStatusController_getStatus
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountSetupStatusResponseDto'
      tags:
        - account-setup-status
  /import/stetrade/database/dry-run:
    post:
      operationId: LegacyImportController_dryRunDatabase
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LegacyDatabaseImportDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LegacyDatabaseImportReportDto'
      tags:
        - legacy-import
  /import/stetrade/{steamAccountId}/database/apply:
    post:
      operationId: LegacyImportController_applyDatabase
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LegacyDatabaseImportDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AppliedLegacyDatabaseImportReportDto'
      tags:
        - legacy-import
  /steam-accounts/{steamAccountId}/trading-stats/pnl:
    get:
      operationId: TradingStatsController_getRealizedPnl
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RealizedPnlSummaryDto'
      tags:
        - trading-stats
  /steam-accounts/{steamAccountId}/trading-stats/daily:
    get:
      operationId: TradingStatsController_getDaily
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: days
          required: true
          in: query
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DailyStatsSummaryDto'
      tags:
        - trading-stats
  /steam-accounts/{steamAccountId}/trading-stats/pnl-timeline:
    get:
      operationId: TradingStatsController_getPnlTimeline
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PnlTimelineDto'
      tags:
        - trading-stats
  /steam-accounts/{steamAccountId}/trading-stats/ledger:
    get:
      operationId: TradingStatsController_getLedger
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: limit
          required: true
          in: query
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TradeLedgerRowDto'
      tags:
        - trading-stats
  /steam-accounts/{steamAccountId}/trading-stats/ingest:
    post:
      operationId: TradingStatsController_ingest
      parameters:
        - name: steamAccountId
          required: true
          in: path
          schema:
            type: string
        - name: pages
          required: true
          in: query
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IngestHistoryResponseDto'
      tags:
        - trading-stats
  /portfolio/stats:
    get:
      operationId: PortfolioController_getStats
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PortfolioStatsDto'
      tags:
        - trading-stats
  /portfolio/daily:
    get:
      operationId: PortfolioController_getDaily
      parameters: []
      responses:
        '200':
          description: ''
      tags:
        - trading-stats
info:
  title: SteamMarketRunner API
  description: Operational backend for SteamMarketRunner trading automation.
  version: 0.1.0
  contact: {}
tags: []
servers: []
components:
  securitySchemes:
    api-key:
      type: apiKey
      in: header
      name: x-api-key
  schemas:
    NotificationSettingsResponseDto:
      type: object
      properties:
        enabled:
          type: boolean
        minSeverity:
          type: string
          enum:
            - info
            - warning
            - error
        telegramChatId:
          type: string
          nullable: true
        hasWebhook:
          type: boolean
          description: Whether a webhook URL is configured.
      required:
        - enabled
        - minSeverity
        - telegramChatId
        - hasWebhook
    CurrencyRatesResponseDto:
      type: object
      properties:
        rates:
          type: object
          description: Units of each currency per 1 USD (USD = 1).
          example:
            USD: 1
            RUB: 90
          additionalProperties:
            type: number
        fetchedAt:
          type: string
          nullable: true
      required:
        - rates
        - fetchedAt
    PreferencesResponseDto:
      type: object
      properties:
        displayCurrency:
          type: string
          example: USD
      required:
        - displayCurrency
    AuditEventResponseDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        steamAccountId:
          type: object
          format: uuid
          nullable: true
        appid:
          type: object
          example: 252490
          nullable: true
        category:
          type: string
          example: runner.started
        severity:
          type: string
          enum:
            - debug
            - info
            - warning
            - error
        message:
          type: string
          example: Trading started
        actorType:
          type: object
          example: service_api
          nullable: true
        actorName:
          type: object
          example: openclaw
          nullable: true
        requestId:
          type: object
          example: frontend-request-1
          nullable: true
        data:
          type: object
          additionalProperties: true
        createdAt:
          type: string
          format: date-time
      required:
        - id
        - category
        - severity
        - message
        - data
        - createdAt
    SignupDto:
      type: object
      properties:
        email:
          type: string
          example: tenant@example.com
        password:
          type: string
          writeOnly: true
          example: aStrongPassphrase
          minLength: 12
      required:
        - email
        - password
    OwnerUserDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
          example: admin
      required:
        - id
        - email
    OwnerAuthResponseDto:
      type: object
      properties:
        user:
          $ref: '#/components/schemas/OwnerUserDto'
      required:
        - user
    OwnerLoginDto:
      type: object
      properties:
        email:
          type: string
          example: admin
        password:
          type: string
          writeOnly: true
          example: admin
      required:
        - email
        - password
    PasswordResetRequestDto:
      type: object
      properties:
        email:
          type: string
          example: tenant@example.com
      required:
        - email
    PasswordResetRequestResponseDto:
      type: object
      properties:
        ok:
          type: boolean
          example: true
        token:
          type: string
          description: Only returned in non-production environments for e2e tests.
        expiresAt:
          type: object
          format: date-time
          description: Only returned in non-production environments for e2e tests.
      required:
        - ok
    PasswordResetConfirmDto:
      type: object
      properties:
        token:
          type: string
          example: opaque-token-string
        password:
          type: string
          writeOnly: true
          example: aNewStrongPassphrase
          minLength: 12
      required:
        - token
        - password
    PasswordResetConfirmResponseDto:
      type: object
      properties:
        ok:
          type: boolean
          example: true
      required:
        - ok
    OwnerLogoutResponseDto:
      type: object
      properties:
        ok:
          type: boolean
          example: true
      required:
        - ok
    ServiceActorDto:
      type: object
      properties:
        type:
          type: string
          example: service_api
        name:
          type: string
          example: openclaw
      required:
        - type
        - name
    ServiceAuthCapabilitiesDto:
      type: object
      properties:
        auth:
          type: object
          example:
            actorHeader: x-steammarketrunner-actor
            requestIdHeader: x-request-id
        idempotency:
          type: object
          example:
            header: x-idempotency-key
            decisionEnqueue: true
            runnerStaleJobRecovery: true
            runnerFailedJobRequeue: true
        audit:
          type: object
          example:
            actorAttribution: true
      required:
        - auth
        - idempotency
        - audit
    ServiceAuthResponseDto:
      type: object
      properties:
        actor:
          $ref: '#/components/schemas/ServiceActorDto'
        requestId:
          type: string
          example: openclaw-probe-1
        capabilities:
          $ref: '#/components/schemas/ServiceAuthCapabilitiesDto'
      required:
        - actor
        - requestId
        - capabilities
    ServiceApiKeyDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          example: OpenClaw
        prefix:
          type: string
          example: mops_abc
        lastFour:
          type: string
          example: wxyz
        createdAt:
          type: object
          format: date-time
        updatedAt:
          type: object
          format: date-time
        lastUsedAt:
          type: object
          format: date-time
          nullable: true
        revokedAt:
          type: object
          format: date-time
          nullable: true
      required:
        - id
        - name
        - prefix
        - lastFour
        - createdAt
        - updatedAt
        - lastUsedAt
        - revokedAt
    CreateServiceApiKeyDto:
      type: object
      properties:
        name:
          type: string
          example: OpenClaw
      required:
        - name
    CreatedServiceApiKeyDto:
      type: object
      properties:
        key:
          type: string
          example: mops_plaintext_key
          description: Shown once when the key is created.
        serviceKey:
          $ref: '#/components/schemas/ServiceApiKeyDto'
      required:
        - key
        - serviceKey
    HealthResponseDto:
      type: object
      properties:
        ok:
          type: boolean
          example: true
        service:
          type: string
          example: steammarketrunner-api
      required:
        - ok
        - service
    HealthDependencyDto:
      type: object
      properties:
        ok:
          type: boolean
          example: true
        latencyMs:
          type: number
          example: 2
      required:
        - ok
        - latencyMs
    DeepHealthDependenciesDto:
      type: object
      properties:
        database:
          $ref: '#/components/schemas/HealthDependencyDto'
        redis:
          $ref: '#/components/schemas/HealthDependencyDto'
      required:
        - database
        - redis
    ReadinessResponseDto:
      type: object
      properties:
        ok:
          type: boolean
          example: true
        service:
          type: string
          example: steammarketrunner-api
        status:
          type: string
          enum:
            - ready
            - shutting_down
            - dependency_down
        signal:
          type: string
          example: SIGTERM
        dependencies:
          $ref: '#/components/schemas/DeepHealthDependenciesDto'
      required:
        - ok
        - service
        - status
    ErrorCodeDto:
      type: object
      properties:
        code:
          type: string
          example: VALIDATION_FAILED
        statusCode:
          type: number
          example: 400
        retryable:
          type: boolean
          example: false
      required:
        - code
        - statusCode
        - retryable
    ErrorCodesResponseDto:
      type: object
      properties:
        errorCodes:
          type: array
          items:
            $ref: '#/components/schemas/ErrorCodeDto'
      required:
        - errorCodes
    ApiCapabilityHeadersDto:
      type: object
      properties:
        apiKey:
          type: string
          example: x-api-key
        actor:
          type: string
          example: x-steammarketrunner-actor
        requestId:
          type: string
          example: x-request-id
        idempotencyKey:
          type: string
          example: x-idempotency-key
      required:
        - apiKey
        - actor
        - requestId
        - idempotencyKey
    ApiCapabilityIdempotencyDto:
      type: object
      properties:
        requiredFor:
          type: array
          items:
            type: string
      required:
        - requiredFor
    ApiCapabilityEndpointsDto:
      type: object
      properties:
        read:
          type: array
          items:
            type: string
        mutate:
          type: array
          items:
            type: string
        dangerous:
          type: array
          items:
            type: string
      required:
        - read
        - mutate
        - dangerous
    ApiCapabilitiesResponseDto:
      type: object
      properties:
        headers:
          $ref: '#/components/schemas/ApiCapabilityHeadersDto'
        idempotency:
          $ref: '#/components/schemas/ApiCapabilityIdempotencyDto'
        endpoints:
          $ref: '#/components/schemas/ApiCapabilityEndpointsDto'
      required:
        - headers
        - idempotency
        - endpoints
    TradingLimitsResponseDto:
      type: object
      properties:
        maxCandidatesPerJob:
          type: number
          example: 100
          description: Platform ceiling for per-account "items per cycle".
        minRequestDelayMs:
          type: number
          example: 0
          description: Platform floor (ms) for the per-account delay between Steam actions.
      required:
        - maxCandidatesPerJob
        - minRequestDelayMs
    ApiVersionBuildDto:
      type: object
      properties:
        sha:
          type: string
          example: abc1234
        time:
          type: string
          example: '2026-05-26T10:00:00.000Z'
    ApiVersionResponseDto:
      type: object
      properties:
        service:
          type: string
          example: steammarketrunner-api
        version:
          type: string
          example: 0.0.1
        build:
          $ref: '#/components/schemas/ApiVersionBuildDto'
      required:
        - service
        - version
        - build
    GameResponseDto:
      type: object
      properties:
        appid:
          type: number
          example: 252490
        name:
          type: string
          example: Rust
        defaultContextid:
          type: string
          example: '2'
        moduleKey:
          type: string
          example: rust
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      required:
        - appid
        - name
        - defaultContextid
        - moduleKey
    UpsertSteamAccountSecretsDto:
      type: object
      properties:
        login:
          type: string
          example: steam-login
        password:
          type: string
          writeOnly: true
          example: steam-password
        maFile:
          type: object
          additionalProperties: true
    UpsertProxyProfileDto:
      type: object
      properties:
        protocol:
          type: string
          enum:
            - http
            - https
            - socks4
            - socks5
        host:
          type: string
          example: 127.0.0.1
        port:
          type: number
          example: 8080
          minimum: 1
          maximum: 65535
        username:
          type: string
          example: proxy-user
        password:
          type: string
          writeOnly: true
          example: proxy-password
        expectedIp:
          type: object
          nullable: true
          example: 203.0.113.10
      required:
        - protocol
        - host
        - port
    CreateSteamAccountDto:
      type: object
      properties:
        displayName:
          type: string
          example: Main Steam
        steamId:
          type: string
          example: '76561198000000000'
        secrets:
          $ref: '#/components/schemas/UpsertSteamAccountSecretsDto'
        proxy:
          $ref: '#/components/schemas/UpsertProxyProfileDto'
      required:
        - displayName
    SteamAccountResponseDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        displayName:
          type: string
          example: Main Steam
        steamId:
          type: object
          nullable: true
          example: '76561198000000000'
        status:
          type: string
          enum:
            - draft
            - ready
            - blocked
            - disabled
        sessionState:
          type: object
          additionalProperties: true
        walletBalance:
          type: object
          nullable: true
          example: '10000'
        walletDelayedBalance:
          type: object
          nullable: true
          example: '82'
          description: Steam on-hold (pending) funds, minor units
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      required:
        - id
        - userId
        - displayName
        - status
    UpdateSteamAccountDto:
      type: object
      properties:
        displayName:
          type: string
          example: Main Steam
        steamId:
          type: object
          nullable: true
          example: '76561198000000000'
        status:
          type: string
          enum:
            - draft
            - ready
            - blocked
            - disabled
    SteamAccountSecretsStatusDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        hasLogin:
          type: boolean
          example: true
        hasPassword:
          type: boolean
          example: true
        hasMaFile:
          type: boolean
          example: false
        updatedAt:
          type: string
          format: date-time
      required:
        - steamAccountId
        - hasLogin
        - hasPassword
        - hasMaFile
    ProxyProfileResponseDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        steamAccountId:
          type: string
          format: uuid
        protocol:
          type: string
          enum:
            - http
            - https
            - socks4
            - socks5
        host:
          type: string
          example: 127.0.0.1
        port:
          type: number
          example: 8080
        expectedIp:
          type: object
          nullable: true
          example: 203.0.113.10
        lastStatus:
          type: string
          enum:
            - unknown
            - healthy
            - connection_failed
            - auth_failed
            - ip_changed
        lastLatencyMs:
          type: object
          nullable: true
          example: 123
        hasUsername:
          type: boolean
          example: true
        hasPassword:
          type: boolean
          example: true
        updatedAt:
          type: string
          format: date-time
      required:
        - id
        - steamAccountId
        - protocol
        - host
        - port
        - lastStatus
        - hasUsername
        - hasPassword
    ProxyTestResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - missing_proxy
            - healthy
            - connection_failed
            - auth_failed
            - ip_changed
        statusCode:
          type: number
          example: 200
        expectedIp:
          type: object
          nullable: true
          example: 203.0.113.10
        observedIp:
          type: string
          example: 203.0.113.10
        latencyMs:
          type: number
          example: 123
        proxyUsed:
          type: boolean
          example: true
        message:
          type: string
          example: Proxy test succeeded.
      required:
        - steamAccountId
        - status
        - message
    TradeStateDto:
      type: object
      properties:
        buyEnabled:
          type: boolean
          example: false
        sellEnabled:
          type: boolean
          example: false
        buyPrice:
          type: object
          nullable: true
          example: 1000
        sellNetPrice:
          type: object
          nullable: true
          example: 1200
        sellGrossPrice:
          type: object
          nullable: true
          example: 1400
        currency:
          type: object
          nullable: true
          example: USD
        buyQuantity:
          type: object
          nullable: true
          example: 1
        activeBuyOrderId:
          type: object
          nullable: true
        activeBuyOrderCount:
          type: number
          example: 0
        activeListingCount:
          type: number
          example: 0
        inventoryCount:
          type: number
          example: 1
    CreateMarketItemDto:
      type: object
      properties:
        appid:
          type: number
          example: 252490
        contextid:
          type: string
          example: '2'
        marketHashName:
          type: string
          example: Metal Facemask
        itemNameid:
          type: string
        displayName:
          type: string
        gameMetadata:
          type: object
          additionalProperties: true
        legacyState:
          type: object
          additionalProperties: true
        tradeState:
          $ref: '#/components/schemas/TradeStateDto'
      required:
        - appid
        - contextid
        - marketHashName
    MarketItemResponseDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        steamAccountId:
          type: string
          format: uuid
        catalogItemId:
          type: string
          format: uuid
        groupId:
          type: object
          format: uuid
          nullable: true
        appid:
          type: number
          example: 252490
        contextid:
          type: string
          example: '2'
        marketHashName:
          type: string
          example: Metal Facemask
        itemNameid:
          type: object
          nullable: true
        displayName:
          type: object
          nullable: true
        gameMetadata:
          type: object
          additionalProperties: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      required:
        - id
        - steamAccountId
        - catalogItemId
        - appid
        - contextid
        - marketHashName
        - gameMetadata
    ItemTradeStateResponseDto:
      type: object
      properties:
        buyEnabled:
          type: boolean
          example: false
        sellEnabled:
          type: boolean
          example: false
        buyPrice:
          type: object
          nullable: true
          example: 1000
        sellNetPrice:
          type: object
          nullable: true
          example: 1200
        sellGrossPrice:
          type: object
          nullable: true
          example: 1400
        currency:
          type: object
          nullable: true
          example: USD
        buyQuantity:
          type: object
          nullable: true
          example: 1
        activeBuyOrderId:
          type: object
          nullable: true
        activeBuyOrderCount:
          type: number
          example: 0
        activeListingCount:
          type: number
          example: 0
        inventoryCount:
          type: number
          example: 1
        marketItemId:
          type: string
          format: uuid
        legacyState:
          type: object
          additionalProperties: true
        updatedAt:
          type: string
          format: date-time
      required:
        - marketItemId
        - legacyState
    CreateMarketItemResponseDto:
      type: object
      properties:
        item:
          $ref: '#/components/schemas/MarketItemResponseDto'
        tradeState:
          $ref: '#/components/schemas/ItemTradeStateResponseDto'
      required:
        - item
        - tradeState
    MarketItemsPageResponseDto:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/MarketItemResponseDto'
        page:
          type: number
          example: 1
        pageSize:
          type: number
          example: 100
        pageCount:
          type: number
          example: 18
        total:
          type: number
          example: 1793
      required:
        - items
        - page
        - pageSize
        - pageCount
        - total
    BulkMoveMarketItemsDto:
      type: object
      properties:
        itemIds:
          type: array
          items:
            type: string
            format: uuid
        groupId:
          type: string
          format: uuid
          nullable: true
      required:
        - itemIds
    BulkMoveMarketItemsResponseDto:
      type: object
      properties:
        itemsMoved:
          type: number
          example: 12
        groupId:
          type: string
          format: uuid
          nullable: true
      required:
        - itemsMoved
    BulkDeleteMarketItemsDto:
      type: object
      properties:
        scope:
          type: string
          enum:
            - selected
            - query
          example: selected
        itemIds:
          type: array
          items:
            type: string
            format: uuid
        appid:
          type: number
          example: 252490
        groupId:
          type: string
          format: uuid
          nullable: true
        search:
          type: string
          example: Abyss
        status:
          type: string
          example: eligible
    BulkDeleteMarketItemsResponseDto:
      type: object
      properties:
        itemsDeleted:
          type: number
          example: 12
      required:
        - itemsDeleted
    PatchTradeStateDto:
      type: object
      properties:
        buyEnabled:
          type: boolean
          example: true
        sellEnabled:
          type: boolean
          example: false
        buyQuantity:
          type: object
          nullable: true
          example: 4
    CatalogPriceSnapshotDto:
      type: object
      properties:
        source:
          type: object
          nullable: true
          example: steamwebapi
        currency:
          type: object
          nullable: true
          example: USD
        minPrice:
          type: object
          nullable: true
          example: 196
        maxPrice:
          type: object
          nullable: true
          example: 229
        listingCount:
          type: number
          example: 42
        salesCount:
          type: object
          nullable: true
          example: 310
        coefficient:
          type: object
          nullable: true
          example: 1650
        checkedAt:
          type: string
          format: date-time
          nullable: true
    CatalogItemResponseDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        appid:
          type: number
          example: 252490
        contextid:
          type: string
          example: '2'
        marketHashName:
          type: string
          example: Black Hoodie
        itemNameid:
          type: object
          nullable: true
        displayName:
          type: object
          nullable: true
        gameMetadata:
          type: object
          additionalProperties: true
        isInTradingBase:
          type: boolean
          example: false
        status:
          type: string
          example: eligible
        reason:
          type: string
          example: filters_passed
        profitPercent:
          type: object
          nullable: true
          example: 8.62
        priceSnapshot:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/CatalogPriceSnapshotDto'
        buyPrice:
          type: object
          nullable: true
          example: 156
        sellNetPrice:
          type: object
          nullable: true
          example: 171
        sellGrossPrice:
          type: object
          nullable: true
          example: 196
      required:
        - id
        - appid
        - contextid
        - marketHashName
        - gameMetadata
        - isInTradingBase
        - status
        - reason
    CatalogItemsPageResponseDto:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/CatalogItemResponseDto'
        page:
          type: number
          example: 1
        pageSize:
          type: number
          example: 100
        pageCount:
          type: number
          example: 18
        total:
          type: number
          example: 1793
        currency:
          type: string
          example: USD
      required:
        - items
        - page
        - pageSize
        - pageCount
        - total
        - currency
    ImportInventoryItemsDto:
      type: object
      properties:
        appid:
          type: number
          example: 252490
        contextid:
          type: string
          example: '2'
    ImportInventoryItemsResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        appidsScanned:
          example:
            - 252490
          type: array
          items:
            type: number
        heldDistinct:
          type: number
          example: 10
        matchedCatalogItems:
          type: number
          example: 10
        itemsAdded:
          type: number
          example: 6
        alreadyPresent:
          type: number
          example: 4
        notInCatalog:
          type: array
          items:
            type: string
      required:
        - steamAccountId
        - appidsScanned
        - heldDistinct
        - matchedCatalogItems
        - itemsAdded
        - alreadyPresent
        - notInCatalog
    AddCatalogItemsToAccountDto:
      type: object
      properties:
        mode:
          type: string
          enum:
            - eligible
            - all
          example: eligible
        appid:
          type: number
          example: 252490
        groupId:
          type: string
          format: uuid
        limit:
          type: number
          example: 500
        offset:
          type: number
          example: 0
        priceMin:
          type: number
          example: 0.5
        priceMax:
          type: number
          example: 10
        salesPerDayMin:
          type: number
          example: 3
        salesPerDayMax:
          type: number
          example: 50
        excludeWeapons:
          type: boolean
          example: true
        excludeStickersPatches:
          type: boolean
          example: true
        excludeSouvenirs:
          type: boolean
          example: true
        excludeAgents:
          type: boolean
          example: true
        excludeGraffiti:
          type: boolean
          example: true
        excludeCharms:
          type: boolean
          example: true
        excludeCasesKeysToolsOther:
          type: boolean
          example: true
        catalogItemIds:
          type: array
          items:
            type: string
            format: uuid
    AddCatalogItemsToAccountResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        catalogItemsScanned:
          type: number
          example: 128
        eligible:
          type: number
          example: 83
        itemsAdded:
          type: number
          example: 70
        alreadyPresent:
          type: number
          example: 13
        rejected:
          type: number
          example: 45
        skippedByLimit:
          type: number
          example: 0
        reasons:
          type: object
          additionalProperties: true
      required:
        - steamAccountId
        - catalogItemsScanned
        - eligible
        - itemsAdded
        - alreadyPresent
        - rejected
        - skippedByLimit
        - reasons
    Object:
      type: object
      properties: {}
    RuntimeSettingsResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        settings:
          type: object
          additionalProperties: true
        legacySettings:
          type: object
          additionalProperties: true
        updatedAt:
          type: string
          format: date-time
      required:
        - steamAccountId
        - settings
        - legacySettings
    StrategyProfileResponseDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        steamAccountId:
          type: string
          format: uuid
        name:
          type: string
          example: Default sell strategy
        algorithm:
          type: string
          example: AVG
        algorithmBuy:
          type: string
          example: AVG
        settings:
          type: object
          additionalProperties: true
        legacyAliases:
          type: object
          additionalProperties: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      required:
        - id
        - steamAccountId
        - name
        - algorithm
        - algorithmBuy
        - settings
        - legacyAliases
    ImportLegacySettingsResponseDto:
      type: object
      properties:
        runtimeSettings:
          $ref: '#/components/schemas/RuntimeSettingsResponseDto'
        strategyProfile:
          $ref: '#/components/schemas/StrategyProfileResponseDto'
        importedKeys:
          type: number
          example: 82
        runtimeKeys:
          type: array
          items:
            type: string
        strategyKeys:
          type: array
          items:
            type: string
      required:
        - runtimeSettings
        - strategyProfile
        - importedKeys
        - runtimeKeys
        - strategyKeys
    ImportListingsSnapshotDto:
      type: object
      properties:
        currency:
          type: object
          additionalProperties: true
        listings:
          type: array
          items:
            type: object
      required:
        - listings
    ImportListingsSnapshotResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        listingsProcessed:
          type: number
          example: 614
        uniqueItems:
          type: number
          example: 200
        itemsUpserted:
          type: number
          example: 200
        catalogItemsUpserted:
          type: number
          example: 200
        priceSnapshotsCreated:
          type: number
          example: 200
      required:
        - steamAccountId
        - listingsProcessed
        - uniqueItems
        - itemsUpserted
        - catalogItemsUpserted
        - priceSnapshotsCreated
    CreateGroupDto:
      type: object
      properties:
        appid:
          type: number
          example: 252490
        name:
          type: string
          example: High volume skins
        legacyGroupId:
          type: string
          example: legacy-group-1
        sortOrder:
          type: number
          example: 0
        metadata:
          type: object
          additionalProperties: true
      required:
        - appid
        - name
    ItemGroupResponseDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        steamAccountId:
          type: string
          format: uuid
        appid:
          type: number
          example: 252490
        name:
          type: string
          example: High volume skins
        legacyGroupId:
          type: object
          nullable: true
          example: legacy-group-1
        sortOrder:
          type: number
          example: 0
        metadata:
          type: object
          additionalProperties: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      required:
        - id
        - steamAccountId
        - appid
        - name
        - sortOrder
        - metadata
    UpdateGroupDto:
      type: object
      properties:
        name:
          type: string
          example: High volume skins
        sortOrder:
          type: number
          example: 0
        metadata:
          type: object
          additionalProperties: true
    DeleteGroupResponseDto:
      type: object
      properties:
        groupId:
          type: string
          format: uuid
        itemsDeleted:
          type: number
          example: 42
        groupDeleted:
          type: boolean
          example: true
      required:
        - groupId
        - itemsDeleted
        - groupDeleted
    CreateStrategyProfileDto:
      type: object
      properties:
        name:
          type: string
          example: Default sell strategy
        algorithm:
          type: string
          example: AVG
        algorithmBuy:
          type: string
          example: AVG
        settings:
          type: object
          additionalProperties: true
        legacyAliases:
          type: object
          additionalProperties: true
      required:
        - name
    UpsertRuntimeSettingsDto:
      type: object
      properties:
        settings:
          type: object
          additionalProperties: true
        legacySettings:
          type: object
          additionalProperties: true
    DecisionJobResponseDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        steamAccountId:
          type: string
          format: uuid
        appid:
          type: object
          example: 252490
          nullable: true
        type:
          type: string
          enum:
            - buy_analysis
            - sell_analysis
            - maintenance_low_profit
            - maintenance_reprice
            - maintenance_cancel_orders
            - maintenance_remove_listings
            - maintenance_competitor_removal
            - steam_session_health
            - steam_market_state_sync
            - steam_confirm_pending
            - trading_stats_ingest
        status:
          type: string
          enum:
            - queued
            - running
            - succeeded
            - failed
            - cancelled
        priority:
          type: number
          example: 0
        payload:
          type: object
          additionalProperties: true
        attempts:
          type: number
          example: 0
        lastError:
          type: object
          nullable: true
        scheduledAt:
          type: string
          format: date-time
        startedAt:
          type: string
          nullable: true
          format: date-time
        finishedAt:
          type: string
          nullable: true
          format: date-time
      required:
        - id
        - steamAccountId
        - type
        - status
        - priority
        - payload
        - attempts
    DecisionJobAuditSummaryDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        category:
          type: string
          example: decision.job_succeeded
        severity:
          type: string
          example: info
        createdAt:
          type: string
          format: date-time
      required:
        - id
        - category
        - severity
        - createdAt
    DecisionJobResultResponseDto:
      type: object
      properties:
        job:
          $ref: '#/components/schemas/DecisionJobResponseDto'
        audit:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/DecisionJobAuditSummaryDto'
        result:
          type: object
          nullable: true
          additionalProperties: true
        error:
          type: object
          additionalProperties: true
      required:
        - job
        - audit
        - result
    EnqueueDecisionJobResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        appid:
          type: object
          example: 252490
          nullable: true
        type:
          type: string
          enum:
            - buy_analysis
            - sell_analysis
            - maintenance_low_profit
            - maintenance_reprice
            - maintenance_cancel_orders
            - maintenance_remove_listings
            - maintenance_competitor_removal
            - steam_session_health
            - steam_market_state_sync
            - steam_confirm_pending
            - trading_stats_ingest
        jobQueueId:
          type: string
          format: uuid
        bullJobId:
          type: object
          nullable: true
          example: bull-job-1
        status:
          type: string
          enum:
            - queued
            - running
            - succeeded
            - failed
            - cancelled
      required:
        - steamAccountId
        - type
        - jobQueueId
        - bullJobId
        - status
    RunnerSettingsDto:
      type: object
      properties:
        appid:
          type: number
          example: 252490
        dryRun:
          type: boolean
          example: true
        runnerJobs:
          example:
            - sell_analysis
          type: array
          items:
            type: string
      required:
        - dryRun
        - runnerJobs
    RunnerSafetyDto:
      type: object
      properties:
        allowed:
          type: boolean
          example: true
        reasons:
          type: array
          items:
            type: string
      required:
        - allowed
        - reasons
    ResolvedRunnerJobDto:
      type: object
      properties:
        type:
          type: string
          example: sell_analysis
        cadenceMs:
          type: number
          example: 300000
        lastScheduledAt:
          type: string
          format: date-time
      required:
        - type
        - cadenceMs
    RunnerDueJobsDto:
      type: object
      properties:
        due:
          type: array
          items:
            $ref: '#/components/schemas/ResolvedRunnerJobDto'
        skipped:
          type: array
          items:
            $ref: '#/components/schemas/ResolvedRunnerJobDto'
      required:
        - due
        - skipped
    RunnerStatusResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        status:
          type: string
          example: running
        currentJob:
          type: object
          nullable: true
          example: cycle_dispatch
        blockedReason:
          type: object
          nullable: true
          example: null
        microbanUntil:
          type: string
          nullable: true
          format: date-time
        throttleState:
          type: object
          additionalProperties: true
        settings:
          $ref: '#/components/schemas/RunnerSettingsDto'
        safety:
          $ref: '#/components/schemas/RunnerSafetyDto'
        jobs:
          $ref: '#/components/schemas/RunnerDueJobsDto'
      required:
        - steamAccountId
        - status
        - currentJob
        - blockedReason
        - microbanUntil
        - throttleState
        - settings
        - safety
        - jobs
    QueuedRunnerJobDto:
      type: object
      properties:
        type:
          type: string
          example: sell_analysis
        jobQueueId:
          type: string
          format: uuid
        bullJobId:
          type: object
          nullable: true
          example: bull-job-1
      required:
        - type
        - jobQueueId
        - bullJobId
    RunnerStartResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        queuedJobs:
          type: array
          items:
            $ref: '#/components/schemas/QueuedRunnerJobDto'
        blockedReason:
          type: string
          example: account_not_ready
        status:
          type: string
          example: running
        currentJob:
          type: object
          nullable: true
          example: cycle_dispatch
      required:
        - steamAccountId
        - queuedJobs
        - status
        - currentJob
    RunnerStopResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        status:
          type: string
          example: stopped
        currentJob:
          type: object
          nullable: true
          example: null
        blockedReason:
          type: object
          nullable: true
          example: null
      required:
        - steamAccountId
        - status
        - currentJob
        - blockedReason
    RunnerCycleResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        queuedJobs:
          type: array
          items:
            $ref: '#/components/schemas/QueuedRunnerJobDto'
        blockedReason:
          type: string
          example: account_not_ready
      required:
        - steamAccountId
        - queuedJobs
    OwnerDashboardStatusCountsDto:
      type: object
      properties:
        draft:
          type: number
          example: 1
        ready:
          type: number
          example: 3
        blocked:
          type: number
          example: 1
        disabled:
          type: number
          example: 0
      required:
        - draft
        - ready
        - blocked
        - disabled
    OwnerDashboardSummaryDto:
      type: object
      properties:
        totalAccounts:
          type: number
          example: 5
        statuses:
          $ref: '#/components/schemas/OwnerDashboardStatusCountsDto'
        needsAttention:
          type: number
          example: 2
        totalBalanceByCurrency:
          type: object
          additionalProperties:
            type: number
          example:
            USD: 12345
        totalHeldByCurrency:
          type: object
          additionalProperties:
            type: number
          example:
            USD: 82
          description: Steam on-hold (pending) funds per currency
        totalInventoryValueByCurrency:
          type: object
          additionalProperties:
            type: number
          example:
            USD: 6789
        totalOnSaleValueByCurrency:
          type: object
          additionalProperties:
            type: number
          example:
            USD: 4321
        totalOnOrdersValueByCurrency:
          type: object
          additionalProperties:
            type: number
          example:
            USD: 4321
        totalNetWorthByCurrency:
          type: object
          additionalProperties:
            type: number
          example:
            USD: 24316
          description: Wallet + held + inventory + on-sale + on-orders per currency
        totalActiveBuyOrders:
          type: number
          example: 12
      required:
        - totalAccounts
        - statuses
        - needsAttention
        - totalBalanceByCurrency
        - totalHeldByCurrency
        - totalInventoryValueByCurrency
        - totalOnSaleValueByCurrency
        - totalOnOrdersValueByCurrency
        - totalNetWorthByCurrency
        - totalActiveBuyOrders
    DecisionJobStatusCountsDto:
      type: object
      properties:
        queued:
          type: number
          example: 3
        running:
          type: number
          example: 1
        succeeded:
          type: number
          example: 10
        failed:
          type: number
          example: 2
        cancelled:
          type: number
          example: 0
      required:
        - queued
        - running
        - succeeded
        - failed
        - cancelled
    DecisionJobsSummaryResponseDto:
      type: object
      properties:
        total:
          type: number
          example: 16
        counts:
          $ref: '#/components/schemas/DecisionJobStatusCountsDto'
      required:
        - total
        - counts
    OwnerDashboardInventoryDto:
      type: object
      properties:
        count:
          type: number
          example: 12
        valueMinor:
          type: object
          example: 6789
          nullable: true
        currency:
          type: object
          example: USD
          nullable: true
      required:
        - count
        - valueMinor
        - currency
    OwnerDashboardOnSaleDto:
      type: object
      properties:
        valueMinor:
          type: object
          example: 4321
          nullable: true
        currency:
          type: object
          example: USD
          nullable: true
        count:
          type: number
          example: 7
          description: Items currently listed for sale
      required:
        - valueMinor
        - currency
        - count
    OwnerDashboardOnOrdersDto:
      type: object
      properties:
        valueMinor:
          type: object
          example: 4321
          nullable: true
        currency:
          type: object
          example: USD
          nullable: true
        count:
          type: number
          example: 5
          description: Number of active buy orders
        quantity:
          type: number
          example: 10
          description: Items being bought across orders
      required:
        - valueMinor
        - currency
        - count
        - quantity
    OwnerDashboardHealthDto:
      type: object
      properties:
        blockedReason:
          type: object
          nullable: true
          example: session_expired
        microbanUntil:
          type: string
          nullable: true
          format: date-time
        buyPausedUntil:
          type: string
          nullable: true
          format: date-time
        lastContactAt:
          type: string
          nullable: true
          format: date-time
      required:
        - blockedReason
        - microbanUntil
        - buyPausedUntil
        - lastContactAt
    OwnerDashboardAccountCheckDto:
      type: object
      properties:
        key:
          type: string
          example: proxy
        status:
          type: string
          example: ok
          enum:
            - ok
            - error
            - warning
            - unknown
      required:
        - key
        - status
    OwnerDashboardAccountDto:
      type: object
      properties:
        account:
          $ref: '#/components/schemas/SteamAccountResponseDto'
        runnerStatus:
          type: string
          example: running
        proxyStatus:
          type: string
          example: healthy
        safety:
          $ref: '#/components/schemas/RunnerSafetyDto'
        jobsSummary:
          $ref: '#/components/schemas/DecisionJobsSummaryResponseDto'
        setupComplete:
          type: boolean
          example: true
        missingSetupSteps:
          type: array
          items:
            type: string
        readyForDryRun:
          type: boolean
          example: true
        readyForLiveRun:
          type: boolean
          example: false
        attentionReasons:
          type: array
          items:
            type: string
        inventory:
          $ref: '#/components/schemas/OwnerDashboardInventoryDto'
        onSale:
          $ref: '#/components/schemas/OwnerDashboardOnSaleDto'
        onOrders:
          $ref: '#/components/schemas/OwnerDashboardOnOrdersDto'
        health:
          $ref: '#/components/schemas/OwnerDashboardHealthDto'
        checks:
          type: array
          items:
            $ref: '#/components/schemas/OwnerDashboardAccountCheckDto'
      required:
        - account
        - runnerStatus
        - proxyStatus
        - safety
        - jobsSummary
        - setupComplete
        - missingSetupSteps
        - readyForDryRun
        - readyForLiveRun
        - attentionReasons
        - inventory
        - onSale
        - onOrders
        - health
        - checks
    OwnerDashboardResponseDto:
      type: object
      properties:
        generatedAt:
          type: string
          format: date-time
        summary:
          $ref: '#/components/schemas/OwnerDashboardSummaryDto'
        accounts:
          type: array
          items:
            $ref: '#/components/schemas/OwnerDashboardAccountDto'
      required:
        - generatedAt
        - summary
        - accounts
    AccountDashboardResponseDto:
      type: object
      properties:
        generatedAt:
          type: string
          format: date-time
        account:
          $ref: '#/components/schemas/SteamAccountResponseDto'
        proxy:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/ProxyProfileResponseDto'
        runner:
          $ref: '#/components/schemas/RunnerStatusResponseDto'
        jobs:
          type: array
          items:
            $ref: '#/components/schemas/DecisionJobResponseDto'
        auditEvents:
          type: array
          items:
            $ref: '#/components/schemas/AuditEventResponseDto'
      required:
        - generatedAt
        - account
        - proxy
        - runner
        - jobs
        - auditEvents
    SessionCredentialStatusDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        hasSessionId:
          type: boolean
          example: true
        hasCookie:
          type: boolean
          example: true
        updatedAt:
          type: string
          nullable: true
          format: date-time
      required:
        - steamAccountId
        - hasSessionId
        - hasCookie
        - updatedAt
    AccountSetupStatusResponseDto:
      type: object
      properties:
        steamAccountId:
          type: string
          format: uuid
        generatedAt:
          type: string
          format: date-time
        account:
          $ref: '#/components/schemas/SteamAccountResponseDto'
        secrets:
          $ref: '#/components/schemas/SteamAccountSecretsStatusDto'
        sessionCredentials:
          $ref: '#/components/schemas/SessionCredentialStatusDto'
        proxy:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/ProxyProfileResponseDto'
        runnerSafety:
          $ref: '#/components/schemas/RunnerSafetyDto'
        missingSteps:
          type: array
          items:
            type: string
        blockingReasons:
          type: array
          items:
            type: string
        setupComplete:
          type: boolean
          example: false
        readyForDryRun:
          type: boolean
          example: true
        readyForLiveRun:
          type: boolean
          example: false
      required:
        - steamAccountId
        - generatedAt
        - account
        - secrets
        - sessionCredentials
        - proxy
        - runnerSafety
        - missingSteps
        - blockingReasons
        - setupComplete
        - readyForDryRun
        - readyForLiveRun
    LegacyDatabaseImportDto:
      type: object
      properties:
        items:
          type: object
          additionalProperties: true
        groups:
          type: object
          additionalProperties: true
        group_settings:
          type: object
          additionalProperties: true
        config:
          type: object
          additionalProperties: true
    LegacyImportWarningDto:
      type: object
      properties:
        severity:
          type: string
          enum:
            - info
            - warning
            - error
        code:
          type: string
          example: unknown_store
        message:
          type: string
          example: Unsupported legacy store preserved in report.
        path:
          type: string
          example: items.0
      required:
        - severity
        - code
        - message
    LegacyDatabaseImportReportDto:
      type: object
      properties:
        sourceType:
          type: string
          enum:
            - indexeddb-json
            - unknown
        recordsRead:
          type: number
          example: 42
        recordsImported:
          type: number
          example: 3
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/LegacyImportWarningDto'
        sampleKeys:
          example:
            - items
            - config
          type: array
          items:
            type: string
        items:
          type: array
          items:
            $ref: '#/components/schemas/CreateMarketItemDto'
        groups:
          type: array
          items:
            $ref: '#/components/schemas/CreateGroupDto'
        strategyProfiles:
          type: array
          items:
            $ref: '#/components/schemas/CreateStrategyProfileDto'
        runtimeSettings:
          $ref: '#/components/schemas/UpsertRuntimeSettingsDto'
      required:
        - sourceType
        - recordsRead
        - recordsImported
        - warnings
        - sampleKeys
        - items
        - groups
        - strategyProfiles
    AppliedLegacyImportCountsDto:
      type: object
      properties:
        groups:
          type: number
          example: 1
        strategyProfiles:
          type: number
          example: 1
        items:
          type: number
          example: 1
        runtimeSettings:
          type: number
          example: 1
        mode:
          type: string
          example: upsert
      required:
        - groups
        - strategyProfiles
        - items
        - runtimeSettings
        - mode
    AppliedLegacyDatabaseImportReportDto:
      type: object
      properties:
        sourceType:
          type: string
          enum:
            - indexeddb-json
            - unknown
        recordsRead:
          type: number
          example: 42
        recordsImported:
          type: number
          example: 3
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/LegacyImportWarningDto'
        sampleKeys:
          example:
            - items
            - config
          type: array
          items:
            type: string
        items:
          type: array
          items:
            $ref: '#/components/schemas/CreateMarketItemDto'
        groups:
          type: array
          items:
            $ref: '#/components/schemas/CreateGroupDto'
        strategyProfiles:
          type: array
          items:
            $ref: '#/components/schemas/CreateStrategyProfileDto'
        runtimeSettings:
          $ref: '#/components/schemas/UpsertRuntimeSettingsDto'
        imported:
          $ref: '#/components/schemas/AppliedLegacyImportCountsDto'
      required:
        - sourceType
        - recordsRead
        - recordsImported
        - warnings
        - sampleKeys
        - items
        - groups
        - strategyProfiles
        - imported
    RealizedPnlTotalsDto:
      type: object
      properties:
        buyCount:
          type: number
          example: 19
        sellCount:
          type: number
          example: 12
        totalSpent:
          type: number
          example: 1240
        grossProceeds:
          type: number
          example: 1500
        netProceeds:
          type: number
          example: 1300
        feesPaid:
          type: number
          example: 200
        realizedPnl:
          type: number
          example: 60
        proceedsWithoutCostBasis:
          type: number
          example: 0
        closedTrades:
          type: number
          example: 12
        winRate:
          type: object
          example: 0.66
          nullable: true
        avgHoldDays:
          type: object
          example: 2.4
          nullable: true
        roi:
          type: object
          example: 8.5
          nullable: true
        openPositionCost:
          type: number
          example: 1500
          description: Cost basis of open (unsold) lots, minor units.
        openPositionValue:
          type: number
          example: 1720
          description: Current value of open lots at latest snapshot price, minor units.
        unrealizedPnl:
          type: number
          example: 220
          description: Unrealized P&L on open positions, minor units.
      required:
        - buyCount
        - sellCount
        - totalSpent
        - grossProceeds
        - netProceeds
        - feesPaid
        - realizedPnl
        - proceedsWithoutCostBasis
        - closedTrades
        - winRate
        - avgHoldDays
        - roi
        - openPositionCost
        - openPositionValue
        - unrealizedPnl
    RealizedPnlItemDto:
      type: object
      properties:
        marketHashName:
          type: string
          example: Blue Hoodie
        appid:
          type: object
          example: 252490
          nullable: true
        buyQuantity:
          type: number
          example: 4
        sellQuantity:
          type: number
          example: 3
        totalSpent:
          type: number
          example: 40
        totalProceeds:
          type: number
          example: 33
        feesPaid:
          type: number
          example: 5
        realizedPnl:
          type: object
          example: 3
          nullable: true
      required:
        - marketHashName
        - appid
        - buyQuantity
        - sellQuantity
        - totalSpent
        - totalProceeds
        - feesPaid
        - realizedPnl
    RealizedPnlSummaryDto:
      type: object
      properties:
        currency:
          type: string
          example: USD
        totals:
          $ref: '#/components/schemas/RealizedPnlTotalsDto'
        items:
          type: array
          items:
            $ref: '#/components/schemas/RealizedPnlItemDto'
      required:
        - currency
        - totals
        - items
    DailyStatRowDto:
      type: object
      properties:
        date:
          type: string
          example: '2026-01-21'
        walletBalance:
          type: number
          example: 23746
        held:
          type: number
          example: 0
        onSaleValue:
          type: number
          example: 82382
        inventoryValue:
          type: number
          example: 0
        onOrdersValue:
          type: number
          example: 0
        netWorth:
          type: number
          example: 106128
        profit:
          type: object
          example: 785
          nullable: true
        profitPercent:
          type: object
          example: 0.74
          nullable: true
      required:
        - date
        - walletBalance
        - held
        - onSaleValue
        - inventoryValue
        - onOrdersValue
        - netWorth
        - profit
        - profitPercent
    DailyStatsSummaryDto:
      type: object
      properties:
        currency:
          type: string
          example: USD
        rows:
          type: array
          items:
            $ref: '#/components/schemas/DailyStatRowDto'
      required:
        - currency
        - rows
    PnlTimelinePointDto:
      type: object
      properties:
        date:
          type: string
          example: '2026-01-22'
        realized:
          type: number
          example: 785
        cumulative:
          type: number
          example: 1240
      required:
        - date
        - realized
        - cumulative
    PnlTimelineDto:
      type: object
      properties:
        currency:
          type: string
          example: USD
        points:
          type: array
          items:
            $ref: '#/components/schemas/PnlTimelinePointDto'
      required:
        - currency
        - points
    TradeLedgerRowDto:
      type: object
      properties:
        id:
          type: string
        marketHashName:
          type: string
          example: Blue Hoodie
        side:
          type: string
          example: buy
          enum:
            - buy
            - sell
        quantity:
          type: number
          example: 1
        unitPrice:
          type: number
          example: 13
        fee:
          type: number
          example: 0
        net:
          type: number
          example: 13
        currency:
          type: object
          example: USD
          nullable: true
        source:
          type: string
          example: myhistory
        occurredAt:
          type: string
          format: date-time
      required:
        - id
        - marketHashName
        - side
        - quantity
        - unitPrice
        - fee
        - net
        - currency
        - source
        - occurredAt
    IngestHistoryResponseDto:
      type: object
      properties:
        ok:
          type: boolean
          example: true
        fetched:
          type: number
          example: 200
        ingested:
          type: number
          example: 37
      required:
        - ok
        - fetched
        - ingested
    PortfolioCurrencyStatsDto:
      type: object
      properties:
        currency:
          type: string
          example: USD
        accounts:
          type: number
          example: 3
        realizedPnl:
          type: number
          description: Realized P&L summed across accounts, minor units.
        unrealizedPnl:
          type: number
          description: Unrealized P&L summed across accounts, minor units.
        totalPnl:
          type: number
          description: realized + unrealized, minor units.
        netWorth:
          type: number
          description: Combined net worth, minor units.
        totalSpent:
          type: number
          description: Summed cost basis spent, minor units.
        netProceeds:
          type: number
          description: Summed net proceeds, minor units.
        feesPaid:
          type: number
          description: Summed fees paid, minor units.
        openPositionValue:
          type: number
          description: Summed open-position market value, minor units.
        openPositionCost:
          type: number
          description: Summed open-position cost basis, minor units.
        closedTrades:
          type: number
          description: Total closed trades across accounts.
        roi:
          type: object
          nullable: true
          description: ROI % recomputed from summed realized/spent.
        winRate:
          type: object
          nullable: true
          description: Win rate 0..1, count-weighted.
        avgHoldDays:
          type: object
          nullable: true
          description: Avg hold days, count-weighted.
      required:
        - currency
        - accounts
        - realizedPnl
        - unrealizedPnl
        - totalPnl
        - netWorth
        - totalSpent
        - netProceeds
        - feesPaid
        - openPositionValue
        - openPositionCost
        - closedTrades
        - roi
        - winRate
        - avgHoldDays
    PortfolioAccountStatsDto:
      type: object
      properties:
        steamAccountId:
          type: string
        displayName:
          type: string
        currency:
          type: string
          example: USD
        netWorth:
          type: number
        realizedPnl:
          type: number
        unrealizedPnl:
          type: number
        totalPnl:
          type: number
        roi:
          type: object
          nullable: true
      required:
        - steamAccountId
        - displayName
        - currency
        - netWorth
        - realizedPnl
        - unrealizedPnl
        - totalPnl
        - roi
    PortfolioStatsDto:
      type: object
      properties:
        accountCount:
          type: number
          example: 4
        byCurrency:
          type: array
          items:
            $ref: '#/components/schemas/PortfolioCurrencyStatsDto'
        accounts:
          type: array
          items:
            $ref: '#/components/schemas/PortfolioAccountStatsDto'
      required:
        - accountCount
        - byCurrency
        - accounts
