@cendo/database-schemas 2.1.8 → 2.2.0
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/settings.local.json +9 -0
- package/CLAUDE.md +2 -0
- package/package.json +1 -1
- package/schemas/CarrierSetting.js +9 -1
- package/schemas/FulfillmentStore.js +12 -0
- package/schemas/ImportFile.js +7 -1
- package/schemas/ImportRow.js +11 -0
- package/schemas/Label.js +15 -0
- package/schemas/Media.js +16 -0
- package/schemas/Order.js +51 -1
- package/schemas/OrderFulfillment.js +25 -0
- package/schemas/OrderHistory.js +8 -1
- package/schemas/OrderItem.js +23 -0
- package/schemas/OrderLog.js +10 -1
- package/schemas/Product.js +24 -0
- package/schemas/ShippingCarrier.js +8 -0
- package/schemas/Shop.js +14 -1
- package/schemas/ShopSetting.js +9 -1
- package/schemas/SourceItem.js +19 -1
- package/schemas/SourceOrder.js +12 -0
- package/schemas/TestResponse.js +10 -0
- package/schemas/WebhookEvent.js +11 -1
- package/schemas/types/AttachmentObject.js +6 -0
- package/schemas/types/DimensionObject.js +6 -0
- package/schemas/types/FulfillmentObject.js +6 -0
- package/schemas/types/MoneyObject.js +6 -0
- package/schemas/types/ShippingAddress.js +18 -1
- package/schemas/types/TrackingObject.js +8 -1
package/CLAUDE.md
CHANGED
|
@@ -119,6 +119,8 @@ index.js # Exports path to schemas/ directory
|
|
|
119
119
|
|
|
120
120
|
## Schema Catalog
|
|
121
121
|
|
|
122
|
+
> Field-level descriptions are documented as JSDoc comments directly in each schema file.
|
|
123
|
+
|
|
122
124
|
### Orders & Fulfillment
|
|
123
125
|
- **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
126
|
- **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)
|
package/package.json
CHANGED
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
const {Schema} = require('mongoose')
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* CarrierSetting — Key-value settings per shipping carrier.
|
|
6
|
+
* Stores carrier-specific configuration (e.g., API credentials, routing rules).
|
|
7
|
+
*/
|
|
4
8
|
const CarrierSetting = new Schema({
|
|
9
|
+
/** Reference to the ShippingCarrier */
|
|
5
10
|
shipping_carrier: {
|
|
6
11
|
type: Schema.Types.ObjectId,
|
|
7
12
|
required: true,
|
|
8
13
|
index: true,
|
|
9
14
|
},
|
|
10
15
|
|
|
16
|
+
/** Setting key name */
|
|
11
17
|
key: {
|
|
12
18
|
type: String,
|
|
13
19
|
trim: true,
|
|
14
20
|
index: true,
|
|
15
21
|
},
|
|
16
22
|
|
|
23
|
+
/** Setting value (any type) */
|
|
17
24
|
value: {
|
|
18
25
|
type: Schema.Types.Mixed,
|
|
19
26
|
},
|
|
20
27
|
|
|
28
|
+
/** Last modification timestamp */
|
|
21
29
|
updated_at: {
|
|
22
30
|
type: Date,
|
|
23
31
|
default: Date.now
|
|
24
32
|
},
|
|
25
33
|
|
|
34
|
+
/** Creation timestamp */
|
|
26
35
|
created_at: {
|
|
27
36
|
type: Date,
|
|
28
37
|
default: Date.now,
|
|
@@ -32,4 +41,3 @@ const CarrierSetting = new Schema({
|
|
|
32
41
|
|
|
33
42
|
|
|
34
43
|
module.exports = CarrierSetting
|
|
35
|
-
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
const {Schema} = require('mongoose')
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* FulfillmentStore — Fulfillment provider/warehouse configuration.
|
|
6
|
+
* Stores API credentials and identifiers for connecting to fulfillment providers.
|
|
7
|
+
*/
|
|
4
8
|
const FulfillmentStore = new Schema({
|
|
9
|
+
/** Display name of the fulfillment provider */
|
|
5
10
|
name: {
|
|
6
11
|
type: String,
|
|
7
12
|
trim: true,
|
|
8
13
|
},
|
|
9
14
|
|
|
15
|
+
/** Provider status: 'active' | 'inactive' */
|
|
10
16
|
status: {
|
|
11
17
|
type: String,
|
|
12
18
|
enum: ['active', 'inactive'],
|
|
@@ -14,31 +20,37 @@ const FulfillmentStore = new Schema({
|
|
|
14
20
|
index: true,
|
|
15
21
|
},
|
|
16
22
|
|
|
23
|
+
/** API authentication key for the provider */
|
|
17
24
|
api_key: {
|
|
18
25
|
type: String,
|
|
19
26
|
trim: true,
|
|
20
27
|
},
|
|
21
28
|
|
|
29
|
+
/** Base URL of the provider's API */
|
|
22
30
|
api_url: {
|
|
23
31
|
type: String,
|
|
24
32
|
trim: true,
|
|
25
33
|
},
|
|
26
34
|
|
|
35
|
+
/** Store/account ID on the provider's system */
|
|
27
36
|
store_id: {
|
|
28
37
|
type: String,
|
|
29
38
|
trim: true,
|
|
30
39
|
},
|
|
31
40
|
|
|
41
|
+
/** Team ID on the provider's system */
|
|
32
42
|
team_id: {
|
|
33
43
|
type: String,
|
|
34
44
|
trim: true,
|
|
35
45
|
},
|
|
36
46
|
|
|
47
|
+
/** Last modification timestamp */
|
|
37
48
|
updated_at: {
|
|
38
49
|
type: Date,
|
|
39
50
|
default: Date.now
|
|
40
51
|
},
|
|
41
52
|
|
|
53
|
+
/** Creation timestamp */
|
|
42
54
|
created_at: {
|
|
43
55
|
type: Date,
|
|
44
56
|
default: Date.now,
|
package/schemas/ImportFile.js
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
const {Schema} = require('mongoose')
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* ImportFile — Bulk import file tracking.
|
|
6
|
+
* A container for imported rows from a CSV/Excel upload.
|
|
7
|
+
*/
|
|
4
8
|
const ImportFile = new Schema({
|
|
9
|
+
/** Original filename of the imported file */
|
|
5
10
|
name: {
|
|
6
11
|
type: String,
|
|
7
12
|
trim: true,
|
|
8
13
|
},
|
|
9
14
|
|
|
15
|
+
/** Last modification timestamp */
|
|
10
16
|
updated_at: {
|
|
11
17
|
type: Date,
|
|
12
18
|
default: Date.now
|
|
13
19
|
},
|
|
14
20
|
|
|
21
|
+
/** Creation timestamp */
|
|
15
22
|
created_at: {
|
|
16
23
|
type: Date,
|
|
17
24
|
default: Date.now
|
|
@@ -19,4 +26,3 @@ const ImportFile = new Schema({
|
|
|
19
26
|
})
|
|
20
27
|
|
|
21
28
|
module.exports = ImportFile
|
|
22
|
-
|
package/schemas/ImportRow.js
CHANGED
|
@@ -1,29 +1,38 @@
|
|
|
1
1
|
const {Schema} = require('mongoose')
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* ImportRow — Individual rows from a bulk import.
|
|
6
|
+
* Auto-deleted after 12 months via TTL index.
|
|
7
|
+
*/
|
|
4
8
|
const ImportRow = new Schema({
|
|
9
|
+
/** Reference to the parent ImportFile */
|
|
5
10
|
file: {
|
|
6
11
|
type: Schema.Types.ObjectId,
|
|
7
12
|
index: true,
|
|
8
13
|
required: true
|
|
9
14
|
},
|
|
10
15
|
|
|
16
|
+
/** Row/line number in the import file */
|
|
11
17
|
line: {
|
|
12
18
|
type: Number,
|
|
13
19
|
required: true
|
|
14
20
|
},
|
|
15
21
|
|
|
22
|
+
/** Deduplication key for this row */
|
|
16
23
|
unique_id: {
|
|
17
24
|
type: String,
|
|
18
25
|
required: true,
|
|
19
26
|
trim: true,
|
|
20
27
|
},
|
|
21
28
|
|
|
29
|
+
/** Raw row data from the import file */
|
|
22
30
|
data: {
|
|
23
31
|
type: Schema.Types.Mixed,
|
|
24
32
|
default: {}
|
|
25
33
|
},
|
|
26
34
|
|
|
35
|
+
/** Processing status: 'pending' | 'completed' | 'failed' | 'cancelled' */
|
|
27
36
|
status: {
|
|
28
37
|
type: String,
|
|
29
38
|
default: 'pending',
|
|
@@ -31,10 +40,12 @@ const ImportRow = new Schema({
|
|
|
31
40
|
index: true
|
|
32
41
|
},
|
|
33
42
|
|
|
43
|
+
/** Last modification timestamp */
|
|
34
44
|
updated_at: {
|
|
35
45
|
type: Date,
|
|
36
46
|
},
|
|
37
47
|
|
|
48
|
+
/** Creation timestamp (TTL: 12 months) */
|
|
38
49
|
created_at: {
|
|
39
50
|
type: Date,
|
|
40
51
|
default: Date.now
|
package/schemas/Label.js
CHANGED
|
@@ -1,60 +1,75 @@
|
|
|
1
1
|
const {Schema} = require('mongoose')
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Label — Shipping label records.
|
|
6
|
+
* Tracks label generation, storage, and push status to the source platform.
|
|
7
|
+
*/
|
|
4
8
|
const Label = new Schema({
|
|
9
|
+
/** Reference to the Order */
|
|
5
10
|
order: {
|
|
6
11
|
type: Schema.Types.ObjectId,
|
|
7
12
|
ref: 'Order',
|
|
8
13
|
index: true,
|
|
9
14
|
},
|
|
10
15
|
|
|
16
|
+
/** External order ID for lookup */
|
|
11
17
|
order_id: {
|
|
12
18
|
type: String,
|
|
13
19
|
trim: true,
|
|
14
20
|
index: true,
|
|
15
21
|
},
|
|
16
22
|
|
|
23
|
+
/** Tracking number printed on the label */
|
|
17
24
|
tracking_number: {
|
|
18
25
|
type: String,
|
|
19
26
|
trim: true,
|
|
20
27
|
index: true,
|
|
21
28
|
},
|
|
22
29
|
|
|
30
|
+
/** Carrier name/code for this label */
|
|
23
31
|
carrier: {
|
|
24
32
|
type: String,
|
|
25
33
|
trim: true,
|
|
26
34
|
},
|
|
27
35
|
|
|
36
|
+
/** Public URL to download/view the label */
|
|
28
37
|
url: {
|
|
29
38
|
type: String,
|
|
30
39
|
trim: true,
|
|
31
40
|
},
|
|
32
41
|
|
|
42
|
+
/** Internal file storage path for the label */
|
|
33
43
|
path_file: {
|
|
34
44
|
type: String,
|
|
35
45
|
trim: true,
|
|
36
46
|
},
|
|
37
47
|
|
|
48
|
+
/** Label status (e.g., 'created', 'printed') */
|
|
38
49
|
status: {
|
|
39
50
|
type: String,
|
|
40
51
|
trim: true,
|
|
41
52
|
index: true,
|
|
42
53
|
},
|
|
43
54
|
|
|
55
|
+
/** Whether this label has been pushed to the source platform */
|
|
44
56
|
is_pushed: {
|
|
45
57
|
type: Boolean,
|
|
46
58
|
default: false,
|
|
47
59
|
},
|
|
48
60
|
|
|
61
|
+
/** Timestamp when the label was pushed to the platform */
|
|
49
62
|
pushed_at: {
|
|
50
63
|
type: Date,
|
|
51
64
|
},
|
|
52
65
|
|
|
66
|
+
/** Last modification timestamp */
|
|
53
67
|
updated_at: {
|
|
54
68
|
type: Date,
|
|
55
69
|
default: Date.now
|
|
56
70
|
},
|
|
57
71
|
|
|
72
|
+
/** Creation timestamp */
|
|
58
73
|
created_at: {
|
|
59
74
|
type: Date,
|
|
60
75
|
default: Date.now,
|
package/schemas/Media.js
CHANGED
|
@@ -2,23 +2,31 @@ const {Schema} = require('mongoose')
|
|
|
2
2
|
const DimensionObject = require('./types/DimensionObject')
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Media — Design/mockup files.
|
|
7
|
+
* Tracks file processing status and storage location for print-ready designs and mockups.
|
|
8
|
+
*/
|
|
5
9
|
const Media = new Schema({
|
|
10
|
+
/** Public URL of the media file */
|
|
6
11
|
url: {
|
|
7
12
|
type: String,
|
|
8
13
|
trim: true,
|
|
9
14
|
},
|
|
10
15
|
|
|
16
|
+
/** Internal file storage path */
|
|
11
17
|
path_file: {
|
|
12
18
|
type: String,
|
|
13
19
|
trim: true,
|
|
14
20
|
},
|
|
15
21
|
|
|
22
|
+
/** Media type (default 'design') — e.g., 'design', 'mockup' */
|
|
16
23
|
type: {
|
|
17
24
|
type: String,
|
|
18
25
|
trim: true,
|
|
19
26
|
default: 'design'
|
|
20
27
|
},
|
|
21
28
|
|
|
29
|
+
/** Storage location: 'external' | 'internal' */
|
|
22
30
|
location: {
|
|
23
31
|
type: String,
|
|
24
32
|
default: 'external',
|
|
@@ -26,15 +34,18 @@ const Media = new Schema({
|
|
|
26
34
|
index: true,
|
|
27
35
|
},
|
|
28
36
|
|
|
37
|
+
/** MIME type of the file (e.g., 'image/png') */
|
|
29
38
|
mimetype: {
|
|
30
39
|
type: String,
|
|
31
40
|
trim: true,
|
|
32
41
|
},
|
|
33
42
|
|
|
43
|
+
/** File size in bytes */
|
|
34
44
|
size: {
|
|
35
45
|
type: Number,
|
|
36
46
|
},
|
|
37
47
|
|
|
48
|
+
/** Processing status: 'pending' | 'completed' | 'failed' */
|
|
38
49
|
status: {
|
|
39
50
|
type: String,
|
|
40
51
|
trim: true,
|
|
@@ -42,26 +53,31 @@ const Media = new Schema({
|
|
|
42
53
|
enum: ['pending', 'completed', 'failed'],
|
|
43
54
|
},
|
|
44
55
|
|
|
56
|
+
/** Image dimensions in pixels (embedded) */
|
|
45
57
|
dimension: {
|
|
46
58
|
type: DimensionObject
|
|
47
59
|
},
|
|
48
60
|
|
|
61
|
+
/** Number of processing attempts */
|
|
49
62
|
process_attempts: {
|
|
50
63
|
type: Number,
|
|
51
64
|
default: 0,
|
|
52
65
|
index: true
|
|
53
66
|
},
|
|
54
67
|
|
|
68
|
+
/** Error details if processing failed */
|
|
55
69
|
error_message: {
|
|
56
70
|
type: String,
|
|
57
71
|
trim: true,
|
|
58
72
|
},
|
|
59
73
|
|
|
74
|
+
/** Last modification timestamp */
|
|
60
75
|
updated_at: {
|
|
61
76
|
type: Date,
|
|
62
77
|
default: Date.now
|
|
63
78
|
},
|
|
64
79
|
|
|
80
|
+
/** Creation timestamp */
|
|
65
81
|
created_at: {
|
|
66
82
|
type: Date,
|
|
67
83
|
default: Date.now,
|
package/schemas/Order.js
CHANGED
|
@@ -5,13 +5,19 @@ const AttachmentObject = require('./types/AttachmentObject')
|
|
|
5
5
|
const FulfillmentObject = require('./types/FulfillmentObject')
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Order — Main order entity.
|
|
10
|
+
* Tracks e-commerce orders from multiple sales channels (TikTok, Shopify, etc.).
|
|
11
|
+
*/
|
|
8
12
|
const Order = new Schema({
|
|
13
|
+
/** Display name of the order (e.g., "#1001") */
|
|
9
14
|
name: {
|
|
10
15
|
type: String,
|
|
11
16
|
trim: true,
|
|
12
17
|
index: true,
|
|
13
18
|
},
|
|
14
19
|
|
|
20
|
+
/** External order ID from the source platform */
|
|
15
21
|
order_id: {
|
|
16
22
|
type: String,
|
|
17
23
|
trim: true,
|
|
@@ -19,6 +25,7 @@ const Order = new Schema({
|
|
|
19
25
|
required: true
|
|
20
26
|
},
|
|
21
27
|
|
|
28
|
+
/** Sales channel type, default 'tiktok' */
|
|
22
29
|
type: {
|
|
23
30
|
type: String,
|
|
24
31
|
trim: true,
|
|
@@ -26,46 +33,62 @@ const Order = new Schema({
|
|
|
26
33
|
index: true,
|
|
27
34
|
},
|
|
28
35
|
|
|
36
|
+
/** Reference to the Shop this order belongs to */
|
|
29
37
|
shop: {
|
|
30
38
|
type: Schema.Types.ObjectId,
|
|
31
39
|
index: true,
|
|
32
40
|
},
|
|
33
41
|
|
|
42
|
+
/** Type of shop at the time of order creation */
|
|
43
|
+
shop_type: {
|
|
44
|
+
type: String,
|
|
45
|
+
trim: true,
|
|
46
|
+
index: true,
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/** Reference to the FulfillmentStore handling this order */
|
|
34
50
|
fulfillment_store: {
|
|
35
51
|
type: Schema.Types.ObjectId,
|
|
36
52
|
index: true,
|
|
37
53
|
},
|
|
38
54
|
|
|
55
|
+
/** Reference to the current OrderFulfillment record */
|
|
39
56
|
fulfillment: {
|
|
40
57
|
type: Schema.Types.ObjectId,
|
|
41
58
|
index: true,
|
|
42
59
|
},
|
|
43
60
|
|
|
61
|
+
/** Recipient's shipping address (embedded) */
|
|
44
62
|
shipping_address: {
|
|
45
63
|
type: ShippingAddress,
|
|
46
64
|
},
|
|
47
65
|
|
|
66
|
+
/** Internal note visible to staff */
|
|
48
67
|
note: {
|
|
49
68
|
type: String,
|
|
50
69
|
trim: true,
|
|
51
70
|
},
|
|
52
71
|
|
|
72
|
+
/** Note from the customer or source platform */
|
|
53
73
|
external_note: {
|
|
54
74
|
type: String,
|
|
55
75
|
trim: true,
|
|
56
76
|
},
|
|
57
77
|
|
|
78
|
+
/** Payment method used (e.g., 'cod', 'online') */
|
|
58
79
|
payment_method: {
|
|
59
80
|
type: String,
|
|
60
81
|
trim: true,
|
|
61
82
|
},
|
|
62
83
|
|
|
84
|
+
/** Order status on the source platform */
|
|
63
85
|
platform_status: {
|
|
64
86
|
type: String,
|
|
65
87
|
trim: true,
|
|
66
88
|
index: true,
|
|
67
89
|
},
|
|
68
90
|
|
|
91
|
+
/** Fulfillment progress: 'unfulfilled' | 'processing' | 'fulfilled' | 'cancelled' */
|
|
69
92
|
fulfillment_status: {
|
|
70
93
|
type: String,
|
|
71
94
|
default: 'unfulfilled',
|
|
@@ -73,6 +96,7 @@ const Order = new Schema({
|
|
|
73
96
|
index: true
|
|
74
97
|
},
|
|
75
98
|
|
|
99
|
+
/** Approval status: 'pending' | 'approved' | 'rejected' */
|
|
76
100
|
validation_status: {
|
|
77
101
|
type: String,
|
|
78
102
|
default: 'pending',
|
|
@@ -80,141 +104,168 @@ const Order = new Schema({
|
|
|
80
104
|
index: true
|
|
81
105
|
},
|
|
82
106
|
|
|
107
|
+
/** Total item quantity in this order */
|
|
83
108
|
quantity: {
|
|
84
109
|
type: Number,
|
|
85
110
|
default: 1,
|
|
86
111
|
},
|
|
87
112
|
|
|
113
|
+
/** Order total amount with currency (embedded) */
|
|
88
114
|
amount: {
|
|
89
115
|
type: MoneyObject,
|
|
90
116
|
},
|
|
91
117
|
|
|
118
|
+
/** Special instructions for fulfillment */
|
|
92
119
|
fulfillment_note: {
|
|
93
120
|
type: String,
|
|
94
121
|
trim: true,
|
|
95
122
|
},
|
|
96
123
|
|
|
124
|
+
/** Timestamp when the order was created on the source platform */
|
|
97
125
|
order_created_at: {
|
|
98
126
|
type: Date,
|
|
99
127
|
index: true,
|
|
100
128
|
default: Date.now,
|
|
101
129
|
},
|
|
102
130
|
|
|
131
|
+
/** Last time this order was synced from the source platform */
|
|
103
132
|
last_synced_at: {
|
|
104
133
|
type: Date,
|
|
105
134
|
default: Date.now,
|
|
106
135
|
index: true
|
|
107
136
|
},
|
|
108
137
|
|
|
138
|
+
/** How many times this order has been synced */
|
|
109
139
|
sync_count: {
|
|
110
140
|
type: Number,
|
|
111
141
|
default: 0,
|
|
112
142
|
},
|
|
113
143
|
|
|
144
|
+
/** Error message from the last failed sync attempt */
|
|
114
145
|
last_sync_error: {
|
|
115
146
|
type: String,
|
|
116
147
|
trim: true,
|
|
117
148
|
},
|
|
118
149
|
|
|
150
|
+
/** Mapped order ID in the Nhanh.vn system */
|
|
119
151
|
nhanh_id: {
|
|
120
152
|
type: String,
|
|
121
153
|
trim: true,
|
|
122
154
|
},
|
|
123
155
|
|
|
156
|
+
/** List of validation steps that have passed */
|
|
124
157
|
valid_steps: {
|
|
125
158
|
type: [String],
|
|
126
159
|
default: [],
|
|
127
160
|
index: true
|
|
128
161
|
},
|
|
129
162
|
|
|
163
|
+
/** Number of attempts to map SKU for this order */
|
|
130
164
|
map_sku_attempts: {
|
|
131
165
|
type: Number,
|
|
132
166
|
default: 0,
|
|
133
167
|
index: true
|
|
134
168
|
},
|
|
135
169
|
|
|
170
|
+
/** Reference to the most recent shipping Label */
|
|
136
171
|
last_label: {
|
|
137
172
|
type: Schema.Types.ObjectId,
|
|
138
173
|
index: true,
|
|
139
174
|
},
|
|
140
175
|
|
|
176
|
+
/** Flexible metadata from the source platform */
|
|
141
177
|
metadata: {
|
|
142
178
|
type: Schema.Types.Mixed,
|
|
143
179
|
default: {}
|
|
144
180
|
},
|
|
145
181
|
|
|
182
|
+
/** Logistics/carrier data (tracking info, carrier responses) */
|
|
146
183
|
logistic_data: {
|
|
147
184
|
type: Schema.Types.Mixed,
|
|
148
185
|
default: {}
|
|
149
186
|
},
|
|
150
187
|
|
|
188
|
+
/** Storage location identifier for the shipping label file */
|
|
151
189
|
label_location: {
|
|
152
190
|
type: String,
|
|
153
191
|
trim: true,
|
|
154
192
|
},
|
|
155
193
|
|
|
194
|
+
/** Attached images (e.g., customer-uploaded design files) */
|
|
156
195
|
attachments: {
|
|
157
196
|
type: [AttachmentObject],
|
|
158
197
|
default: []
|
|
159
198
|
},
|
|
160
199
|
|
|
200
|
+
/** Categorization tags for filtering and grouping */
|
|
161
201
|
tags: {
|
|
162
202
|
type: [String],
|
|
163
203
|
default: [],
|
|
164
204
|
index: true
|
|
165
205
|
},
|
|
166
206
|
|
|
207
|
+
/** Number of attempts to push this order to a shipping carrier */
|
|
167
208
|
push_to_carrier_attempts: {
|
|
168
209
|
type: Number,
|
|
169
210
|
default: 0,
|
|
170
211
|
index: true
|
|
171
212
|
},
|
|
172
213
|
|
|
214
|
+
/** Reference to the ShippingCarrier assigned to this order */
|
|
173
215
|
shipping_carrier: {
|
|
174
216
|
type: Schema.Types.ObjectId,
|
|
175
217
|
index: true
|
|
176
218
|
},
|
|
177
219
|
|
|
220
|
+
/** List of fulfillment number + production status pairs (embedded) */
|
|
178
221
|
fulfillments: {
|
|
179
222
|
type: [FulfillmentObject],
|
|
180
223
|
default: []
|
|
181
224
|
},
|
|
182
225
|
|
|
226
|
+
/** External sync identifier for deduplication */
|
|
183
227
|
sync_id: {
|
|
184
228
|
type: String,
|
|
185
229
|
trim: true,
|
|
186
230
|
},
|
|
187
231
|
|
|
232
|
+
/** Mapped order ID in the Pancake system */
|
|
188
233
|
pancake_system_id: {
|
|
189
234
|
type: String,
|
|
190
235
|
trim: true,
|
|
191
236
|
},
|
|
192
237
|
|
|
238
|
+
/** Whether this order was imported from a legacy system */
|
|
193
239
|
is_legacy: {
|
|
194
240
|
type: Boolean,
|
|
195
241
|
},
|
|
196
242
|
|
|
243
|
+
/** Whether this order comes from a marketplace channel */
|
|
197
244
|
is_marketplace: {
|
|
198
245
|
type: Boolean,
|
|
199
246
|
default: false,
|
|
200
247
|
index: true
|
|
201
248
|
},
|
|
202
249
|
|
|
250
|
+
/** Estimated delivery date from the carrier */
|
|
203
251
|
estimate_delivery_date: {
|
|
204
252
|
type: Date,
|
|
205
253
|
index: true,
|
|
206
254
|
},
|
|
207
255
|
|
|
256
|
+
/** Timestamp when this order was pushed to the carrier */
|
|
208
257
|
pushed_at: {
|
|
209
258
|
type: Date,
|
|
210
259
|
index: true
|
|
211
260
|
},
|
|
212
261
|
|
|
262
|
+
/** Last modification timestamp */
|
|
213
263
|
updated_at: {
|
|
214
264
|
type: Date,
|
|
215
265
|
default: Date.now
|
|
216
266
|
},
|
|
217
267
|
|
|
268
|
+
/** Creation timestamp */
|
|
218
269
|
created_at: {
|
|
219
270
|
type: Date,
|
|
220
271
|
default: Date.now,
|
|
@@ -244,4 +295,3 @@ Order.index({
|
|
|
244
295
|
})
|
|
245
296
|
|
|
246
297
|
module.exports = Order
|
|
247
|
-
|