@7365admin1/core 3.48.1-staging.160 → 3.48.1-staging.162
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/.changeset/occurrence-entry-site-scope.md +58 -0
- package/.changeset/occurrence-subject-site-scope.md +58 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.js +45 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/harness.mjs +40 -0
- package/test/e2e/occurrence-entry-scope.e2e.test.mjs +483 -0
- package/test/e2e/occurrence-subject-scope.e2e.test.mjs +414 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Scope the occurrence entry routes to the estate the entry belongs to.
|
|
6
|
+
|
|
7
|
+
An occurrence entry is a single line the guards write into an estate's daily
|
|
8
|
+
security log — the time, the subject, the free-text account of what happened, the
|
|
9
|
+
signature of the guard who wrote it, and any incident report attached to it.
|
|
10
|
+
Every route on `/api/occurrence-entries` carried `requireAuth` and nothing more,
|
|
11
|
+
and `occurrence-entry.controller.ts` held no authorization identifier of any
|
|
12
|
+
kind. `requireAuth` proves a session exists; it makes no organisation or site
|
|
13
|
+
decision. So being signed in anywhere on the platform was enough to read another
|
|
14
|
+
client's log line by line, rewrite what an entry says, or delete an entry from
|
|
15
|
+
the record.
|
|
16
|
+
|
|
17
|
+
All six handlers now decide before any work is done. The route count was
|
|
18
|
+
verified at the registration site — `occurrence-entry.route.ts` mounts **six**
|
|
19
|
+
routes, not the four the earlier inventory recorded.
|
|
20
|
+
|
|
21
|
+
- `POST /` and `GET /` already REQUIRE a site (in the body and the query
|
|
22
|
+
respectively), so the guard checks a site the request already names and no
|
|
23
|
+
caller's contract changes.
|
|
24
|
+
- `GET /id/:id`, `PUT /id/:id` and `DELETE /id/:id` name only a record, so the
|
|
25
|
+
site is read off the STORED row through the new `requireOccurrenceEntryReach`,
|
|
26
|
+
built on a new raw reader `getRawOccurrenceEntryById` (the existing
|
|
27
|
+
`getOccurrenceEntryById` is CACHED).
|
|
28
|
+
- `GET /count/bookId/:id` is the one shape not seen on the earlier mounts: the
|
|
29
|
+
id identifies a **book**, not an entry. Its scope therefore comes from the
|
|
30
|
+
BOOK's row, through `requireOccurrenceBookSiteReach`.
|
|
31
|
+
|
|
32
|
+
That last one matters. Deriving reach from "some entry carrying this book id"
|
|
33
|
+
would have refused the FIRST entry of every new day, because a freshly opened
|
|
34
|
+
book has no entries to read — the security app calls this route to work out the
|
|
35
|
+
next serial number before writing that first line. There is a regression case
|
|
36
|
+
for exactly that.
|
|
37
|
+
|
|
38
|
+
`requireOccurrenceBookSiteReach` deliberately uses the book repository's
|
|
39
|
+
ordinary (cached) reader. A book's `site` is immutable — no route on
|
|
40
|
+
`/api/occurrence-books` accepts `site` on update — so a cached row cannot carry
|
|
41
|
+
a site that differs from the stored one, and the usual objection to deciding
|
|
42
|
+
reach from a cache does not apply here.
|
|
43
|
+
|
|
44
|
+
The rule is the existing one, `requireSiteReach` -> `entitleSite`. The
|
|
45
|
+
`customer.sites` branch is load-bearing: the guards who WRITE these entries are
|
|
46
|
+
the contracted security agency's staff and hold no membership in the estate's
|
|
47
|
+
own organisation.
|
|
48
|
+
|
|
49
|
+
Each guard sits AFTER the handler's own Joi validation, so a malformed id still
|
|
50
|
+
answers 400 exactly as before. A row that does not exist has no site, and
|
|
51
|
+
`requireSiteReach` refuses a missing site, so an id matching nothing is refused
|
|
52
|
+
rather than falling through.
|
|
53
|
+
|
|
54
|
+
`PUT /id/:id` cannot MOVE an entry — `schemaUpdateOccurrenceEntry` does not
|
|
55
|
+
accept `site` at all — so there is no destination to check.
|
|
56
|
+
|
|
57
|
+
`/api/occurrence-books` and `/api/occurrence-subjects` are separate mounts and
|
|
58
|
+
are not touched here; each gets its own change.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Scope the occurrence subject routes to the estate the subject belongs to, and
|
|
6
|
+
take the author from the session.
|
|
7
|
+
|
|
8
|
+
An occurrence subject is one of the named headings the guards pick from when
|
|
9
|
+
they write a line into an estate's daily security log — "Lift breakdown",
|
|
10
|
+
"Trespasser", "Fire alarm". The list belongs to one site. Every route on
|
|
11
|
+
`/api/occurrence-subjects` carried `requireAuth` and nothing more, and
|
|
12
|
+
`occurrence-subject.controller.ts` held no authorization identifier of any kind.
|
|
13
|
+
`requireAuth` proves a session exists; it makes no organisation or site
|
|
14
|
+
decision. So being signed in anywhere on the platform was enough to read another
|
|
15
|
+
client's subject list, add a heading to it, rename one, or delete one out from
|
|
16
|
+
under the guards who are picking from it.
|
|
17
|
+
|
|
18
|
+
Two defects, not one:
|
|
19
|
+
|
|
20
|
+
1. **No scope.** All five handlers now decide before any work is done. The route
|
|
21
|
+
count was verified at the registration site — `occurrence-subject.route.ts`
|
|
22
|
+
mounts **five** routes, not the three the earlier inventory recorded.
|
|
23
|
+
2. **Identity from the caller's body.** `POST /` took `addedBy` straight out of
|
|
24
|
+
the request body and never compared it to the session, so a heading could be
|
|
25
|
+
filed under somebody else's name. It comes from `callerId(req)` now. The
|
|
26
|
+
shipped mobile client's own comment records the old behaviour — "`addedBy` is
|
|
27
|
+
sent because the model stores it; the server does not take it from the
|
|
28
|
+
session". Same defect already fixed on `/api/attendances`,
|
|
29
|
+
`/api/site-entrypass-settings` and `/api/feedbacks`.
|
|
30
|
+
|
|
31
|
+
- `POST /` and `GET /` already REQUIRE a site (`schemaOccurrenceSubject` and the
|
|
32
|
+
query schema both have `site` required), so the guard checks a site the
|
|
33
|
+
request already names and no caller's contract changes.
|
|
34
|
+
- `GET /id/:id`, `PUT /id/:id` and `DELETE /id/:id` name only a record, so the
|
|
35
|
+
site is read off the STORED row through the new
|
|
36
|
+
`requireOccurrenceSubjectReach`, built on a new raw reader
|
|
37
|
+
`getRawOccurrenceSubjectById` (the existing `getOccurrenceSubjectById` is
|
|
38
|
+
CACHED, so a guard built on it would decide reach from a cache entry).
|
|
39
|
+
|
|
40
|
+
`GET /`'s `site` is genuinely applied by the repository — it is part of the
|
|
41
|
+
`baseQuery` and of the cache key — so the list needed a reach check on the site
|
|
42
|
+
it names, not a narrowing pass after the read.
|
|
43
|
+
|
|
44
|
+
The rule is the existing one, `requireSiteReach` -> `entitleSite`. The
|
|
45
|
+
`customer.sites` branch is load-bearing: the guards who maintain this list are
|
|
46
|
+
the contracted security agency's staff and hold no membership in the estate's
|
|
47
|
+
own organisation.
|
|
48
|
+
|
|
49
|
+
Each guard sits AFTER the handler's own Joi validation, so a malformed id still
|
|
50
|
+
answers 400 exactly as before. A row that does not exist has no site, and
|
|
51
|
+
`requireSiteReach` refuses a missing site, so an id matching nothing is refused
|
|
52
|
+
rather than falling through.
|
|
53
|
+
|
|
54
|
+
`PUT /id/:id` cannot MOVE a subject — `schemaUpdateOccurrenceSubject` accepts
|
|
55
|
+
only `_id` and `subject` — so there is no destination to check.
|
|
56
|
+
|
|
57
|
+
This closes the occurrence-book family: `/occurrence-books`,
|
|
58
|
+
`/occurrence-entries` and `/occurrence-subjects`.
|
package/dist/index.d.ts
CHANGED
|
@@ -7581,6 +7581,7 @@ declare function useOccurrenceEntryRepo(): {
|
|
|
7581
7581
|
pageRange: string;
|
|
7582
7582
|
} | TOccurrenceEntry>;
|
|
7583
7583
|
getOccurrenceEntryById: (_id: string | ObjectId, session?: ClientSession) => Promise<bson.Document>;
|
|
7584
|
+
getRawOccurrenceEntryById: (_id: string | ObjectId) => Promise<mongodb.WithId<bson.Document> | null>;
|
|
7584
7585
|
getOccurrenceEntryByBookId: (dailyOccurrenceBookId: string | ObjectId) => Promise<mongodb.WithId<bson.Document> | null>;
|
|
7585
7586
|
updateOccurrenceEntryById: (_id: ObjectId | string, value: Partial<TOccurrenceEntry>, session?: ClientSession) => Promise<mongodb.UpdateResult<bson.Document>>;
|
|
7586
7587
|
updateUserNameBySignatureId: (_id: string | ObjectId, value: string | ObjectId, session?: ClientSession) => Promise<number>;
|
|
@@ -7597,6 +7598,39 @@ declare function useOccurrenceEntryService(): {
|
|
|
7597
7598
|
updateOccurrenceEntryById: (id: string | ObjectId, value: TOccurrenceEntry) => Promise<"Successfully updated occurrence entry (incident report)." | "Successfully updated daily occurrence entry.">;
|
|
7598
7599
|
};
|
|
7599
7600
|
|
|
7601
|
+
/**
|
|
7602
|
+
* Who may see, or change, one line of a site's occurrence book.
|
|
7603
|
+
*
|
|
7604
|
+
* An occurrence entry is a single line the guards write into an estate's daily
|
|
7605
|
+
* security log - the time, the subject, the free-text account of what happened,
|
|
7606
|
+
* the signature of the guard who wrote it, and any incident report attached to
|
|
7607
|
+
* it. Every route on `/api/occurrence-entries` carried `requireAuth` and
|
|
7608
|
+
* nothing more, and this controller held no authorization identifier of any
|
|
7609
|
+
* kind, so being signed in anywhere on the platform was enough to read another
|
|
7610
|
+
* client's log line by line, rewrite what an entry says, or delete an entry
|
|
7611
|
+
* from the record.
|
|
7612
|
+
*
|
|
7613
|
+
* The estate is the scope. `requireSiteReach` is the rule `/api/feedbacks`,
|
|
7614
|
+
* `/api/work-orders`, `/api/occurrence-books`, `/api/manpower-monitoring`,
|
|
7615
|
+
* `/api/attendances`, `/api/remarks`, `/api/vehicles`, `/api/documents` and
|
|
7616
|
+
* `/api/incident-reports` already use. The `customer.sites` branch is
|
|
7617
|
+
* load-bearing here: the guards who WRITE these entries are the contracted
|
|
7618
|
+
* security agency's staff and hold no membership in the estate's organisation.
|
|
7619
|
+
*
|
|
7620
|
+
* - `POST /` and `GET /` already REQUIRE a site, in the body and the query
|
|
7621
|
+
* respectively, so the guard checks the site the request already names and
|
|
7622
|
+
* no caller's contract changes.
|
|
7623
|
+
* - `GET /id/:id`, `PUT /id/:id` and `DELETE /id/:id` name only a record, so
|
|
7624
|
+
* the site is read off the STORED row via `requireOccurrenceEntryReach`.
|
|
7625
|
+
* - `GET /count/bookId/:id` is the one different shape on this mount: `:id`
|
|
7626
|
+
* identifies a BOOK, not an entry. Its scope therefore comes from the BOOK's
|
|
7627
|
+
* row, not from an entry - `requireOccurrenceBookSiteReach` below. Deriving
|
|
7628
|
+
* it from "some entry with this book id" would refuse the FIRST entry of
|
|
7629
|
+
* every new day, because a freshly opened book has no entries to read.
|
|
7630
|
+
*
|
|
7631
|
+
* `PUT /id/:id` cannot MOVE an entry: `schemaUpdateOccurrenceEntry` does not
|
|
7632
|
+
* accept `site` at all, so there is no destination to check.
|
|
7633
|
+
*/
|
|
7600
7634
|
declare function useOccurrenceEntryController(): {
|
|
7601
7635
|
add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
7602
7636
|
getAll: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
@@ -7731,6 +7765,7 @@ declare function useOccurrenceSubjectRepo(): {
|
|
|
7731
7765
|
pageRange: string;
|
|
7732
7766
|
} | TOccurrenceSubject>;
|
|
7733
7767
|
getOccurrenceSubjectById: (_id: string | ObjectId, session?: ClientSession) => Promise<mongodb.WithId<bson.Document> | TOccurrenceSubject>;
|
|
7768
|
+
getRawOccurrenceSubjectById: (_id: string | ObjectId) => Promise<mongodb.WithId<bson.Document> | null>;
|
|
7734
7769
|
updateOccurrenceSubjectById: (_id: ObjectId | string, value: Partial<TOccurrenceSubject>, session?: ClientSession) => Promise<mongodb.UpdateResult<bson.Document>>;
|
|
7735
7770
|
deleteOccurrenceSubjectById: (_id: string | ObjectId) => Promise<number>;
|
|
7736
7771
|
createIndexes: () => Promise<void>;
|
|
@@ -7742,6 +7777,41 @@ declare function useOccurrenceSubjectService(): {
|
|
|
7742
7777
|
updateOccurrenceSubjectById: (id: string | ObjectId, value: Partial<TOccurrenceSubject>) => Promise<string>;
|
|
7743
7778
|
};
|
|
7744
7779
|
|
|
7780
|
+
/**
|
|
7781
|
+
* Who may see, or change, the list of subjects an estate logs against.
|
|
7782
|
+
*
|
|
7783
|
+
* An occurrence subject is one of the named headings the guards pick from when
|
|
7784
|
+
* they write a line into the estate's daily security log - "Lift breakdown",
|
|
7785
|
+
* "Trespasser", "Fire alarm". The list belongs to one site. Every route on
|
|
7786
|
+
* `/api/occurrence-subjects` carried `requireAuth` and nothing more, and this
|
|
7787
|
+
* controller held no authorization identifier of any kind, so being signed in
|
|
7788
|
+
* anywhere on the platform was enough to read another client's subject list,
|
|
7789
|
+
* add a heading to it, rename one, or delete one out from under the guards
|
|
7790
|
+
* who are picking from it.
|
|
7791
|
+
*
|
|
7792
|
+
* Two defects, not one:
|
|
7793
|
+
*
|
|
7794
|
+
* 1. **No scope.** The estate is the scope, and the rule is the existing
|
|
7795
|
+
* `requireSiteReach` -> `entitleSite` that `/api/occurrence-books`,
|
|
7796
|
+
* `/api/occurrence-entries`, `/api/work-orders`, `/api/feedbacks` and the
|
|
7797
|
+
* rest already use. The `customer.sites` branch is load-bearing: the guards
|
|
7798
|
+
* who maintain this list are the contracted security agency's staff and
|
|
7799
|
+
* hold no membership in the estate's own organisation.
|
|
7800
|
+
* 2. **Identity from the caller's body.** `POST /` took `addedBy` straight out
|
|
7801
|
+
* of the request body and never compared it to the session, so a subject
|
|
7802
|
+
* could be filed under somebody else's name. It comes from `callerId(req)`
|
|
7803
|
+
* now. This is the same defect already fixed on `/api/attendances`,
|
|
7804
|
+
* `/api/site-entrypass-settings` and `/api/feedbacks`.
|
|
7805
|
+
*
|
|
7806
|
+
* - `POST /` and `GET /` already REQUIRE a site (`schemaOccurrenceSubject` and
|
|
7807
|
+
* the query schema both have `site` required), so the guard checks a site
|
|
7808
|
+
* the request already names and no caller's contract changes.
|
|
7809
|
+
* - `GET /id/:id`, `PUT /id/:id` and `DELETE /id/:id` name only a record, so
|
|
7810
|
+
* the site is read off the STORED row via `requireOccurrenceSubjectReach`.
|
|
7811
|
+
*
|
|
7812
|
+
* `PUT /id/:id` cannot MOVE a subject: `schemaUpdateOccurrenceSubject` accepts
|
|
7813
|
+
* only `_id` and `subject`, so there is no destination to check.
|
|
7814
|
+
*/
|
|
7745
7815
|
declare function useOccurrenceSubjectController(): {
|
|
7746
7816
|
add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
7747
7817
|
getAll: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -8551,6 +8551,14 @@ function useOccurrenceEntryRepo() {
|
|
|
8551
8551
|
throw error;
|
|
8552
8552
|
}
|
|
8553
8553
|
}
|
|
8554
|
+
async function getRawOccurrenceEntryById(_id) {
|
|
8555
|
+
try {
|
|
8556
|
+
_id = new import_mongodb8.ObjectId(_id);
|
|
8557
|
+
} catch (error) {
|
|
8558
|
+
throw new import_node_server_utils9.BadRequestError("Invalid occurrence entry ID format.");
|
|
8559
|
+
}
|
|
8560
|
+
return await collection.findOne({ _id });
|
|
8561
|
+
}
|
|
8554
8562
|
async function getOccurrenceEntryByBookId(dailyOccurrenceBookId) {
|
|
8555
8563
|
try {
|
|
8556
8564
|
dailyOccurrenceBookId = new import_mongodb8.ObjectId(dailyOccurrenceBookId);
|
|
@@ -8770,6 +8778,7 @@ function useOccurrenceEntryRepo() {
|
|
|
8770
8778
|
add,
|
|
8771
8779
|
getAll,
|
|
8772
8780
|
getOccurrenceEntryById,
|
|
8781
|
+
getRawOccurrenceEntryById,
|
|
8773
8782
|
getOccurrenceEntryByBookId,
|
|
8774
8783
|
updateOccurrenceEntryById,
|
|
8775
8784
|
updateUserNameBySignatureId,
|
|
@@ -71289,6 +71298,14 @@ function useOccurrenceSubjectRepo() {
|
|
|
71289
71298
|
throw error;
|
|
71290
71299
|
}
|
|
71291
71300
|
}
|
|
71301
|
+
async function getRawOccurrenceSubjectById(_id) {
|
|
71302
|
+
try {
|
|
71303
|
+
_id = new import_mongodb137.ObjectId(_id);
|
|
71304
|
+
} catch (error) {
|
|
71305
|
+
throw new import_node_server_utils218.BadRequestError("Invalid occurrence subject ID format.");
|
|
71306
|
+
}
|
|
71307
|
+
return await collection.findOne({ _id });
|
|
71308
|
+
}
|
|
71292
71309
|
async function updateOccurrenceSubjectById(_id, value, session) {
|
|
71293
71310
|
value.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
71294
71311
|
try {
|
|
@@ -71353,6 +71370,7 @@ function useOccurrenceSubjectRepo() {
|
|
|
71353
71370
|
add,
|
|
71354
71371
|
getAll,
|
|
71355
71372
|
getOccurrenceSubjectById,
|
|
71373
|
+
getRawOccurrenceSubjectById,
|
|
71356
71374
|
updateOccurrenceSubjectById,
|
|
71357
71375
|
deleteOccurrenceSubjectById,
|
|
71358
71376
|
createIndexes,
|
|
@@ -71486,9 +71504,19 @@ function useOccurrenceEntryController() {
|
|
|
71486
71504
|
const {
|
|
71487
71505
|
getAll: _getAll,
|
|
71488
71506
|
getOccurrenceEntryById: _getOccurrenceEntryById,
|
|
71507
|
+
getRawOccurrenceEntryById: _getRawOccurrenceEntryById,
|
|
71489
71508
|
deleteOccurrenceEntryById: _deleteOccurrenceEntryById,
|
|
71490
71509
|
getLatestSerialNumber: _getLatestSerialNumber
|
|
71491
71510
|
} = useOccurrenceEntryRepo();
|
|
71511
|
+
const { getOccurrenceBookById: _getOccurrenceBookById } = useOccurrenceBookRepo();
|
|
71512
|
+
async function requireOccurrenceEntryReach(req, _id) {
|
|
71513
|
+
const row = await _getRawOccurrenceEntryById(_id);
|
|
71514
|
+
await requireSiteReach(req, row?.site);
|
|
71515
|
+
}
|
|
71516
|
+
async function requireOccurrenceBookSiteReach(req, bookId) {
|
|
71517
|
+
const book = await _getOccurrenceBookById(bookId);
|
|
71518
|
+
await requireSiteReach(req, book?.site);
|
|
71519
|
+
}
|
|
71492
71520
|
async function add(req, res, next) {
|
|
71493
71521
|
try {
|
|
71494
71522
|
const { error, value } = schemaOccurrenceEntry.validate(req.body, {
|
|
@@ -71500,6 +71528,7 @@ function useOccurrenceEntryController() {
|
|
|
71500
71528
|
next(new import_node_server_utils220.BadRequestError(messages));
|
|
71501
71529
|
return;
|
|
71502
71530
|
}
|
|
71531
|
+
await requireSiteReach(req, value.site);
|
|
71503
71532
|
const data = await _add(value);
|
|
71504
71533
|
res.status(201).json(data);
|
|
71505
71534
|
return;
|
|
@@ -71533,6 +71562,7 @@ function useOccurrenceEntryController() {
|
|
|
71533
71562
|
const sortObj = {
|
|
71534
71563
|
[sort ? sort : "_id" /* ID */]: order === "asc" /* ASC */ ? 1 : -1
|
|
71535
71564
|
};
|
|
71565
|
+
await requireSiteReach(req, site);
|
|
71536
71566
|
const data = await _getAll({
|
|
71537
71567
|
search,
|
|
71538
71568
|
page,
|
|
@@ -71561,6 +71591,7 @@ function useOccurrenceEntryController() {
|
|
|
71561
71591
|
return;
|
|
71562
71592
|
}
|
|
71563
71593
|
const { _id } = value;
|
|
71594
|
+
await requireOccurrenceEntryReach(req, _id);
|
|
71564
71595
|
const data = await _getOccurrenceEntryById(_id);
|
|
71565
71596
|
res.status(200).json(data);
|
|
71566
71597
|
return;
|
|
@@ -71583,6 +71614,7 @@ function useOccurrenceEntryController() {
|
|
|
71583
71614
|
return;
|
|
71584
71615
|
}
|
|
71585
71616
|
const { _id, ...rest } = value;
|
|
71617
|
+
await requireOccurrenceEntryReach(req, _id);
|
|
71586
71618
|
const result = await _updateOccurrenceEntryById(_id, rest);
|
|
71587
71619
|
res.status(200).json({ message: result });
|
|
71588
71620
|
return;
|
|
@@ -71604,6 +71636,7 @@ function useOccurrenceEntryController() {
|
|
|
71604
71636
|
return;
|
|
71605
71637
|
}
|
|
71606
71638
|
const { _id } = value;
|
|
71639
|
+
await requireOccurrenceEntryReach(req, _id);
|
|
71607
71640
|
await _deleteOccurrenceEntryById(_id);
|
|
71608
71641
|
res.status(200).json({ message: "Successfully deleted occurrence entry." });
|
|
71609
71642
|
return;
|
|
@@ -71623,6 +71656,7 @@ function useOccurrenceEntryController() {
|
|
|
71623
71656
|
return;
|
|
71624
71657
|
}
|
|
71625
71658
|
try {
|
|
71659
|
+
await requireOccurrenceBookSiteReach(req, _id);
|
|
71626
71660
|
const data = await _getLatestSerialNumber(_id);
|
|
71627
71661
|
res.status(200).json({ count: data });
|
|
71628
71662
|
return;
|
|
@@ -72243,8 +72277,13 @@ function useOccurrenceSubjectController() {
|
|
|
72243
72277
|
const {
|
|
72244
72278
|
getAll: _getAll,
|
|
72245
72279
|
getOccurrenceSubjectById: _getOccurrenceSubjectById,
|
|
72280
|
+
getRawOccurrenceSubjectById: _getRawOccurrenceSubjectById,
|
|
72246
72281
|
deleteOccurrenceSubjectById: _deleteOccurrenceSubjectById
|
|
72247
72282
|
} = useOccurrenceSubjectRepo();
|
|
72283
|
+
async function requireOccurrenceSubjectReach(req, _id) {
|
|
72284
|
+
const row = await _getRawOccurrenceSubjectById(_id);
|
|
72285
|
+
await requireSiteReach(req, row?.site);
|
|
72286
|
+
}
|
|
72248
72287
|
async function add(req, res, next) {
|
|
72249
72288
|
try {
|
|
72250
72289
|
const { error, value } = schemaOccurrenceSubject.validate(req.body, {
|
|
@@ -72256,7 +72295,8 @@ function useOccurrenceSubjectController() {
|
|
|
72256
72295
|
next(new import_node_server_utils224.BadRequestError(messages));
|
|
72257
72296
|
return;
|
|
72258
72297
|
}
|
|
72259
|
-
|
|
72298
|
+
await requireSiteReach(req, value.site);
|
|
72299
|
+
const data = await _add({ ...value, addedBy: callerId(req) });
|
|
72260
72300
|
res.status(201).json(data);
|
|
72261
72301
|
return;
|
|
72262
72302
|
} catch (error) {
|
|
@@ -72285,6 +72325,7 @@ function useOccurrenceSubjectController() {
|
|
|
72285
72325
|
return;
|
|
72286
72326
|
}
|
|
72287
72327
|
const { search, page, limit, site, sort, order } = value;
|
|
72328
|
+
await requireSiteReach(req, site);
|
|
72288
72329
|
const sortObj = {
|
|
72289
72330
|
[sort ? sort : "_id" /* ID */]: order === "asc" /* ASC */ ? 1 : -1
|
|
72290
72331
|
};
|
|
@@ -72315,6 +72356,7 @@ function useOccurrenceSubjectController() {
|
|
|
72315
72356
|
return;
|
|
72316
72357
|
}
|
|
72317
72358
|
const { _id } = value;
|
|
72359
|
+
await requireOccurrenceSubjectReach(req, _id);
|
|
72318
72360
|
const data = await _getOccurrenceSubjectById(_id);
|
|
72319
72361
|
res.status(200).json(data);
|
|
72320
72362
|
return;
|
|
@@ -72339,6 +72381,7 @@ function useOccurrenceSubjectController() {
|
|
|
72339
72381
|
return;
|
|
72340
72382
|
}
|
|
72341
72383
|
const { _id, ...rest } = value;
|
|
72384
|
+
await requireOccurrenceSubjectReach(req, _id);
|
|
72342
72385
|
const result = await _updateOccurrenceSubjectById(_id, rest);
|
|
72343
72386
|
res.status(200).json({ message: result });
|
|
72344
72387
|
return;
|
|
@@ -72358,6 +72401,7 @@ function useOccurrenceSubjectController() {
|
|
|
72358
72401
|
return;
|
|
72359
72402
|
}
|
|
72360
72403
|
try {
|
|
72404
|
+
await requireOccurrenceSubjectReach(req, _id);
|
|
72361
72405
|
await _deleteOccurrenceSubjectById(_id);
|
|
72362
72406
|
res.status(200).json({ message: "Successfully deleted occurrence subject." });
|
|
72363
72407
|
return;
|