Skip to content

Database Overview

The @nx/core package defines all database models across 7 PostgreSQL schemas with a total of 55 models. All packages share a single PostgresCoreDataSource backed by Drizzle ORM with the node-postgres driver.

SectionDescription
Public SchemaCore domain models: users, products, merchants, organizers (30 models)
Pricing SchemaFares, fare sets, fare rules, costs, taxes (7 models)
Allocation SchemaEvent seating: plans, layouts, zones, units (4 models)
Sale SchemaSale orders and sale order items (2 models)
Inventory SchemaStock management: items, locations, tracking, purchase orders (8 models)
Finance SchemaFinance wallets, categories, transactions (3 models)
Payment SchemaWebhook configurations (1 model)
ERDEntity-Relationship Diagram (Mermaid)
MigrationsMigration CLI, Drizzle Kit integration, seed data

Schema Summary

SchemaModelsDescription
public30Core domain: users, products, merchants, organizers, configurations
pricing7Fares, fare sets, fare rules, costs, taxes, tax sets, tax types
allocation4Event seating: layouts, plans, units, zones
sale2Sale orders and sale items
inventory8Stock management: items, locations, stocks, tracking, purchase orders, vendors
finance3Finance wallets, categories, transactions
payment1Webhook configurations
Total55

Schema distribution across the database:

All 7 schemas are defined in the PostgresSchemas class:

Source: packages/core/src/common/constants.ts

typescript
export class PostgresSchemas {
  static readonly PUBLIC = 'public';
  static readonly PRICING = 'pricing';
  static readonly ALLOCATION = 'allocation';
  static readonly SALE = 'sale';
  static readonly INVENTORY = 'inventory';
  static readonly FINANCE = 'finance';
  static readonly PAYMENT = 'payment';

  static readonly SCHEME_SET = new Set([
    this.PUBLIC, this.PRICING, this.ALLOCATION,
    this.SALE, this.INVENTORY, this.FINANCE, this.PAYMENT,
  ]);
}

DataSource

All packages connect to the same PostgreSQL database via PostgresCoreDataSource. It uses the node-postgres driver with Drizzle ORM and auto-discovers models from @repository bindings.

Source: packages/core/src/datasources/postgres-core.datasource.ts

typescript
@datasource({ driver: 'node-postgres' })
export class PostgresCoreDataSource extends BaseDataSource<IPostgresDataSourceSettings> {
  override configure(): ValueOrPromise<void> {
    const schema = this.getSchema(); // Auto-discovers models from @repository bindings
    this.pool = new Pool(this.settings);
    this.connector = drizzle({ client: this.pool, schema });
  }

  override getConnectionString(): ValueOrPromise<string> {
    const { host, port, database, user, password, useSSL } = this.settings;
    return `postgresql://${user}:${password}@${host}:${port}/${database}?sslmode=${
      useSSL ? 'require' : 'disable'
    }`;
  }
}

Environment Variables

VariableDescription
APP_ENV_POSTGRES_HOSTDatabase host
APP_ENV_POSTGRES_PORTDatabase port
APP_ENV_POSTGRES_DATABASEDatabase name
APP_ENV_POSTGRES_USERNAMEDatabase user
APP_ENV_POSTGRES_PASSWORDDatabase password

For more details on data sources in the IGNIS framework, see the IGNIS DataSources Reference.

Common Column Definitions

All models share a common set of columns generated by generateCommonColumnDefs(), defined in packages/core/src/models/schemas/common.ts.

generateCommonColumnDefs()

This function produces the following columns for every model:

ColumnTypeDescription
idtext (PK)Snowflake ID primary key
created_attimestamptzRow creation timestamp
modified_attimestamptzLast modification timestamp
deleted_attimestamptzSoft-delete timestamp (null = active)
metadatajsonbFlexible metadata field (typed per model)
typescript
export const generateCommonColumnDefs = <Metadata extends AnyType = AnyType>() => {
  return {
    ...generateIdColumnDefs({ id: { dataType: 'string' } }),
    ...generateTzColumnDefs({
      deleted: { enable: true, columnName: 'deleted_at', withTimezone: true },
    }),
    metadata: jsonb().$type<Metadata>(),
  };
};

