@pintahub/database-schemas
v6.9.0
Published
Pintahub MongoDB schemas (TypeScript). Compatible with both schemis (CJS) and schemas-ts (ESM) resolvers.
Readme
@pintahub/database-schemas
Shared Mongoose schema definitions for PintaHub microservices. This package is the single source of truth for all MongoDB data models — services import schemas from here to ensure consistency.
Written in TypeScript (since v6.0.0), compiled to CommonJS in dist/ with TypeScript declaration files. Works with both schemis (CJS, JS legacy services) and schemas-ts (ESM, new TS services).
Documentation
Full guides live in docs/:
- docs/usage-js.md — consuming the package from a JavaScript (CJS) service via
schemis. - docs/usage-ts.md — consuming the package from a TypeScript (ESM) service via
schemas-ts, including typed models from@pintahub/database-schemas/types. - docs/migration.md — upgrading an existing service from v5 (CJS-only) to v6 (TypeScript rewrite), with two paths: stay on JS, or migrate to TS.
- docs/contributing.md — adding fields, schemas, indexes, embedded types; versioning rules; build & publish.
The sections below are a quick reference; the docs above are authoritative.
Installation
yarn add @pintahub/database-schemasPeer dependency:
mongoose^9.1.3
Plus one of the resolver libraries (pick based on your service style):
schemis^2.0.2— for CommonJS (JS) servicesschemas-ts^1.0.2— for ESM (TS) services
Usage
Option A — CommonJS service (admin-api, admin-worker, ...)
// src/connections/database.js
const {createConnection, createStore} = require('schemis')
const schemas = require('@pintahub/database-schemas')
const uri = process.env.MONGODB_URI || 'mongodb://localhost:27017/dev'
const connection = createConnection(uri)
const store = createStore({connection, schemas})
module.exports = storeOption B — ESM TypeScript service (shopify-gateway, ...)
// src/connections/database.ts
import {createConnection, createStore} from 'schemas-ts'
import schemasPath from '@pintahub/database-schemas'
import type {Model} from 'mongoose'
import type {IStore, IOrder} from '@pintahub/database-schemas/types'
const uri = process.env.MONGODB_URI || 'mongodb://localhost:27017/dev'
const connection = createConnection(uri)
const store = createStore({connection, schemas: schemasPath})
export default store
// Caller side
import storeDb from './connections/database.js'
const Store = storeDb.getModel('Store') as unknown as Model<IStore>
const found = await Store.findOne<IStore>({subdomain: 'foo'}).lean()The @pintahub/database-schemas/types subpath re-exports interfaces (IOrder, IStore, ...) for every schema, with the same field shape as the underlying Mongoose Schema.
Use models in actions
const Product = getModel('Product')
const product = await Product.findOne({_id: productId, store: storeId}).lean()
await Product.updateOne(
{_id: productId},
{$set: {status: 'active', updated_at: Date.now()}}
)Populate references with explicit model
const TransferJob = getModel('TransferJob')
const Product = getModel('Product')
const Store = getModel('Store')
const items = await TransferJob
.find({store: storeId})
.populate({path: 'product', model: Product, select: {title: 1, code: 1}})
.populate({path: 'destination_store', model: Store, select: {name: 1}})
.lean()Source Structure
src/
├── index.ts # export = path.join(__dirname, 'schemas') — public CJS entry
├── types.ts # re-exports all interfaces (consumed via '@pintahub/database-schemas/types')
├── interfaces/ # *.ts pure type definitions — no runtime
│ ├── Order.ts
│ ├── ...
│ ├── types/ # sub-schema interfaces (BrandSettings, ...)
│ └── products/ # product-specific interfaces (MediaObject, ...)
└── schemas/ # Mongoose Schema runtime — each file: export = SchemaInstance
├── Order.ts
├── ...
├── types/
└── products/Compiles to dist/ with the same shape; CJS module.exports = Schema per file so both schemis (require()) and schemas-ts (mod.default || mod) load identically.
Schema Catalog
Field-level documentation lives in JSDoc comments inside each schema file. This catalog is a quick map.
Accounts & Auth
Account, User, Store, Shop, ShopifyAPI
Products
Product, ProductFeature, ProductImage, ProductRaw, ProductType, ProductTag, ProductImport, Customize, CustomField, FieldSetting
Collections & Groups
Collection, Group, GroupItem, GroupArtwork
Orders & Fulfillment
Order, OrderItem, Fulfillment, Payout
Content & Pages
Post, Menu, MenuItem, AnnouncementBar
Media & Assets
Image, Artwork, Media, MediaUpload, TempUpload
Analytics & Tracking
StoreEvent, LatestEvent, RecentView, SearchTerm, FavoriteItem, TrackPage, MarketingCost
Short URLs
ShortUrl, ShortDomain, ShortLog, LogURL
Jobs & Events
ExportJob, TransferJob, WebhookEvent, ShopifyAPIRequest
Settings & Config
StoreSetting, PrintifySetting, BlockedLocation, Publication, ShopifyObject
Reports
CreatorReport, ProductReport
Reviews
Review
Embedded Types
schemas/types/: BrandSettings, DMCASetting, FacebookObject, FooterSetting, FreeShippingSetting, GoogleAnalytics, KlaviyoObject, MerchizeSettings, SocialsObject, TopBarSettings, TrustpilotObject
schemas/products/: MediaObject, SeoObject, VideoObject
schemas/ (root, embedded): MoneyObject, ImageObject, DimensionObject, PriceRange, FieldSetting
Conventions
- Each schema file exports a Mongoose Schema (not a Model) — consumers register models themselves via
schemisorschemas-ts. - Multi-tenancy: most domain schemas include a
storeObjectId ref, indexed for query performance. - Timestamps: schemas use explicit
created_at/updated_atDate fields (not Mongoose'stimestampsoption). - Status fields use string enums (e.g.
'active'|'inactive','pending'|'completed'|'failed'). - Embedded types in
schemas/types/andschemas/products/are declared with{_id: false}. - TTL indexes are used for ephemeral data (events, webhooks, page tracking).
- Text indexes exist on Product (
title,alternative_title,code,tags) and Order (name,id,email,phone). - The Product schema also exposes a precomputed
display_titlefield (alternative_title || title) for storefront search/display. Consumer services are responsible for setting it at write time.
Querying Tips
- Use
.lean()for read-only queries — returns plain objects instead of Mongoose documents. - Use
.populate()with an explicitmodelparameter when crossing collections. - Use
Promise.all()for independent queries (e.g.find+countDocuments). - Always filter by
storefor multi-tenant data.
Development
yarn install
yarn build # tsc → dist/
yarn dev # tsc --watch
node scripts/snapshot.js # diff dist/schemas/ paths against legacy schemas/ (when present)The scripts/convert.js one-off converter (used during the v5→v6 TS migration) and scripts/snapshot.js parity check are kept in the repo as historical reference.
Versioning
This package follows semver:
- Patch — JSDoc / docs only.
- Minor — new fields, new schemas, new indexes (backward compatible).
- Major — removing/renaming fields or schemas, changing field types, breaking index changes, or build/format changes (e.g. v6.0.0 TypeScript rewrite).
Bump the version in package.json whenever a schema change is committed.
