Skip to content

Constants

FieldDetail
Source filepackages/core/src/common/constants.ts (294 lines)
Importimport { <ClassName> } from '@nx/core';
PatternStatic-class constants with Set-based validation
Total classes14

Overview

All application-wide constants are centralized in a single file (src/common/constants.ts) inside the @nx/core package. Every other package imports from @nx/core rather than defining its own magic strings.

Each constant class follows a consistent pattern:

  1. Static readonly fields -- the actual constant values.
  2. SCHEME_SET / TYPE_SET -- a Set containing all valid values, used for O(1) membership checks.
  3. isValid() helper -- a static method that delegates to the Set.
typescript
import { <ClassName> } from '@nx/core';

// Use a constant
const schema = PostgresSchemas.PUBLIC;

// Validate input
if (!PostgresSchemas.isValid(userInput)) {
  throw new Error('Invalid schema');
}

1. Infrastructure

RedisModes

Redis connection mode selector. Determines whether the application connects to a single Redis instance or a Redis Cluster.

NameValueDescription
SINGLE'single'Single Redis instance (standalone)
CLUSTER'cluster'Redis Cluster (multi-node)

INFO

RedisModes does not include a SCHEME_SET or isValid() helper. Validation is handled at the configuration layer.

Usage

typescript
import { RedisModes } from '@nx/core';

const redisMode = applicationEnvironment.get<string>('APP_ENV_WEBSOCKET_REDIS_MODE')
  ?? RedisModes.SINGLE;

if (redisMode === RedisModes.CLUSTER) {
  // Initialize cluster connection
}

PostgresSchemas

Identifiers for the seven PostgreSQL schemas used across the database.

NameValueDescription
PUBLIC'public'Users, roles, products, merchants, organizers, configurations
PRICING'pricing'Fares, pricing rules, costs, taxes
ALLOCATION'allocation'Event seating and venue layouts
SALE'sale'Sale orders and order items
INVENTORY'inventory'Stock and inventory management
FINANCE'finance'Wallets, transactions, categories
PAYMENT'payment'Webhook configurations

Helpers

MethodSignatureDescription
isValidisValid(input: string): booleanReturns true if input is a member of SCHEME_SET

Usage

typescript
import { PostgresSchemas } from '@nx/core';
import { pgSchema } from 'drizzle-orm/pg-core';

// Define a table in the pricing schema
const pricingSchema = pgSchema(PostgresSchemas.PRICING);
const Fare = pricingSchema.table('Fare', { /* columns */ });

// Validate schema name
if (!PostgresSchemas.isValid(input)) {
  throw new Error(`Unknown schema: ${input}`);
}

// Use in migration config
const schemaFilter = [
  PostgresSchemas.PUBLIC,
  PostgresSchemas.ALLOCATION,
  PostgresSchemas.PRICING,
];

2. Table / UI

TableConst

Default values for data-table and grid components used by both backend pagination and frontend UI.

NameValueDescription
DEFAULT_NAME'System'Default system display name
DEFAULT_PAGINATION{ pageIndex: 0, pageSize: 50 }Starting page and page size
DEFAULT_ROWS_PER_PAGE_OPTIONS[25, 50, 75, 100]Page-size selector options
DEFAULT_SORTING[{ id: 'createdAt', desc: true }]Default sort: newest first
DEFAULT_FILTER{}Empty filter object
DEFAULT_SIZE180Default column width in pixels

INFO

TableConst does not include a SCHEME_SET or isValid() helper because it holds default configuration objects, not enumeration values.

Usage

typescript
import { TableConst } from '@nx/core';

async findAll(opts?: PaginationOptions) {
  const pagination = opts?.pagination ?? TableConst.DEFAULT_PAGINATION;
  const sorting = opts?.sorting ?? TableConst.DEFAULT_SORTING;

  return this.find({
    limit: pagination.pageSize,
    offset: pagination.pageIndex * pagination.pageSize,
    orderBy: sorting.map(s => ({ [s.id]: s.desc ? 'desc' : 'asc' })),
  });
}