The id column uses the IGNIS generateIdColumnDefs helper with string data type. IDs are generated using the Snowflake algorithm via IdGenerator.

The generateTzColumnDefs helper produces createdAt and modifiedAt timestamps, with an optional deletedAt column for soft-delete support.

isoTimestamp Custom Type

Drizzle's built-in timestamp types have incompatible behaviors:

  • mode: 'date' requires Date objects (not JSON-friendly)
  • mode: 'string' returns PostgreSQL format instead of ISO 8601

The isoTimestamp custom type solves this by accepting ISO strings from the frontend and converting PostgreSQL timestamps back to ISO 8601 format for consistent API responses.

typescript
export const isoTimestamp = (name: string, config?: { withTimezone?: boolean }) =>
  customType<{ data: string; driverData: string }>({
    dataType() {
      return `timestamp${config?.withTimezone ? ' with time zone' : ''}`;
    },
    toDriver(value: string): string {
      return value; // Pass the ISO string directly
    },
    fromDriver(value: string): string {
      const date = new Date(value);
      if (isNaN(date.getTime())) {
        throw getError({
          message: `Invalid date string: ${value}`,
          statusCode: HTTP.ResultCodes.RS_5.InternalServerError,
        });
      }
      return date.toISOString(); // Always returns ISO 8601
    },
  })(name);

Additional Column Helpers

Several models also use these IGNIS-provided column generators:

HelperColumns ProducedUsed By
generateUserAuditColumnDefs()created_by, modified_byOrganizer, Merchant, Configuration, SaleOrder, PurchaseOrder, etc.
generatePrincipalColumnDefs()principal_id, principal_typeUserMapping, UserRole, ProductInfo, ProductIdentifier, TaxSet, etc.
generateDataTypeColumnDefs()data_type, t_value, n_value, bo_value, b_value, j_valueFareRule, Configuration, Variant, UserConfiguration, Settings

Shared Types

INameI18n

Internationalized name fields stored as JSONB with optional English and Vietnamese translations.

typescript
export interface INameI18n {
  en?: string;
  vi?: string;
}

export const generateI18nColumnDef = (name: string) => jsonb(name).$type<INameI18n>();

Used for: categories, roles, organizers, merchants, products, fare names, inventory locations, finance wallets, and more.

ILocation

Physical address and coordinates stored as JSONB.

typescript
export interface ILocation {
  main: string;
  sub?: string;
  long?: string;
  lat?: string;
  postCode?: string;
}

Used for: organizers, merchants, devices, inventory locations, vendors.

ISocial

Social media links stored as JSONB with extensible key-value pairs.

typescript
export interface ISocial {
  facebook?: string;
  twitter?: string;
  instagram?: string;
  linkedin?: string;
  [key: string]: string | undefined;
}

Used for: organizers.

Schema Directory Structure

packages/core/src/models/schemas/
├── index.ts                        # Barrel export (all schemas)
├── common.ts                       # Shared types, column defs, schema objects
├── public/                         # public schema (30 models)
│   ├── user/                       # User, UserProfile, UserIdentifier, etc.
│   ├── role/                       # Role
│   ├── permission/                 # Permission, PermissionMapping
│   ├── organizer/                  # Organizer
│   ├── merchant/                   # Merchant, MerchantIdentifier
│   ├── product/                    # Product, ProductInfo, ProductVariant, etc.
│   ├── category/                   # Category
│   ├── sale-channel/               # SaleChannel, SaleChannelProduct
│   ├── configuration/              # Configuration
│   ├── settings/                   # Settings
│   ├── device/                     # Device
│   ├── meta-link/                  # MetaLink
│   ├── campaign/                   # Campaign
│   ├── quota/                      # Quota
│   ├── email-verification/         # EmailVerification
│   └── migration/                  # Migration
├── pricing/                        # pricing schema (7 models)
├── allocation/                     # allocation schema (4 models)
├── sale/                           # sale schema (2 models)
├── inventory/                      # inventory schema (8 models)
├── finance/                        # finance schema (3 models)
└── payment/                        # payment schema (1 model)

Each model directory contains:

  • schema.ts -- Drizzle table definition (columns, indexes, constraints)
  • model.ts -- Entity class with @model decorator, relations, and Zod schemas
  • index.ts -- Barrel export

IGNIS Framework References

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