Packages Module

Description

The Packages module manages subscription package definitions and feature access control within the Trend Viewer API system. It provides read APIs for clients to discover available packages and concrete package plans, and supports provider mapping (e.g., Stripe product/price IDs) used by the Checkout/Subscription flows.

Main Features

  1. Package Catalog

    • Centralized definition of packages and capabilities (limits, visibility, API availability)
    • Exposes read endpoints for client apps and admin tools
  2. Package Plans and Pricing

    • Multiple plans per package with currencies, amounts, and billing cycles
    • Provider linkage for payment processors via price IDs
  3. Provider Mapping

    • Maps packages and plans to payment providers (e.g., Stripe product/price IDs)
    • Ensures consistent linkage used during checkout/subscription
  4. Feature Access Control

    • Controls limits such as members, product groups, products, categories, search queries, viewpoints
    • Enables tiered feature visibility per package

Overview Process Flow Diagram

---
config:
  theme: base
  layout: dagre
  flowchart:
    curve: linear
    htmlLabels: true
  themeVariables:
    edgeLabelBackground: "transparent"
---
flowchart TD
    %% Actors
    Client[Consumer]

    %% API Controller Layer
    subgraph ApiControllerLayer["API Controller Layer"]
        PackageController[PackageController]
        PackagePlanController[PackagePlanController]
    end

    %% Repository Layer
    subgraph RepositoryLayer["Repository Layer"]
        PackageRepository(PackageRepository)
        PackagePlanToProviderRepository(PackagePlanToProviderRepository)
    end

    %% Database Layer
    subgraph DatabaseLayer["Database Layer"]
        PackagesDB[(packages)]
        PackagePlansDB[(package_plans)]
        PlanToProvidersDB[(package_plan_to_providers)]
        ProvidersDB[(payment_providers)]
        PackageToProvidersDB[(package_to_providers)]
    end

    %% Packages listing flow
    Client --- P1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
            <p style='margin-top: 8px'>Request packages list</p>
        </div>
    ]
    P1 --> PackageController
    PackageController --- P2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
            <p style='margin-top: 8px'>Fetch from repository</p>
        </div>
    ]
    P2 --> PackageRepository
    PackageRepository --> PackagesDB
    PackageRepository --> PackagePlansDB
    PackageRepository --> PackageToProvidersDB
    PackageRepository --> ProvidersDB

    %% Package plan listing flow
    Client --- PP1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1'</span>
            <p style='margin-top: 8px'>Request package plans</p>
        </div>
    ]
    PP1 --> PackagePlanController
    PackagePlanController --- PP2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2'</span>
            <p style='margin-top: 8px'>Fetch from repository</p>
        </div>
    ]
    PP2 --> PackagePlanToProviderRepository
    PackagePlanToProviderRepository --> PackagePlansDB
    PackagePlanToProviderRepository --> PlanToProvidersDB
    PackagePlanToProviderRepository --> PackagesDB
    PackagePlanToProviderRepository --> ProvidersDB

    %% Styling
    style Client fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style ApiControllerLayer fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style RepositoryLayer fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style DatabaseLayer fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style P1 fill:transparent,stroke:transparent,stroke-width:1px
    style P2 fill:transparent,stroke:transparent,stroke-width:1px
    style PP1 fill:transparent,stroke:transparent,stroke-width:1px
    style PP2 fill:transparent,stroke:transparent,stroke-width:1px

Feature List Table

Name Link Description
Package Package Subscription package management and feature access control

Related Database

erDiagram
    packages {
        bigint id PK "Primary key"
        string name "Package name"
        string slug "Package slug (unique)"
        text description "Package description (nullable)"
        text image "Image path (nullable)"
        integer schedule_id "Schedule ID"
        integer schedule_priority "Schedule priority"
        integer max_member "Max members (nullable)"
        integer max_product_group "Max product groups (nullable)"
        integer max_product "Max products (nullable)"
        integer max_category "Max categories (nullable)"
        integer max_search_query "Max search queries (nullable)"
        integer max_viewpoint "Max viewpoints (nullable)"
        string data_visible "Data visibility"
        tinyint api_available "API available"
        tinyint status "Package status"
        timestamp created_at "Created at"
        timestamp updated_at "Updated at"
    }

    package_plans {
        bigint id PK "Primary key"
        string name "Plan name"
        string slug "Plan slug (unique)"
        bigint package_id FK "Linked to packages table"
        double amount "Amount"
        string currency "Currency"
        string type "Plan type (recurring, one_time)"
        string billing_plan "Billing cycle"
        tinyint status "Plan status"
        timestamp created_at "Created at"
        timestamp updated_at "Updated at"
    }

    package_plan_to_providers {
        bigint id PK "Primary key"
        bigint package_plan_id FK "Linked to package_plans table"
        bigint provider_id FK "Linked to payment_providers table"
        string provider_price_id "Price ID from provider (Stripe)"
        tinyint status "Status"
        timestamp created_at "Created at"
        timestamp updated_at "Updated at"
    }

    package_to_providers {
        bigint id PK "Primary key"
        bigint package_id FK "Linked to packages table"
        bigint provider_id FK "Linked to payment_providers table"
        string provider_product_id "Product ID from provider (Stripe)"
        tinyint status "Status"
        timestamp created_at "Created at"
        timestamp updated_at "Updated at"
    }

    payment_providers {
        bigint id PK "Primary key"
        string name "Provider name"
        string slug "Provider slug (unique)"
        tinyint status "Status"
        timestamp created_at "Created at"
        timestamp updated_at "Updated at"
    }

    packages ||--o{ package_plans : has
    package_plans ||--o{ package_plan_to_providers : has
    packages ||--o{ package_to_providers : has
    payment_providers ||--o{ package_plan_to_providers : linked
    payment_providers ||--o{ package_to_providers : linked

Related API Endpoints

Method Endpoint Controller Description
GET /api/admin/groups/packages PackageController@index Get available service packages list
GET /api/general/package-plan PackagePlanController@index Get service package plan list