Shop It Docs
Developer Resourcestraining

Training Module API & Integration Guide

Full admin and customer/mobile API contract for training, session, cohort, waitlist, and enrollment flows.

Training - API & Integration Guide

Audience: Admin-panel developers, mobile/web client developers, backend integrators
Scope: Auth model, endpoints, DTO contracts, enums, business rules, and integration recipes.

1. How to Read / Quick Metadata

  • Module: Training
  • Auth models:
    • Admin routes: JwtAuthGuard + RoleGuard + @Permissions(...)
    • Customer/mobile routes: JwtAuthGuard
  • Primary base URLs:
    • Admin training: /api/admin/training
    • Admin sessions: /api/admin/training/:trainingId/sessions
    • Admin cohorts: /api/admin/training/:trainingId/cohorts
    • Admin enrollments: /api/admin/training/enrollments
    • Customer discovery: /api/trainings
    • Mobile-composed discovery: /api/mobile/trainings
    • Customer enrollment/access: /api/training
    • Mobile-composed enrollment/access: /api/mobile/training
  • Response envelope: all successful endpoints return ResponseDto<T>
  • Swagger tags used by controllers:
    • Training (Admin)
    • Training Session (Admin)
    • Training Cohort (Admin)
    • Training Enrollment (Admin)
    • Training Discovery
    • Training Enrollment

2. High-Level Overview

Training module manages:

  • training metadata and publication lifecycle,
  • training sessions,
  • cohorts with capacity/waitlist,
  • user enrollments and enrollment access fields,
  • session access at runtime.

Commerce integration model:

  • Training enrollment request creates pending enrollment + training order/payment intent synchronously.
  • API returns payment-init payload immediately for gateway handoff.
  • Payment success finalizes enrollment (status = "enrolled") and sets access fields.

Training products bypass cart.

3. Core Concepts and Terminology

  • training: Content metadata for a training product.
  • training_session: Session entity linked to the training's product ID.
  • training_cohort: Capacity-based batch for a training.
  • training_cohort_session: Cohort-specific schedule overrides per session.
  • training_enrollment: User enrollment state (pending, enrolled, cancelled).
    • DB constraint: only one enrolled row per (user_id, product_id) via partial unique index.
    • Compatibility rule: pending rows may exist with orderId = null during pre-payment lifecycle.
  • training_enrollment_form_config: Optional structured form schema per training.
  • training_waitlist: Overflow queue for full cohorts.
  • product_access: Entitlement row used across digital products.

Key state fields:

  • training.status: draft | published | hidden | archived
  • training_session.status: scheduled | live | completed | cancelled
  • training_cohort.status: open | closed | full | cancelled
  • training_waitlist.status: waiting | promoted | expired | cancelled
  • training_enrollment.status: pending | enrolled | cancelled

4. Route Summary

4.1 Admin training endpoints

MethodPathPermissionRequest DTOResponse DTO
GET/api/admin/trainingTraining_READFetchTrainingDtoTrainingListItemDto[] (paginated)
GET/api/admin/training/:idTraining_READpath idTrainingResponseDto
POST/api/admin/trainingTraining_CREATECreateTrainingDtoTrainingResponseDto
PATCH/api/admin/training/:idTraining_UPDATEUpdateTrainingDtoTrainingResponseDto
POST/api/admin/training/:id/trailerTraining_UPDATEmultipart fileTrainingResponseDto
DELETE/api/admin/training/:id/trailerTraining_UPDATEpath idTrainingResponseDto
DELETE/api/admin/training/:idTraining_DELETEpath idTrainingDeleteResponseDto
GET/api/admin/training/:id/form-configTraining_READpath idTrainingFormConfigDto | null
PUT/api/admin/training/:id/form-configTraining_UPDATEUpdateFormConfigDtoTrainingFormConfigDto

4.2 Admin session endpoints

MethodPathPermission
GET/api/admin/training/:trainingId/sessionsTraining_READ
POST/api/admin/training/:trainingId/sessionsTraining_SESSION_CREATE
PUT/api/admin/training/:trainingId/sessions/reorderTraining_SESSION_UPDATE
GET/api/admin/training/:trainingId/sessions/:sessionIdTraining_READ
PATCH/api/admin/training/:trainingId/sessions/:sessionIdTraining_SESSION_UPDATE
PATCH/api/admin/training/:trainingId/sessions/:sessionId/recordingTraining_SESSION_UPDATE
DELETE/api/admin/training/:trainingId/sessions/:sessionIdTraining_SESSION_DELETE

