@cravery/firebase 0.0.32 → 0.0.33
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/dist/repository/equipment.d.ts.map +1 -1
- package/dist/repository/equipment.js +12 -41
- package/dist/repository/equipment.js.map +1 -1
- package/dist/repository/ingredient.d.ts.map +1 -1
- package/dist/repository/ingredient.js +16 -80
- package/dist/repository/ingredient.js.map +1 -1
- package/package.json +1 -1
- package/src/repository/equipment.ts +15 -48
- package/src/repository/ingredient.ts +19 -94
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"equipment.d.ts","sourceRoot":"","sources":["../../src/repository/equipment.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"equipment.d.ts","sourceRoot":"","sources":["../../src/repository/equipment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,MAAM,EACX,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAGzB,MAAM,eAAe,CAAC;AAKvB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAWrD,qBAAa,mBAAoB,SAAQ,cAAc,CACrD,eAAe,EACf,mBAAmB,EACnB,sBAAsB,CACvB;IACC,SAAS,CAAC,QAAQ,CAAC,cAAc,SAAyB;IAC1D,SAAS,CAAC,QAAQ,CAAC,UAAU,eAAe;IAC5C,SAAS,CAAC,QAAQ,CAAC,aAAa,gGAA0B;IAC1D,SAAS,CAAC,QAAQ,CAAC,gBAAgB,mGAA6B;gBAEpD,EAAE,EAAE,SAAS;IAIzB,SAAS,CAAC,KAAK,CACb,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,sBAAsB,GAC9B,eAAe;IAIlB,SAAS,CAAC,KAAK,CACb,SAAS,EAAE,eAAe,GACzB,WAAW,CAAC,mBAAmB,EAAE,sBAAsB,CAAC;IA4BrD,aAAa,CACjB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,MAAM,EACd,KAAK,SAAK,EACV,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,GAAE,mBAA+B,GACzC,OAAO,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;CAQnD"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EquipmentRepository = void 0;
|
|
4
|
-
const firestore_1 = require("firebase-admin/firestore");
|
|
5
4
|
const core_1 = require("@cravery/core");
|
|
6
5
|
const converter_1 = require("../converter");
|
|
7
6
|
const base_1 = require("./base");
|
|
8
|
-
|
|
7
|
+
// All statuses except "deleted" - used for filtering
|
|
8
|
+
const ACTIVE_STATUSES = [
|
|
9
|
+
"active",
|
|
10
|
+
"archived",
|
|
11
|
+
"flagged",
|
|
12
|
+
"pending",
|
|
13
|
+
"suspended",
|
|
14
|
+
];
|
|
9
15
|
class EquipmentRepository extends base_1.BaseRepository {
|
|
10
16
|
constructor(db) {
|
|
11
17
|
super(db);
|
|
@@ -34,46 +40,11 @@ class EquipmentRepository extends base_1.BaseRepository {
|
|
|
34
40
|
};
|
|
35
41
|
}
|
|
36
42
|
async getByCategory(category, locale, limit = 20, cursor, direction = "forward") {
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
// Firestore requires orderBy on inequality field (status) first
|
|
40
|
-
let query = this.metaCollection
|
|
43
|
+
// Use "in" instead of "!=" to avoid complex index requirements
|
|
44
|
+
const baseQuery = this.metaCollection
|
|
41
45
|
.where("category", "==", category)
|
|
42
|
-
.where("status", "
|
|
43
|
-
|
|
44
|
-
.orderBy("createdAt", sortDir)
|
|
45
|
-
.orderBy(firestore_1.FieldPath.documentId(), sortDir);
|
|
46
|
-
if (cursor) {
|
|
47
|
-
const [timestamp, id] = (0, cursor_1.cursorToFirestoreValues)(cursor);
|
|
48
|
-
query = query.startAfter(timestamp, id);
|
|
49
|
-
}
|
|
50
|
-
const snapshot = await query.limit(limit + 1).get();
|
|
51
|
-
const hasMore = snapshot.docs.length > limit;
|
|
52
|
-
let docs = hasMore ? snapshot.docs.slice(0, -1) : snapshot.docs;
|
|
53
|
-
if (!isForward) {
|
|
54
|
-
docs = docs.reverse();
|
|
55
|
-
}
|
|
56
|
-
if (docs.length === 0) {
|
|
57
|
-
return {
|
|
58
|
-
data: [],
|
|
59
|
-
startCursor: null,
|
|
60
|
-
endCursor: null,
|
|
61
|
-
hasNextPage: false,
|
|
62
|
-
hasPreviousPage: false,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
const entities = await this.hydrate(docs, locale);
|
|
66
|
-
const firstDoc = docs[0];
|
|
67
|
-
const lastDoc = docs[docs.length - 1];
|
|
68
|
-
const firstCreatedAt = firstDoc.get("createdAt");
|
|
69
|
-
const lastCreatedAt = lastDoc.get("createdAt");
|
|
70
|
-
return {
|
|
71
|
-
data: entities,
|
|
72
|
-
startCursor: (0, cursor_1.encodeCursor)(firstCreatedAt, firstDoc.id),
|
|
73
|
-
endCursor: (0, cursor_1.encodeCursor)(lastCreatedAt, lastDoc.id),
|
|
74
|
-
hasNextPage: isForward ? hasMore : !!cursor,
|
|
75
|
-
hasPreviousPage: isForward ? !!cursor : hasMore,
|
|
76
|
-
};
|
|
46
|
+
.where("status", "in", ACTIVE_STATUSES);
|
|
47
|
+
return this.executePaginatedQuery(baseQuery, locale, limit, cursor, direction);
|
|
77
48
|
}
|
|
78
49
|
}
|
|
79
50
|
exports.EquipmentRepository = EquipmentRepository;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"equipment.js","sourceRoot":"","sources":["../../src/repository/equipment.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"equipment.js","sourceRoot":"","sources":["../../src/repository/equipment.ts"],"names":[],"mappings":";;;AACA,wCAUuB;AACvB,4CAGsB;AACtB,iCAAqD;AAErD,qDAAqD;AACrD,MAAM,eAAe,GAAmB;IACtC,QAAQ;IACR,UAAU;IACV,SAAS;IACT,SAAS;IACT,WAAW;CACZ,CAAC;AAEF,MAAa,mBAAoB,SAAQ,qBAIxC;IAMC,YAAY,EAAa;QACvB,KAAK,CAAC,EAAE,CAAC,CAAC;QANO,mBAAc,GAAG,kBAAW,CAAC,SAAS,CAAC;QACvC,eAAU,GAAG,WAAW,CAAC;QACzB,kBAAa,GAAG,kCAAsB,CAAC;QACvC,qBAAgB,GAAG,qCAAyB,CAAC;IAIhE,CAAC;IAES,KAAK,CACb,IAAyB,EACzB,OAA+B;QAE/B,uCAAY,IAAI,GAAK,OAAO,EAAG;IACjC,CAAC;IAES,KAAK,CACb,SAA0B;QAE1B,MAAM,EACJ,EAAE,EAAE,GAAG,EACP,SAAS,EACT,SAAS,EACT,SAAS,EACT,MAAM,EACN,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,IAAI,GACL,GAAG,SAAS,CAAC;QACd,OAAO;YACL,IAAI,EAAE;gBACJ,QAAQ;gBACR,QAAQ;gBACR,IAAI;gBACJ,KAAK;gBACL,MAAM;gBACN,SAAS;gBACT,SAAS;gBACT,SAAS;aACV;YACD,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;SACxB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,QAA2B,EAC3B,MAAc,EACd,KAAK,GAAG,EAAE,EACV,MAAe,EACf,YAAiC,SAAS;QAE1C,+DAA+D;QAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc;aAClC,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC;aACjC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;QAE1C,OAAO,IAAI,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACjF,CAAC;CACF;AAjED,kDAiEC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingredient.d.ts","sourceRoot":"","sources":["../../src/repository/ingredient.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ingredient.d.ts","sourceRoot":"","sources":["../../src/repository/ingredient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAGzB,MAAM,eAAe,CAAC;AAcvB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErD,qBAAa,oBAAqB,SAAQ,cAAc,CACtD,gBAAgB,EAChB,oBAAoB,EACpB,uBAAuB,CACxB;IACC,SAAS,CAAC,QAAQ,CAAC,cAAc,SAA2B;IAC5D,SAAS,CAAC,QAAQ,CAAC,UAAU,gBAAgB;IAC7C,SAAS,CAAC,QAAQ,CAAC,aAAa,iGAA2B;IAC3D,SAAS,CAAC,QAAQ,CAAC,gBAAgB,oGAA8B;gBAErD,EAAE,EAAE,SAAS;IAIzB,SAAS,CAAC,KAAK,CACb,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB;IAInB,SAAS,CAAC,KAAK,CACb,UAAU,EAAE,gBAAgB,GAC3B,WAAW,CAAC,oBAAoB,EAAE,uBAAuB,CAAC;IAgCvD,aAAa,CACjB,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,MAAM,EACd,KAAK,SAAK,EACV,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,GAAE,mBAA+B,GACzC,OAAO,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IAS7C,UAAU,CACd,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,SAAK,EACV,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,GAAE,mBAA+B,GACzC,OAAO,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;CAQpD"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.IngredientRepository = void 0;
|
|
4
|
-
const firestore_1 = require("firebase-admin/firestore");
|
|
5
4
|
const core_1 = require("@cravery/core");
|
|
5
|
+
// All statuses except "deleted" - used for filtering
|
|
6
|
+
const ACTIVE_STATUSES = [
|
|
7
|
+
"active",
|
|
8
|
+
"archived",
|
|
9
|
+
"flagged",
|
|
10
|
+
"pending",
|
|
11
|
+
"suspended",
|
|
12
|
+
];
|
|
6
13
|
const converter_1 = require("../converter");
|
|
7
14
|
const base_1 = require("./base");
|
|
8
|
-
const cursor_1 = require("../utils/cursor");
|
|
9
15
|
class IngredientRepository extends base_1.BaseRepository {
|
|
10
16
|
constructor(db) {
|
|
11
17
|
super(db);
|
|
@@ -36,88 +42,18 @@ class IngredientRepository extends base_1.BaseRepository {
|
|
|
36
42
|
};
|
|
37
43
|
}
|
|
38
44
|
async getByCategory(category, locale, limit = 20, cursor, direction = "forward") {
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
// Firestore requires orderBy on inequality field (status) first
|
|
42
|
-
let query = this.metaCollection
|
|
45
|
+
// Use "in" instead of "!=" to avoid complex index requirements
|
|
46
|
+
const baseQuery = this.metaCollection
|
|
43
47
|
.where("category", "==", category)
|
|
44
|
-
.where("status", "
|
|
45
|
-
|
|
46
|
-
.orderBy("createdAt", sortDir)
|
|
47
|
-
.orderBy(firestore_1.FieldPath.documentId(), sortDir);
|
|
48
|
-
if (cursor) {
|
|
49
|
-
const [timestamp, id] = (0, cursor_1.cursorToFirestoreValues)(cursor);
|
|
50
|
-
query = query.startAfter(timestamp, id);
|
|
51
|
-
}
|
|
52
|
-
const snapshot = await query.limit(limit + 1).get();
|
|
53
|
-
const hasMore = snapshot.docs.length > limit;
|
|
54
|
-
let docs = hasMore ? snapshot.docs.slice(0, -1) : snapshot.docs;
|
|
55
|
-
if (!isForward) {
|
|
56
|
-
docs = docs.reverse();
|
|
57
|
-
}
|
|
58
|
-
if (docs.length === 0) {
|
|
59
|
-
return {
|
|
60
|
-
data: [],
|
|
61
|
-
startCursor: null,
|
|
62
|
-
endCursor: null,
|
|
63
|
-
hasNextPage: false,
|
|
64
|
-
hasPreviousPage: false,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
const entities = await this.hydrate(docs, locale);
|
|
68
|
-
const firstDoc = docs[0];
|
|
69
|
-
const lastDoc = docs[docs.length - 1];
|
|
70
|
-
const firstCreatedAt = firstDoc.get("createdAt");
|
|
71
|
-
const lastCreatedAt = lastDoc.get("createdAt");
|
|
72
|
-
return {
|
|
73
|
-
data: entities,
|
|
74
|
-
startCursor: (0, cursor_1.encodeCursor)(firstCreatedAt, firstDoc.id),
|
|
75
|
-
endCursor: (0, cursor_1.encodeCursor)(lastCreatedAt, lastDoc.id),
|
|
76
|
-
hasNextPage: isForward ? hasMore : !!cursor,
|
|
77
|
-
hasPreviousPage: isForward ? !!cursor : hasMore,
|
|
78
|
-
};
|
|
48
|
+
.where("status", "in", ACTIVE_STATUSES);
|
|
49
|
+
return this.executePaginatedQuery(baseQuery, locale, limit, cursor, direction);
|
|
79
50
|
}
|
|
80
51
|
async getByGroup(group, locale, limit = 20, cursor, direction = "forward") {
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
// Firestore requires orderBy on inequality field (status) first
|
|
84
|
-
let query = this.metaCollection
|
|
52
|
+
// Use "in" instead of "!=" to avoid complex index requirements
|
|
53
|
+
const baseQuery = this.metaCollection
|
|
85
54
|
.where("group", "==", group)
|
|
86
|
-
.where("status", "
|
|
87
|
-
|
|
88
|
-
.orderBy("createdAt", sortDir)
|
|
89
|
-
.orderBy(firestore_1.FieldPath.documentId(), sortDir);
|
|
90
|
-
if (cursor) {
|
|
91
|
-
const [timestamp, id] = (0, cursor_1.cursorToFirestoreValues)(cursor);
|
|
92
|
-
query = query.startAfter(timestamp, id);
|
|
93
|
-
}
|
|
94
|
-
const snapshot = await query.limit(limit + 1).get();
|
|
95
|
-
const hasMore = snapshot.docs.length > limit;
|
|
96
|
-
let docs = hasMore ? snapshot.docs.slice(0, -1) : snapshot.docs;
|
|
97
|
-
if (!isForward) {
|
|
98
|
-
docs = docs.reverse();
|
|
99
|
-
}
|
|
100
|
-
if (docs.length === 0) {
|
|
101
|
-
return {
|
|
102
|
-
data: [],
|
|
103
|
-
startCursor: null,
|
|
104
|
-
endCursor: null,
|
|
105
|
-
hasNextPage: false,
|
|
106
|
-
hasPreviousPage: false,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
const entities = await this.hydrate(docs, locale);
|
|
110
|
-
const firstDoc = docs[0];
|
|
111
|
-
const lastDoc = docs[docs.length - 1];
|
|
112
|
-
const firstCreatedAt = firstDoc.get("createdAt");
|
|
113
|
-
const lastCreatedAt = lastDoc.get("createdAt");
|
|
114
|
-
return {
|
|
115
|
-
data: entities,
|
|
116
|
-
startCursor: (0, cursor_1.encodeCursor)(firstCreatedAt, firstDoc.id),
|
|
117
|
-
endCursor: (0, cursor_1.encodeCursor)(lastCreatedAt, lastDoc.id),
|
|
118
|
-
hasNextPage: isForward ? hasMore : !!cursor,
|
|
119
|
-
hasPreviousPage: isForward ? !!cursor : hasMore,
|
|
120
|
-
};
|
|
55
|
+
.where("status", "in", ACTIVE_STATUSES);
|
|
56
|
+
return this.executePaginatedQuery(baseQuery, locale, limit, cursor, direction);
|
|
121
57
|
}
|
|
122
58
|
}
|
|
123
59
|
exports.IngredientRepository = IngredientRepository;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingredient.js","sourceRoot":"","sources":["../../src/repository/ingredient.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"ingredient.js","sourceRoot":"","sources":["../../src/repository/ingredient.ts"],"names":[],"mappings":";;;AACA,wCAWuB;AAEvB,qDAAqD;AACrD,MAAM,eAAe,GAAmB;IACtC,QAAQ;IACR,UAAU;IACV,SAAS;IACT,SAAS;IACT,WAAW;CACZ,CAAC;AACF,4CAGsB;AACtB,iCAAqD;AAErD,MAAa,oBAAqB,SAAQ,qBAIzC;IAMC,YAAY,EAAa;QACvB,KAAK,CAAC,EAAE,CAAC,CAAC;QANO,mBAAc,GAAG,kBAAW,CAAC,WAAW,CAAC;QACzC,eAAU,GAAG,YAAY,CAAC;QAC1B,kBAAa,GAAG,mCAAuB,CAAC;QACxC,qBAAgB,GAAG,sCAA0B,CAAC;IAIjE,CAAC;IAES,KAAK,CACb,IAA0B,EAC1B,OAAgC;QAEhC,uCAAY,IAAI,GAAK,OAAO,EAAG;IACjC,CAAC;IAES,KAAK,CACb,UAA4B;QAE5B,MAAM,EACJ,EAAE,EAAE,GAAG,EACP,SAAS,EACT,SAAS,EACT,SAAS,EACT,MAAM,EACN,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,KAAK,EACL,YAAY,EACZ,IAAI,EACJ,IAAI,GACL,GAAG,UAAU,CAAC;QACf,OAAO;YACL,IAAI,EAAE;gBACJ,QAAQ;gBACR,KAAK;gBACL,QAAQ;gBACR,KAAK;gBACL,IAAI;gBACJ,YAAY;gBACZ,MAAM;gBACN,SAAS;gBACT,SAAS;gBACT,SAAS;aACV;YACD,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;SACxB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,QAA4B,EAC5B,MAAc,EACd,KAAK,GAAG,EAAE,EACV,MAAe,EACf,YAAiC,SAAS;QAE1C,+DAA+D;QAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc;aAClC,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC;aACjC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;QAE1C,OAAO,IAAI,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACjF,CAAC;IAED,KAAK,CAAC,UAAU,CACd,KAAsB,EACtB,MAAc,EACd,KAAK,GAAG,EAAE,EACV,MAAe,EACf,YAAiC,SAAS;QAE1C,+DAA+D;QAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc;aAClC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC;aAC3B,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;QAE1C,OAAO,IAAI,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACjF,CAAC;CACF;AApFD,oDAoFC"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Firestore } from "firebase-admin/firestore";
|
|
2
2
|
import {
|
|
3
3
|
type EquipmentEntity,
|
|
4
4
|
type EquipmentEntityMeta,
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type Locale,
|
|
8
8
|
type CursorPaginatedResult,
|
|
9
9
|
type PaginationDirection,
|
|
10
|
+
type EntityStatus,
|
|
10
11
|
COLLECTIONS,
|
|
11
12
|
} from "@cravery/core";
|
|
12
13
|
import {
|
|
@@ -14,7 +15,15 @@ import {
|
|
|
14
15
|
equipmentContentConverter,
|
|
15
16
|
} from "../converter";
|
|
16
17
|
import { BaseRepository, SplitResult } from "./base";
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
// All statuses except "deleted" - used for filtering
|
|
20
|
+
const ACTIVE_STATUSES: EntityStatus[] = [
|
|
21
|
+
"active",
|
|
22
|
+
"archived",
|
|
23
|
+
"flagged",
|
|
24
|
+
"pending",
|
|
25
|
+
"suspended",
|
|
26
|
+
];
|
|
18
27
|
|
|
19
28
|
export class EquipmentRepository extends BaseRepository<
|
|
20
29
|
EquipmentEntity,
|
|
@@ -74,53 +83,11 @@ export class EquipmentRepository extends BaseRepository<
|
|
|
74
83
|
cursor?: string,
|
|
75
84
|
direction: PaginationDirection = "forward",
|
|
76
85
|
): Promise<CursorPaginatedResult<EquipmentEntity>> {
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
// Firestore requires orderBy on inequality field (status) first
|
|
81
|
-
let query = this.metaCollection
|
|
86
|
+
// Use "in" instead of "!=" to avoid complex index requirements
|
|
87
|
+
const baseQuery = this.metaCollection
|
|
82
88
|
.where("category", "==", category)
|
|
83
|
-
.where("status", "
|
|
84
|
-
.orderBy("status", sortDir)
|
|
85
|
-
.orderBy("createdAt", sortDir)
|
|
86
|
-
.orderBy(FieldPath.documentId(), sortDir);
|
|
87
|
-
|
|
88
|
-
if (cursor) {
|
|
89
|
-
const [timestamp, id] = cursorToFirestoreValues(cursor);
|
|
90
|
-
query = query.startAfter(timestamp, id);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const snapshot = await query.limit(limit + 1).get();
|
|
94
|
-
const hasMore = snapshot.docs.length > limit;
|
|
95
|
-
let docs = hasMore ? snapshot.docs.slice(0, -1) : snapshot.docs;
|
|
96
|
-
|
|
97
|
-
if (!isForward) {
|
|
98
|
-
docs = docs.reverse();
|
|
99
|
-
}
|
|
89
|
+
.where("status", "in", ACTIVE_STATUSES);
|
|
100
90
|
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
data: [],
|
|
104
|
-
startCursor: null,
|
|
105
|
-
endCursor: null,
|
|
106
|
-
hasNextPage: false,
|
|
107
|
-
hasPreviousPage: false,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const entities = await this.hydrate(docs, locale);
|
|
112
|
-
|
|
113
|
-
const firstDoc = docs[0];
|
|
114
|
-
const lastDoc = docs[docs.length - 1];
|
|
115
|
-
const firstCreatedAt = firstDoc.get("createdAt") as Timestamp;
|
|
116
|
-
const lastCreatedAt = lastDoc.get("createdAt") as Timestamp;
|
|
117
|
-
|
|
118
|
-
return {
|
|
119
|
-
data: entities,
|
|
120
|
-
startCursor: encodeCursor(firstCreatedAt, firstDoc.id),
|
|
121
|
-
endCursor: encodeCursor(lastCreatedAt, lastDoc.id),
|
|
122
|
-
hasNextPage: isForward ? hasMore : !!cursor,
|
|
123
|
-
hasPreviousPage: isForward ? !!cursor : hasMore,
|
|
124
|
-
};
|
|
91
|
+
return this.executePaginatedQuery(baseQuery, locale, limit, cursor, direction);
|
|
125
92
|
}
|
|
126
93
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Firestore } from "firebase-admin/firestore";
|
|
2
2
|
import {
|
|
3
3
|
type IngredientEntity,
|
|
4
4
|
type IngredientEntityMeta,
|
|
@@ -8,14 +8,23 @@ import {
|
|
|
8
8
|
type Locale,
|
|
9
9
|
type CursorPaginatedResult,
|
|
10
10
|
type PaginationDirection,
|
|
11
|
+
type EntityStatus,
|
|
11
12
|
COLLECTIONS,
|
|
12
13
|
} from "@cravery/core";
|
|
14
|
+
|
|
15
|
+
// All statuses except "deleted" - used for filtering
|
|
16
|
+
const ACTIVE_STATUSES: EntityStatus[] = [
|
|
17
|
+
"active",
|
|
18
|
+
"archived",
|
|
19
|
+
"flagged",
|
|
20
|
+
"pending",
|
|
21
|
+
"suspended",
|
|
22
|
+
];
|
|
13
23
|
import {
|
|
14
24
|
ingredientMetaConverter,
|
|
15
25
|
ingredientContentConverter,
|
|
16
26
|
} from "../converter";
|
|
17
27
|
import { BaseRepository, SplitResult } from "./base";
|
|
18
|
-
import { encodeCursor, cursorToFirestoreValues } from "../utils/cursor";
|
|
19
28
|
|
|
20
29
|
export class IngredientRepository extends BaseRepository<
|
|
21
30
|
IngredientEntity,
|
|
@@ -79,54 +88,12 @@ export class IngredientRepository extends BaseRepository<
|
|
|
79
88
|
cursor?: string,
|
|
80
89
|
direction: PaginationDirection = "forward",
|
|
81
90
|
): Promise<CursorPaginatedResult<IngredientEntity>> {
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
// Firestore requires orderBy on inequality field (status) first
|
|
86
|
-
let query = this.metaCollection
|
|
91
|
+
// Use "in" instead of "!=" to avoid complex index requirements
|
|
92
|
+
const baseQuery = this.metaCollection
|
|
87
93
|
.where("category", "==", category)
|
|
88
|
-
.where("status", "
|
|
89
|
-
.orderBy("status", sortDir)
|
|
90
|
-
.orderBy("createdAt", sortDir)
|
|
91
|
-
.orderBy(FieldPath.documentId(), sortDir);
|
|
92
|
-
|
|
93
|
-
if (cursor) {
|
|
94
|
-
const [timestamp, id] = cursorToFirestoreValues(cursor);
|
|
95
|
-
query = query.startAfter(timestamp, id);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const snapshot = await query.limit(limit + 1).get();
|
|
99
|
-
const hasMore = snapshot.docs.length > limit;
|
|
100
|
-
let docs = hasMore ? snapshot.docs.slice(0, -1) : snapshot.docs;
|
|
101
|
-
|
|
102
|
-
if (!isForward) {
|
|
103
|
-
docs = docs.reverse();
|
|
104
|
-
}
|
|
94
|
+
.where("status", "in", ACTIVE_STATUSES);
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
data: [],
|
|
109
|
-
startCursor: null,
|
|
110
|
-
endCursor: null,
|
|
111
|
-
hasNextPage: false,
|
|
112
|
-
hasPreviousPage: false,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const entities = await this.hydrate(docs, locale);
|
|
117
|
-
|
|
118
|
-
const firstDoc = docs[0];
|
|
119
|
-
const lastDoc = docs[docs.length - 1];
|
|
120
|
-
const firstCreatedAt = firstDoc.get("createdAt") as Timestamp;
|
|
121
|
-
const lastCreatedAt = lastDoc.get("createdAt") as Timestamp;
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
data: entities,
|
|
125
|
-
startCursor: encodeCursor(firstCreatedAt, firstDoc.id),
|
|
126
|
-
endCursor: encodeCursor(lastCreatedAt, lastDoc.id),
|
|
127
|
-
hasNextPage: isForward ? hasMore : !!cursor,
|
|
128
|
-
hasPreviousPage: isForward ? !!cursor : hasMore,
|
|
129
|
-
};
|
|
96
|
+
return this.executePaginatedQuery(baseQuery, locale, limit, cursor, direction);
|
|
130
97
|
}
|
|
131
98
|
|
|
132
99
|
async getByGroup(
|
|
@@ -136,53 +103,11 @@ export class IngredientRepository extends BaseRepository<
|
|
|
136
103
|
cursor?: string,
|
|
137
104
|
direction: PaginationDirection = "forward",
|
|
138
105
|
): Promise<CursorPaginatedResult<IngredientEntity>> {
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
// Firestore requires orderBy on inequality field (status) first
|
|
143
|
-
let query = this.metaCollection
|
|
106
|
+
// Use "in" instead of "!=" to avoid complex index requirements
|
|
107
|
+
const baseQuery = this.metaCollection
|
|
144
108
|
.where("group", "==", group)
|
|
145
|
-
.where("status", "
|
|
146
|
-
.orderBy("status", sortDir)
|
|
147
|
-
.orderBy("createdAt", sortDir)
|
|
148
|
-
.orderBy(FieldPath.documentId(), sortDir);
|
|
149
|
-
|
|
150
|
-
if (cursor) {
|
|
151
|
-
const [timestamp, id] = cursorToFirestoreValues(cursor);
|
|
152
|
-
query = query.startAfter(timestamp, id);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const snapshot = await query.limit(limit + 1).get();
|
|
156
|
-
const hasMore = snapshot.docs.length > limit;
|
|
157
|
-
let docs = hasMore ? snapshot.docs.slice(0, -1) : snapshot.docs;
|
|
158
|
-
|
|
159
|
-
if (!isForward) {
|
|
160
|
-
docs = docs.reverse();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (docs.length === 0) {
|
|
164
|
-
return {
|
|
165
|
-
data: [],
|
|
166
|
-
startCursor: null,
|
|
167
|
-
endCursor: null,
|
|
168
|
-
hasNextPage: false,
|
|
169
|
-
hasPreviousPage: false,
|
|
170
|
-
};
|
|
171
|
-
}
|
|
109
|
+
.where("status", "in", ACTIVE_STATUSES);
|
|
172
110
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const firstDoc = docs[0];
|
|
176
|
-
const lastDoc = docs[docs.length - 1];
|
|
177
|
-
const firstCreatedAt = firstDoc.get("createdAt") as Timestamp;
|
|
178
|
-
const lastCreatedAt = lastDoc.get("createdAt") as Timestamp;
|
|
179
|
-
|
|
180
|
-
return {
|
|
181
|
-
data: entities,
|
|
182
|
-
startCursor: encodeCursor(firstCreatedAt, firstDoc.id),
|
|
183
|
-
endCursor: encodeCursor(lastCreatedAt, lastDoc.id),
|
|
184
|
-
hasNextPage: isForward ? hasMore : !!cursor,
|
|
185
|
-
hasPreviousPage: isForward ? !!cursor : hasMore,
|
|
186
|
-
};
|
|
111
|
+
return this.executePaginatedQuery(baseQuery, locale, limit, cursor, direction);
|
|
187
112
|
}
|
|
188
113
|
}
|