TableConfigurations

Keys for storing per-user table display configurations (column visibility, ordering, sizing). Each key corresponds to one admin dashboard screen table.

NameValue
TABLE_ORGANIZER'TABLE_ORGANIZER'
TABLE_MERCHANT'TABLE_MERCHANT'
TABLE_CATEGORY'TABLE_CATEGORY'
TABLE_PRODUCT'TABLE_PRODUCT'
TABLE_USER'TABLE_USER'
TABLE_CATEGORY_TEMPLATE'TABLE_CATEGORY_TEMPLATE'
TABLE_MERCHANT_TYPE'TABLE_MERCHANT_TYPE'
TABLE_EMPLOYEE'TABLE_EMPLOYEE'
TABLE_SALE_CHANNEL'TABLE_SALE_CHANNEL'
TABLE_DEVICE'TABLE_DEVICE'
TABLE_ROLE'TABLE_ROLE'
TABLE_TRANSACTION'TABLE_TRANSACTION'
TABLE_REVENUE_REPORT'TABLE_REVENUE_REPORT'
TABLE_ORDER_REPORT'TABLE_ORDER_REPORT'
TABLE_CUSTOMER'TABLE_CUSTOMER'
TABLE_INVOICE'TABLE_INVOICE'
TABLE_TERMINAL'TABLE_TERMINAL'
TABLE_VENDOR'TABLE_VENDOR'
TABLE_INVENTORY_TRACKING'TABLE_INVENTORY_TRACKING'
TABLE_SALE_ORDER'TABLE_SALE_ORDER'
TABLE_INVENTORY'TABLE_INVENTORY'
TABLE_FINANCE_TRANSACTION'TABLE_FINANCE_TRANSACTION'
TABLE_FINANCE_CATEGORY'TABLE_FINANCE_CATEGORY'
TABLE_FINANCE_WALLET'TABLE_FINANCE_WALLET'
TABLE_PURCHASE_ORDER'TABLE_PURCHASE_ORDER'

Usage

typescript
import { TableConfigurations } from '@nx/core';

// Save user's table configuration
await configurationRepository.upsert({
  userId: currentUser.id,
  code: TableConfigurations.TABLE_PRODUCT,
  value: JSON.stringify({ columns: ['name', 'price', 'status'], pageSize: 25 }),
});

UserConfigurationCodes

Keys for storing user-level preference data.

NameValueDescription
USER_PREFERENCES'PREFERENCES'General user preferences (language, theme, etc.)

Usage

typescript
import { UserConfigurationCodes } from '@nx/core';

const prefs = await configurationRepository.findOne({
  where: {
    userId: currentUser.id,
    code: UserConfigurationCodes.USER_PREFERENCES,
  },
});

3. System

SystemConfigurations

Identifies system-level configuration entries stored in the Configuration database table. Currently used to store payment provider credentials.

NameValueDescription
VNPAY_QR_MMS'VNPAY_QR_MMS'VNPAY QR MMS provider configuration
VNPAY_PHONE_POS'VNPAY_PHONE_POS'VNPAY PhonePOS provider configuration

Helpers

MethodSignatureDescription
isValidisValid(input: string): booleanReturns true if input is a member of SCHEME_SET

Usage

typescript
import { SystemConfigurations } from '@nx/core';

// Load payment configuration from the database
const config = await configurationRepository.findOne({
  where: { code: SystemConfigurations.VNPAY_QR_MMS },
});

// Validate configuration code
if (!SystemConfigurations.isValid(configCode)) {
  throw new Error(`Unknown system configuration: ${configCode}`);
}

4. Business

MerchantTypes

Business type classifications that determine POS UI layout and feature set.

NameValueDescription
DEFAULT'000_DEFAULT'Standard/general-purpose merchant
TICKET'100_POS_UI_TICKET'Ticket-selling POS (events, transport)
FNB'200_POS_UI_FNB'Food & Beverage POS
THEATER'300_POS_UI_THEATER'Theater/cinema POS with seat allocation