4.3 Admin cohort and waitlist endpoints

MethodPathPermission
GET/api/admin/training/:trainingId/cohortsTraining_READ
POST/api/admin/training/:trainingId/cohortsTraining_Cohort_CREATE
GET/api/admin/training/:trainingId/cohorts/:cohortIdTraining_READ
PATCH/api/admin/training/:trainingId/cohorts/:cohortIdTraining_Cohort_UPDATE
DELETE/api/admin/training/:trainingId/cohorts/:cohortIdTraining_Cohort_DELETE
PUT/api/admin/training/:trainingId/cohorts/:cohortId/sessionsTraining_Cohort_UPDATE
GET/api/admin/training/:trainingId/cohorts/:cohortId/waitlistTraining_READ
POST/api/admin/training/:trainingId/cohorts/:cohortId/waitlist/:waitlistId/promoteTraining_Cohort_UPDATE

4.4 Admin enrollment endpoints

MethodPathPermissionNotes
GET/api/admin/training/enrollmentsTraining_READfilters + pagination/sort
GET/api/admin/training/enrollments/:idTraining_READenriched enrollment detail
PATCH/api/admin/training/enrollments/:id/statusTraining_UPDATEadjusts cohort counters on transitions

4.5 Customer/mobile endpoints

MethodPathRequest DTOResponse DTO
POST/api/mobile/training/enrollEnrollTrainingDtoPaymentInitResponseDto
GET/api/mobile/training/enrollmentsQueryDtoTrainingEnrollmentResponseDto[] (paginated)
GET/api/mobile/training/enrollments/:idpath idTrainingEnrollmentResponseDto
GET/api/mobile/training/cohorts/:cohortIdpath cohortIdCohortEnrollmentDetailDto
GET/api/mobile/training/sessions/:sessionIdpath sessionIdSessionEnrollmentDetailDto
GET/api/mobile/training/:trainingId/sessionspath trainingIdSessionListItemDto[]
GET/api/mobile/training/:trainingId/sessions/:sessionId/contentpath paramsSessionContentResponseDto
POST/api/mobile/training/enrollments/:id/request-cancellationRequestCancellationDtoEnrollmentCancellationResponseDto
GET/api/mobile/trainingsTrainingListQueryDtoTrainingListItemDto[] (paginated)
GET/api/mobile/trainings/featuredTrainingListQueryDtoTrainingListItemDto[] (paginated)

