Skip to content

Subscription API

Relevant source files - config/upstash.js - controllers/subscription.controller.js - routes/subscription.routes.js

The Subscription API provides a comprehensive set of endpoints for managing recurring service commitments. It handles the full lifecycle of a subscription, from creation and automated workflow triggering to specialized queries for upcoming renewals.

API Architecture and Data Flow

The Subscription API is implemented using the Express.js Router pattern, delegating logic to a specialized controller. A critical feature of this API is its integration with an external workflow engine (Upstash) to manage asynchronous reminder logic.

Subscription Lifecycle Diagram

This diagram maps the natural language "Subscription Lifecycle" to the specific code entities responsible for each phase.

[Flowchart Diagram]

Sources:routes/subscription.routes.js82controllers/subscription.controller.js5-31config/upstash.js4-7


Endpoint Definitions

The API is served under the /api/v1/subscriptions prefix.

Method Path Controller Function Auth Required Description
POST / createSubscription Yes Creates a record and triggers a reminder workflow.
GET / getAllSubscriptions No Retrieves all subscriptions in the system.
GET /:id getSubscription No Retrieves a single subscription by its MongoDB ID.
PUT /:id updateSubscription No Updates subscription details with validation.
DELETE /:id deleteSubscription No Removes a subscription record.
GET /user/:id getUserSubscriptions Yes Lists all subscriptions belonging to a specific user.
GET /:id/cancel cancelSubscription No Sets the subscription status to 'canceled'.
GET /upcoming-renewals getUpcomingRenewals No Queries for active subscriptions nearing renewal.

Sources:routes/subscription.routes.js14-195


Key Implementation Details

Subscription Creation and Workflow Triggering

When createSubscription is invoked, the system performs two primary actions:

  1. Persistence: It saves the subscription to MongoDB, automatically associating it with the authenticated user's ID (req.user._id) controllers/subscription.controller.js7-10
  2. Workflow Trigger: It calls workflowClient.trigger() to initiate an asynchronous reminder sequence controllers/subscription.controller.js22-31

The trigger sends the subscriptionId to the workflow endpoint defined by the SERVER_URL. Notably, retries is set to 0 to prevent duplicate workflow runs for the same subscription controllers/subscription.controller.js30

Ownership and Authorization

The getUserSubscriptions endpoint implements an ownership check. It compares the id provided in the URL parameters with the id of the authenticated user stored in req.usercontrollers/subscription.controller.js47-51 If they do not match, it throws a 401 Unauthorized error.

Advanced Query Patterns

The getUpcomingRenewals function utilizes Mongoose/MongoDB operators to filter records controllers/subscription.controller.js152-162:

Sources:controllers/subscription.controller.js45-62controllers/subscription.controller.js152-166


Data Interaction Model

The following diagram illustrates how the subscription.controller.js interacts with the Subscription model and the workflowClient.

sequenceDiagram
    participant Client
    participant Controller as subscription.controller.js
    participant Model as subscription.model.js
    participant Upstash as workflowClient (config/upstash.js)
    Client->>Controller: POST /api/v1/subscriptions
    Controller->>Model: .create(req.body + user._id)
    Model-->>Controller: subscription object
    Controller->>Upstash: .trigger(workflowUrl, subscriptionId)
    Upstash-->>Controller: workflowRunId
    Controller-->>Client: 201 Created (subscription + workflowRunId)

Sources:controllers/subscription.controller.js5-38config/upstash.js4-7

Update and Deletion Logic

Sources:controllers/subscription.controller.js93-112controllers/subscription.controller.js131-150