INFO

MerchantTypes does not include a SCHEME_SET or isValid() helper. Validation is performed at the service layer.

Usage

typescript
import { MerchantTypes } from '@nx/core';

// Create a merchant
await merchantRepository.create({
  data: {
    name: 'Cinema Central',
    type: MerchantTypes.THEATER,
    organizerId,
  },
});

// Conditional UI rendering (frontend)
switch (merchant.type) {
  case MerchantTypes.TICKET:
    return <TicketPOSUI />;
  case MerchantTypes.FNB:
    return <FnBPOSUI />;
  case MerchantTypes.THEATER:
    return <TheaterPOSUI />;
  default:
    return <DefaultPOSUI />;
}

FixedUserRoles

Predefined role identifiers with a numeric priority hierarchy. Higher priority codes grant broader access.

Role Identifiers

NameValueDescription
SUPER_ADMIN'999-super-admin'Full system control
ADMIN'998-admin'Administrative access
OPERATOR'997-operator'Operational management
ORGANIZER_OWNER'899-organizer-owner'Owner of an organizer entity
EMPLOYEE'898-employee'Staff-level access

Priority Codes

KeyCodeLevel
SUPER_ADMIN999System
ADMIN998System
OPERATOR997System
ORGANIZER_OWNER899Organization
EMPLOYEE898Organization

Special Sets

NameContentsDescription
ALWAYS_ALLOW_ROLESSUPER_ADMIN, ADMINRoles that bypass permission checks

Role Hierarchy

Usage

typescript
import { FixedUserRoles } from '@nx/core';

// Check admin bypass
if (FixedUserRoles.ALWAYS_ALLOW_ROLES.has(currentRole)) {
  return true; // Skip permission check
}

// Compare priority
const userPriority = FixedUserRoles.PRIORITY_CODE.ORGANIZER_OWNER; // 899
const requiredPriority = FixedUserRoles.PRIORITY_CODE.ADMIN;       // 998

if (userPriority < requiredPriority) {
  throw new ForbiddenError('Insufficient privileges');
}

CompanyRegistrationTypes

Legal entity classifications for organizer registration. Currently only Vietnam-specific types are active; international types are defined in source but commented out for future expansion.

Active Types (Vietnam)

NameValueVietnamese Name
VN_HOUSEHOLD_BUSINESS'300_VN_HOUSEHOLD_BUSINESS'Ho kinh doanh
VN_PRIVATE_ENTERPRISE'301_VN_PRIVATE_ENTERPRISE'Doanh nghiep tu nhan
VN_LIMITED_LIABILITY_ONE'302_VN_LIMITED_LIABILITY_ONE'Cong ty TNHH mot thanh vien
VN_LIMITED_LIABILITY_TWO_PLUS'303_VN_LIMITED_LIABILITY_TWO_PLUS'Cong ty TNHH hai thanh vien tro len
VN_JOINT_STOCK'304_VN_JOINT_STOCK'Cong ty co phan

Commented-Out Types (Future Use)

The source file contains commented-out definitions for international types that may be activated in the future:

CategoryCodesExamples
Individual/Personal001, 002INDIVIDUAL, SOLE_PROPRIETORSHIP
Partnership100, 101GENERAL_PARTNERSHIP, LIMITED_PARTNERSHIP
Corporation200, 201, 202PRIVATE_LIMITED_COMPANY, PUBLIC_LIMITED_COMPANY, JOINT_STOCK_COMPANY
Non-profit & Special800, 801, 802, 999NON_PROFIT, COOPERATIVE, GOVERNMENT_ENTITY, OTHER

Helpers

MethodSignatureDescription
isValidisValid(type: string): booleanReturns true if type is a member of TYPE_SET (active types only)

Usage

typescript
import { CompanyRegistrationTypes } from '@nx/core';

// Validate registration type
if (!CompanyRegistrationTypes.isValid(input.registrationType)) {
  throw new ValidationError('Invalid company registration type');
}