Same controllers are also available on non-mobile customer prefixes (/api/training/*, /api/trainings/*).

4.6 Trailer contract notes

  • trailerRef is the canonical storage key persisted on training.trailerRef
  • trailerUrl is resolved by backend reads and should be used directly for playback
  • Discovery list and featured responses now expose both fields via TrainingListItemDto
  • Admin clients may still write trailerRef through PATCH /api/admin/training/:id, but dedicated upload/clear routes are preferred for backend-managed cleanup semantics

5. Query Parameters

5.1 Shared base query (QueryDto)

ParamTypeDefaultNotes
paginationbooleantruetoggles count/page/size metadata and DB limit/offset
pagenumber1minimum 1
sizenumber20minimum 1, capped by PaginationUtil
sortstringupdatedAtendpoint-specific allowed values
orderasc | descdescascending/descending
searchstringoptionaltrimmed string search

5.2 Admin training list (FetchTrainingDto)

Additional filters:

  • status: draft \| published \| hidden \| archived
  • categoryId: number
  • tagId: number
  • accepted sort: title \| status \| isFree \| createdAt \| updatedAt \| relevance

5.3 Customer discovery list (TrainingListQueryDto)

Additional filters:

  • categoryId: number
  • tagId: number
  • accepted sort: title \| isFree \| createdAt \| updatedAt \| relevance

5.4 Admin enrollment list (ListTrainingEnrollmentsQueryDto)

Additional filters:

  • status: pending \| enrolled \| cancelled
  • productId: number
  • userId: UUID string
  • cohortId: number
  • accepted sort: id \| status \| productId \| userId \| cohortId \| createdAt \| updatedAt

6. Response Shape Examples

6.1 Enrollment init request (EnrollTrainingDto)

{
  "productId": 101,
  "promoCode": "SUMMER2026",
  "gateway": "esewa",
  "returnUrl": "https://example.com/payment/return",
  "formData": {
    "name": "Sita Shrestha",
    "email": "sita@example.com",
    "phone": "+9779800000000"
  },
  "cohortId": 1,
  "sessionId": 5
}

6.2 Training enrollment response (TrainingEnrollmentResponseDto)

{
  "id": 1,
  "status": "pending",
  "userId": "9a824f6a-28d9-44ef-8c61-72d68a8f1b57",
  "productId": 101,
  "orderId": null,
  "cohortId": 1,
  "sessionId": 5,
  "accessType": null,
  "accessValidUntil": null,
  "formData": {
    "name": "Sita Shrestha"
  },
  "enrolledAt": null,
  "createdAt": "2026-03-17T09:45:00.000Z",
  "updatedAt": "2026-03-17T09:45:00.000Z"
}

6.3 Admin enrollment detail (TrainingEnrollmentAdminResponseDto)

{
  "id": 1,
  "status": "enrolled",
  "userId": "9a824f6a-28d9-44ef-8c61-72d68a8f1b57",
  "productId": 101,
  "orderId": 501,
  "cohortId": 1,
  "sessionId": 5,
  "accessType": "time_limited",
  "accessValidUntil": "2026-09-17T00:00:00.000Z",
  "formData": {
    "name": "Sita Shrestha"
  },
  "enrolledAt": "2026-03-18T10:20:00.000Z",
  "createdAt": "2026-03-17T09:45:00.000Z",
  "updatedAt": "2026-03-18T10:20:00.000Z",
  "orderNumber": "ORD-20260318-001",
  "orderTotalPaisa": 5000,
  "orderStatus": "paid",
  "userName": "Sita Shrestha",
  "userEmail": "sita@example.com",
  "trainingTitle": "NEPSE Trading Masterclass"
}

6.4 Session content response (SessionContentResponseDto)

{
  "id": 5,
  "title": "Session 3: Risk Management",
  "description": "Risk sizing and drawdown controls",
  "videoHlsUrl": "https://cdn.bullhouse.com/hls/training/session-3/index.m3u8?token=eyJ...",
  "videoTokenExpiresAt": "2026-04-16T14:00:00.000Z",
  "liveSessionRef": null,
  "durationMinutes": 75,
  "type": "both",
  "sessionStatus": "completed",
  "accessibleVia": "recording"
}

Note (Phase 12): recordingUrl has been removed from this response. Recorded session playback uses a signed HLS URL (videoHlsUrl) that expires at videoTokenExpiresAt. Use POST /mobile/training/{trainingId}/sessions/{sessionId}/video-token to refresh the token before expiry.

6.5 Standard envelope (ResponseDto)

{
  "message": "Training enrollments fetched successfully",
  "data": [
    {
      "id": 1,
      "status": "pending",
      "userId": "9a824f6a-28d9-44ef-8c61-72d68a8f1b57",
      "productId": 101,
      "orderId": null,
      "cohortId": 1,
      "sessionId": 5,
      "accessType": null,
      "accessValidUntil": null,
      "formData": {
        "name": "Sita Shrestha"
      },
      "enrolledAt": null,
      "createdAt": "2026-03-17T09:45:00.000Z",
      "updatedAt": "2026-03-17T09:45:00.000Z"
    }
  ],
  "count": 10,
  "page": 1,
  "size": 20,
  "errorCode": null
}

6.6 Trailer response fields

Admin detail and discovery preview surfaces now return:

{
  "trailerRef": "public/trailer/training/nepse-masterclass.mp4",
  "trailerUrl": "https://cdn.example.com/public/trailer/training/nepse-masterclass.mp4"
}

Use trailerUrl directly for playback. Do not derive URLs from trailerRef in the client.

7. Enums

EnumValues
training_statusdraft, published, hidden, archived
training_session_typerecorded, live, both
training_session_statusscheduled, live, completed, cancelled
training_cohort_statusopen, closed, full, cancelled
training_waitlist_statuswaiting, promoted, expired, cancelled
training_enrollment_statuspending, enrolled, cancelled
training_access_typelifetime, time_limited

8. Integration Diagram

8.1 Enrollment request and post-payment finalization

8.2 Session access decision flow

9. Caching

Training module uses Redis read-through caching with deterministic keys via CacheKeyUtil.build(...).

9.1 Core cache key prefixes

  • Training admin list/detail: training:admin:list:, training:admin:detail:
  • Discovery list/featured: training:customer:list:, training:customer:featured:
  • Session lists: training:session:admin:list:, training:session:customer:list:
  • Cohort and waitlist: training:cohort:admin:list:, training:cohort:waitlist:
  • Enrollment list/detail (customer): training:enrollment:list:, training:enrollment:detail:
  • Enrollment list/detail (admin): training:enrollment:admin:list:, training:enrollment:admin:detail:
  • Product access by user: training:product-access:user:

9.2 TTL and invalidation

  • TTL env: REDIS_CACHE_TTL_SECONDS
  • Mutation paths invalidate by prefix using invalidatePattern(prefix*)
  • Enrollment and status transitions invalidate enrollment, related session-list, and product-access scopes

10. Error Handling

All business failures use structured { message, errorCode } exceptions and the frontend should branch only on errorCode.

10.1 Validation and domain edge cases

  • Training product mismatch -> TRAINING_PRODUCT_REQUIRED
  • Product unpublished/unsellable -> TRAINING_PRODUCT_UNAVAILABLE
  • Duplicate active enrollment -> TRAINING_ALREADY_ENROLLED
  • Invalid or ineligible promo code during training order creation -> PROMOTION_NOT_APPLICABLE
  • Missing required dynamic form fields -> TRAINING_INVALID_FORM_DATA
  • Cohort full/closed/cancelled -> TRAINING_COHORT_FULL / TRAINING_COHORT_CLOSED / TRAINING_COHORT_CANCELLED
  • Session mismatch with training -> TRAINING_SESSION_MISMATCH
  • Pending cancellation request -> TRAINING_ENROLLMENT_CANCEL_NOT_ALLOWED
  • Session content before live or recording availability -> TRAINING_SESSION_NOT_LIVE / TRAINING_RECORDING_NOT_AVAILABLE

10.2 Common flow recipes and client behavior

Admin setup flow:

  1. Create training via POST /api/admin/training.
  2. Create sessions via POST /api/admin/training/:trainingId/sessions.
  3. Create cohort via POST /api/admin/training/:trainingId/cohorts.
  4. Assign sessions to cohort via PUT /api/admin/training/:trainingId/cohorts/:cohortId/sessions.
  5. Configure enrollment form via PUT /api/admin/training/:id/form-config.

Customer enrollment flow:

  1. Optionally validate coupon via POST /api/mobile/promotions/apply with code + productId.
  2. Submit enrollment request via POST /api/mobile/training/enroll (optional promoCode).
  3. Use returned payment-init payload to start gateway payment.
  4. Poll enrollment list/detail while payment is pending.
  5. After payment success in order flow, enrollment becomes enrolled and session access is enabled.

Client integration guidelines:

  • Use errorCode for business branching.
  • Treat pending enrollment as non-access state.
  • For pending enrollments, session list may include paymentStatusNote; do not expose content links until enrolled.
  • Use pagination params for list endpoints and read count/page/size only when pagination is enabled.

10.3 Testing scenarios and operational integration

Recommended scenario coverage:

  • Admin lifecycle: create training -> update status -> archive.
  • Session ordering and reorder payload validation.
  • Cohort creation and duplicate cohort-name conflict.
  • Waitlist promote idempotency and mismatch rejection.
  • Enrollment idempotency for repeated enroll request.
  • Pending vs enrolled session access behavior.
  • Cancellation path with cohort seat decrement.
  • Admin enrollment status update effect on seat counts.

Transactional notification integration:

  • Order lifecycle events: ORDER_PLACED_CHECKOUT, ORDER_PLACED_BUYNOW, ORDER_PAYMENT_RECEIVED_CHECKOUT, ORDER_PAYMENT_RECEIVED_BUYNOW, ORDER_PAYMENT_FAILED, ORDER_CANCELLED, ORDER_REFUND_*
  • Enrollment confirmation event: TRAINING_ENROLLMENT_CONFIRMED
  • Emission boundary: confirmation is emitted after successful post-payment finalization; notification delivery failure is fail-open and does not block enrollment/access writes.

Related docs:

Time fields in this module are stored as timezone-aware values and should be handled as ISO-8601 instants by API consumers.


See Also