@cendo/database-schemas 2.1.5 → 2.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +184 -0
- package/package.json +3 -2
- package/schemas/OrderFulfillment.js +5 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# @cendo/database-schemas
|
|
2
|
+
|
|
3
|
+
Shared Mongoose schema definitions for Cendo microservices. This package is the single source of truth for all MongoDB data models — services import schemas from here to ensure consistency.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
This package is used via the **schemis** library — it does not work standalone.
|
|
8
|
+
|
|
9
|
+
### Database Connection Setup
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
// src/connections/database.js
|
|
13
|
+
const {createConnection, createStore} = require('schemis')
|
|
14
|
+
const schemas = require('@cendo/database-schemas')
|
|
15
|
+
|
|
16
|
+
const uri = process.env.MONGODB_URI || 'mongodb://localhost:27017/dev'
|
|
17
|
+
const connection = createConnection(uri)
|
|
18
|
+
|
|
19
|
+
const store = createStore({
|
|
20
|
+
connection,
|
|
21
|
+
schemas
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
module.exports = store
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Using Models in Actions
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
const {getModel} = require('../../connections/database')
|
|
31
|
+
|
|
32
|
+
const Product = getModel('Product')
|
|
33
|
+
|
|
34
|
+
// Standard Mongoose operations
|
|
35
|
+
const product = await Product.findOne({_id: productId}).lean()
|
|
36
|
+
await Product.updateOne({_id: productId}, {$set: {status: 'active', updated_at: Date.now()}})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Populate with Explicit Model
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
const {getModel} = require('../../connections/database')
|
|
43
|
+
|
|
44
|
+
const Shop = getModel('Shop')
|
|
45
|
+
const FulfillmentStore = getModel('FulfillmentStore')
|
|
46
|
+
const ShippingCarrier = getModel('ShippingCarrier')
|
|
47
|
+
|
|
48
|
+
const shop = await Shop
|
|
49
|
+
.findOne({_id: id})
|
|
50
|
+
.populate({path: 'fulfillment_store', model: FulfillmentStore, select: {name: 1, status: 1}})
|
|
51
|
+
.populate({path: 'default_carrier', model: ShippingCarrier, select: {name: 1, code: 1, status: 1}})
|
|
52
|
+
.lean()
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Search with Pagination
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
const Product = getModel('Product')
|
|
59
|
+
|
|
60
|
+
const _fetch = Product
|
|
61
|
+
.find(query)
|
|
62
|
+
.sort(sort)
|
|
63
|
+
.skip(skip)
|
|
64
|
+
.limit(limit)
|
|
65
|
+
.lean()
|
|
66
|
+
|
|
67
|
+
const _fetchTotal = Product.countDocuments(query)
|
|
68
|
+
|
|
69
|
+
const [items, total] = await Promise.all([_fetch, _fetchTotal])
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Transactions
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
const Order = getModel('Order')
|
|
76
|
+
const OrderHistory = getModel('OrderHistory')
|
|
77
|
+
|
|
78
|
+
const session = await Order.startSession()
|
|
79
|
+
await session.withTransaction(async () => {
|
|
80
|
+
await Order.updateOne({_id: order._id}, {
|
|
81
|
+
$set: {validation_status, updated_at: Date.now()}
|
|
82
|
+
}, {session})
|
|
83
|
+
|
|
84
|
+
await OrderHistory.create([{
|
|
85
|
+
order: order._id,
|
|
86
|
+
action: 'validation_updated',
|
|
87
|
+
description: `Updated order validation status to ${validation_status}.`,
|
|
88
|
+
}], {session, ordered: true})
|
|
89
|
+
})
|
|
90
|
+
await session.endSession()
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Aggregation
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
const Order = getModel('Order')
|
|
97
|
+
|
|
98
|
+
const rows = await Order.aggregate([
|
|
99
|
+
{$match: query},
|
|
100
|
+
{$project: {tags: 1}},
|
|
101
|
+
{$unwind: {path: '$tags'}},
|
|
102
|
+
{$group: {_id: '$tags', count: {$sum: 1}}},
|
|
103
|
+
{$sort: {count: 1}}
|
|
104
|
+
])
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Dependencies
|
|
108
|
+
|
|
109
|
+
- **mongoose** `^9` (peer dependency)
|
|
110
|
+
- **schemis** — used by consumers to create database store and register models from schemas
|
|
111
|
+
|
|
112
|
+
## Directory Structure
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
schemas/ # Main schema files (19 schemas)
|
|
116
|
+
schemas/types/ # Embedded sub-document types (ShippingAddress, MoneyObject, etc.)
|
|
117
|
+
index.js # Exports path to schemas/ directory
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Schema Catalog
|
|
121
|
+
|
|
122
|
+
### Orders & Fulfillment
|
|
123
|
+
- **Order** — Main order entity (order_id, type, shop, fulfillment_status, validation_status, amount, shipping_address). Compound indexes on (order_id, type), (shipping_address.username), (shipping_address.email), (logistic_data.tracking_number), (fulfillments.number)
|
|
124
|
+
- **OrderItem** — Line items in orders (order, sku_id, product_name, quantity, fulfillment_sku, customize_id, mockup, design). Compound indexes on (order, sku_id) and (order, sync_id)
|
|
125
|
+
- **OrderFulfillment** — Fulfillment/shipment records (order, fulfillment_store, number, production_status, tracking, items). Index on (tracking.tracking_number)
|
|
126
|
+
- **OrderHistory** — Order action history (order, action, description, meta)
|
|
127
|
+
- **OrderLog** — Order event logging (order, level, label, message, meta). TTL: 90 days
|
|
128
|
+
|
|
129
|
+
### Products
|
|
130
|
+
- **Product** — Product/SKU catalog (shop, name, sku_id, seller_sku, fulfillment_sku, customize_sku, status). Full-text index on name/sku_id/fulfillment_sku/customize_sku
|
|
131
|
+
|
|
132
|
+
### Shops & Settings
|
|
133
|
+
- **Shop** — Store/shop configuration (shop_id, type, status, fulfillment_store, default_carrier, nhanh_id)
|
|
134
|
+
- **ShopSetting** — Shop-level key-value settings (shop, key, value as Mixed)
|
|
135
|
+
- **CarrierSetting** — Carrier-specific key-value settings (shipping_carrier, key, value as Mixed)
|
|
136
|
+
|
|
137
|
+
### Fulfillment & Shipping
|
|
138
|
+
- **FulfillmentStore** — Fulfillment provider/warehouse (name, status, api_key, api_url, store_id, team_id)
|
|
139
|
+
- **ShippingCarrier** — Carrier master data (name, code, status)
|
|
140
|
+
- **Label** — Shipping label records (order, order_id, tracking_number, carrier, url, path_file, status, is_pushed)
|
|
141
|
+
|
|
142
|
+
### Media
|
|
143
|
+
- **Media** — Design/mockup files (url, path_file, type, location, mimetype, size, dimension, status, process_attempts)
|
|
144
|
+
|
|
145
|
+
### Import
|
|
146
|
+
- **ImportFile** — Bulk import file tracking (name)
|
|
147
|
+
- **ImportRow** — Individual import rows (file, line, unique_id, data as Mixed, status). TTL: 12 months. Compound index on (file, line)
|
|
148
|
+
|
|
149
|
+
### Source Data
|
|
150
|
+
- **SourceOrder** — Source system order data (type defaults to 'shopify', id, name, financial_status, fulfillment_status)
|
|
151
|
+
- **SourceItem** — Source system line items (order, id, product_name, variant_name, sku, quantity, customize_properties, customize_item, mockup_url, design_url)
|
|
152
|
+
|
|
153
|
+
### Events & Logging
|
|
154
|
+
- **WebhookEvent** — Webhook event queue (topic, type, status, payload as Mixed, is_test). TTL: 7 days
|
|
155
|
+
- **TestResponse** — Test/webhook response logging (url, code, message, data as Mixed)
|
|
156
|
+
|
|
157
|
+
## Common Embedded Types
|
|
158
|
+
|
|
159
|
+
Used as sub-documents across schemas (all with `{ _id: false }`):
|
|
160
|
+
|
|
161
|
+
| Type | Fields | Used In |
|
|
162
|
+
|------|--------|---------|
|
|
163
|
+
| **ShippingAddress** | username, name, address1, address2, city, zip, province, district, commune, country, phone, phone_plain_text, email | Order |
|
|
164
|
+
| **MoneyObject** | amount, currency (default: 'VND') | Order |
|
|
165
|
+
| **AttachmentObject** | type (enum: 'image'), url | Order |
|
|
166
|
+
| **FulfillmentObject** | number, production_status | Order |
|
|
167
|
+
| **DimensionObject** | width, height | Media |
|
|
168
|
+
| **TrackingObject** | tracking_number, tracking_url, carrier | OrderFulfillment |
|
|
169
|
+
|
|
170
|
+
## Conventions
|
|
171
|
+
|
|
172
|
+
- Each schema file exports a Mongoose Schema (not a Model) — consumers register models themselves
|
|
173
|
+
- All text fields use `trim: true`
|
|
174
|
+
- Timestamps: schemas use `created_at` / `updated_at` fields (not Mongoose timestamps option), defaulting to `Date.now`
|
|
175
|
+
- Status fields use string enums (e.g., `'active'|'inactive'`, `'pending'|'completed'|'failed'`)
|
|
176
|
+
- Embedded types in `schemas/types/` have `{ _id: false }`
|
|
177
|
+
- TTL indexes for ephemeral data (OrderLog: 90 days, WebhookEvent: 7 days, ImportRow: 12 months)
|
|
178
|
+
- Text index on Product (name, sku_id, fulfillment_sku, customize_sku)
|
|
179
|
+
- `Schema.Types.Mixed` used for flexible metadata fields (logistic_data, metadata, payload, data)
|
|
180
|
+
- ObjectId references are used without `ref` in most schemas (except Label which refs 'Order')
|
|
181
|
+
- Attempt counters track retry logic: `map_sku_attempts`, `push_to_carrier_attempts`, `sync_media_attempts`, `process_attempts`
|
|
182
|
+
- Multi-platform integration fields: `nhanh_id`, `pancake_system_id`, `platform_status`
|
|
183
|
+
- Default currency is VND (Vietnamese Dong)
|
|
184
|
+
- Default shop type is 'tiktok'
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cendo/database-schemas",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"keywords": [],
|
|
7
7
|
"author": "",
|
|
8
8
|
"license": "ISC",
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"mongoose": "^9"
|
|
10
|
+
"mongoose": "^9",
|
|
11
|
+
"schemis": "^2.0.2"
|
|
11
12
|
},
|
|
12
13
|
"devDependencies": {
|
|
13
14
|
"mongoose": "^9"
|