// Create organizer
await organizerRepository.create({
  data: {
    name: 'ABC Ltd.',
    registrationType: CompanyRegistrationTypes.VN_LIMITED_LIABILITY_ONE,
  },
});

DeviceTypes

POS and hardware device classifications used for device registration and management.

NameValueCategoryDescription
POS_TERMINAL'100_POS_TERMINAL'Fixed POSTraditional countertop POS
POS_WORKSTATION'101_POS_WORKSTATION'Fixed POSDesktop POS with full OS
MOBILE_POS'200_MOBILE_POS'Mobile POSSmartphone/tablet POS app
TABLET'400_TABLET'SpecializedGeneral tablet device
BARCODE_SCANNER'401_BARCODE_SCANNER'SpecializedStandalone barcode scanner
OTHER'999_OTHER'OtherUnclassified device

Helpers

MethodSignatureDescription
isValidisValid(type: string): booleanReturns true if type is a member of TYPE_SET

Usage

typescript
import { DeviceTypes } from '@nx/core';

// Validate device type
if (!DeviceTypes.isValid(input.deviceType)) {
  throw new ValidationError('Invalid device type');
}

// Create device
await deviceRepository.create({
  data: {
    name: 'Checkout Terminal 1',
    type: DeviceTypes.POS_TERMINAL,
    merchantId,
  },
});

5. Payment

MQPayProviders

Payment provider identifiers used by the MQ-Pay subsystem. Includes one internal provider (SYSTEM) and six third-party providers.

NameValueCategoryDescription
SYSTEM'SYSTEM'InternalManual payments (cash, bank transfer)
VNPAY_QR_MMS'VNPAY_QR_MMS'VNPAYDynamic QR code payments
VNPAY_PHONE_POS'VNPAY_PHONE_POS'VNPAYNFC card payment via PhonePOS
VNPAY_SMART_POS'VNPAY_SMART_POS'VNPAYQR + card hybrid via SmartPOS
MOMO'MOMO'Third-partyMoMo e-wallet
ZALOPAY'ZALOPAY'Third-partyZaloPay e-wallet
VIETQR'VIETQR'Third-partyVietQR bank transfer

Sets

NameContentsDescription
SCHEME_SETAll 7 providersComplete provider set
THIRD_PARTY_SCHEME_SETAll except SYSTEMOnly external payment providers

Helpers

MethodSignatureDescription
isValidisValid(scheme: string): booleanReturns true if scheme is any known provider
isThirdPartyProviderisThirdPartyProvider(opts: { provider: string }): booleanReturns true if opts.provider is a third-party (non-SYSTEM) provider

Usage

typescript
import { MQPayProviders } from '@nx/core';

// Check if provider requires external API calls
if (MQPayProviders.isThirdPartyProvider({ provider: paymentProvider })) {
  // Load credentials and call external payment gateway
} else {
  // Handle as manual/system payment
}

// Validate provider
if (!MQPayProviders.isValid(input.provider)) {
  throw new ValidationError('Unknown payment provider');
}

MQPayCredentialActions

Actions that require specific credential sets when communicating with payment providers. Each action maps to a distinct API operation.

NameValueDescription
CREATE_PAYMENT'CREATE_PAYMENT'Initiate a new payment transaction
VERIFY_IPN'VERIFY_IPN'Verify an Instant Payment Notification
CHECK_TRANSACTION'CHECK_TRANSACTION'Query transaction status from provider
CANCEL_PAYMENT'CANCEL_PAYMENT'Cancel an in-progress payment
REFUND'REFUND'Refund a settled payment

Helpers

MethodSignatureDescription
isValidisValid(scheme: string): booleanReturns true if scheme is a member of SCHEME_SET

Usage

typescript
import { MQPayCredentialActions } from '@nx/core';

// Load credentials for a specific action
const credentials = await paymentConfigService.getCredentials({
  provider: MQPayProviders.VNPAY_QR_MMS,
  action: MQPayCredentialActions.CREATE_PAYMENT,
});

MQPayCredentialTypes

Classification of credential data by direction of communication.

NameValueDescription
REQUEST'request'Credentials for outbound requests to the provider
RESPONSE'response'Credentials for validating provider responses
IPN'ipn'Credentials for verifying Instant Payment Notifications

Helpers

MethodSignatureDescription
isValidisValid(scheme: string): booleanReturns true if scheme is a member of SCHEME_SET

Usage

typescript
import { MQPayCredentialTypes } from '@nx/core';

// Retrieve request-specific credentials
const requestCreds = credentials.filter(
  c => c.type === MQPayCredentialTypes.REQUEST
);

// Retrieve IPN verification credentials
const ipnCreds = credentials.filter(
  c => c.type === MQPayCredentialTypes.IPN
);

6. Status

WebhookConfigStatuses

Lifecycle statuses for webhook configuration entries. Values are re-exported from the IGNIS framework Statuses class.

NameSource ConstantValueDescription
ACTIVATEDStatuses.ACTIVATED'201_ACTIVATED'Webhook is active and will receive events
DEACTIVATEDStatuses.DEACTIVATED'401_DEACTIVATED'Webhook is paused, no events dispatched
ARCHIVEDStatuses.ARCHIVED'405_ARCHIVED'Webhook is archived for record keeping

IGNIS Statuses

WebhookConfigStatuses delegates to Statuses from @venizia/ignis. For the complete status code reference, see the IGNIS Statuses documentation.

Type Export

typescript
export type TWebhookConfigStatus = TConstValue<typeof WebhookConfigStatuses>;
// Resolves to: '201_ACTIVATED' | '401_DEACTIVATED' | '405_ARCHIVED'

Helpers

MethodSignatureDescription
isValidisValid(status: string): booleanReturns true if status is a member of SCHEME_SET

Usage

typescript
import { WebhookConfigStatuses } from '@nx/core';
import type { TWebhookConfigStatus } from '@nx/core';

// Create a webhook config
await webhookConfigRepository.create({
  data: {
    name: 'Order Notifications',
    url: 'https://example.com/webhook',
    eventTypes: ['order.created', 'order.completed'],
    status: WebhookConfigStatuses.ACTIVATED,
  },
});

// Deactivate a webhook
await webhookConfigRepository.updateById({
  id: webhookId,
  data: { status: WebhookConfigStatuses.DEACTIVATED },
});

// Type-safe status parameter
function setWebhookStatus(id: string, status: TWebhookConfigStatus) {
  return webhookConfigRepository.updateById({ id, data: { status } });
}

Best Practices

1. Always Use Constants -- Never Magic Strings

typescript
// Good -- type-safe and refactorable
if (device.type === DeviceTypes.POS_TERMINAL) { /* ... */ }

// Bad -- magic string, prone to typos
if (device.type === '100_POS_TERMINAL') { /* ... */ }

2. Validate Input with isValid()

typescript
// Good -- explicit validation using the Set
if (!DeviceTypes.isValid(input.type)) {
  throw new ValidationError('Invalid device type');
}

// Bad -- manual inline check
if (!['100_POS_TERMINAL', '101_POS_WORKSTATION'].includes(input.type)) { /* ... */ }

3. Prefer SCHEME_SET / TYPE_SET for Bulk Checks

typescript
// Good -- O(1) lookup
if (MQPayProviders.THIRD_PARTY_SCHEME_SET.has(provider)) { /* ... */ }

// Bad -- O(n) array search
if (['VNPAY_QR_MMS', 'VNPAY_PHONE_POS', /* ... */].includes(provider)) { /* ... */ }

4. Extend Constants in Downstream Packages

When a downstream package needs additional values, extend the base class rather than duplicating:

typescript
export class ExtendedDeviceTypes extends DeviceTypes {
  static readonly SELF_CHECKOUT_KIOSK = '500_SELF_CHECKOUT_KIOSK';

  static override TYPE_SET = new Set([
    ...DeviceTypes.TYPE_SET,
    this.SELF_CHECKOUT_KIOSK,
  ]);
}

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.