@7365admin1/core 3.48.1-staging.174 → 3.48.1-staging.176
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/site-billing-configuration-scope.md +5 -0
- package/.changeset/site-billing-item-scope.md +5 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +28 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +42 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/harness.mjs +28 -0
- package/test/e2e/site-billing-configuration-scope.e2e.test.mjs +422 -0
- package/test/e2e/site-billing-item-scope.e2e.test.mjs +518 -0
package/dist/index.d.ts
CHANGED
|
@@ -6171,6 +6171,30 @@ declare function useSiteBillingItemRepo(): {
|
|
|
6171
6171
|
createIndexes: () => Promise<string>;
|
|
6172
6172
|
};
|
|
6173
6173
|
|
|
6174
|
+
/**
|
|
6175
|
+
* A billing item is a charge the estate raises on its residents — the name, the
|
|
6176
|
+
* amount, the tax that rides on it, how often it repeats, and which units it is
|
|
6177
|
+
* attached to.
|
|
6178
|
+
*
|
|
6179
|
+
* All five handlers carried `requireAuth` and nothing else, and the controller
|
|
6180
|
+
* held no authorization identifier of any kind. The record id came from the URL
|
|
6181
|
+
* and the site came from the caller's own query or body, so any signed-in
|
|
6182
|
+
* account on the platform could list another client's charges, add a charge to
|
|
6183
|
+
* their estate, change what a charge costs, MOVE a charge onto a different
|
|
6184
|
+
* estate (`site` is writable on the update schema), or delete it.
|
|
6185
|
+
*
|
|
6186
|
+
* The rule is the existing one — `requireSiteReach`, i.e. `entitleSite` — asked
|
|
6187
|
+
* about the site the request names on the way in, and about the STORED site for
|
|
6188
|
+
* the id routes, which name no site at all. `PUT` asks twice, once about where
|
|
6189
|
+
* the record is and once about where the body wants to move it, because a MOVE
|
|
6190
|
+
* needs its destination checked too. This is the same shape as
|
|
6191
|
+
* `site-billing-configuration.controller.ts`, not a second mechanism.
|
|
6192
|
+
*
|
|
6193
|
+
* The unit list is checked separately, in the service — see
|
|
6194
|
+
* `site-billing-item.service.ts`. Reaching a site is not the same question as
|
|
6195
|
+
* "do these units belong to it", and the service is where the unit ids are
|
|
6196
|
+
* actually consumed.
|
|
6197
|
+
*/
|
|
6174
6198
|
declare function useSiteBillingItemController(): {
|
|
6175
6199
|
add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
6176
6200
|
getAll: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
@@ -6253,6 +6277,23 @@ declare function useSiteBillingConfigurationRepo(): {
|
|
|
6253
6277
|
createIndexes: () => Promise<string>;
|
|
6254
6278
|
};
|
|
6255
6279
|
|
|
6280
|
+
/**
|
|
6281
|
+
* Billing configuration is per-estate — the tax rate, the rounding and the
|
|
6282
|
+
* payment settings every bill at that site is calculated from.
|
|
6283
|
+
*
|
|
6284
|
+
* Every one of these five handlers carried `requireAuth` and nothing else. The
|
|
6285
|
+
* record id came from the URL and the site came from the caller's own query or
|
|
6286
|
+
* body, so any signed-in account on the platform could read another client's
|
|
6287
|
+
* billing settings, change their tax rate, move a configuration to a different
|
|
6288
|
+
* estate, or delete it. `createdBy` was read off the raw `user` COOKIE with a
|
|
6289
|
+
* fall back to the body, so the "who set this up" name was client-supplied.
|
|
6290
|
+
*
|
|
6291
|
+
* The rule is the existing one — `requireSiteReach`, i.e. `entitleSite` — asked
|
|
6292
|
+
* about the site the request names on the way in, and about the STORED site for
|
|
6293
|
+
* the id routes, which name no site at all. `PUT` asks twice: once about where
|
|
6294
|
+
* the record is and once about where the body wants to move it, because a MOVE
|
|
6295
|
+
* needs the destination checked too. `createdBy` now comes from the session.
|
|
6296
|
+
*/
|
|
6256
6297
|
declare function useSiteBillingConfigurationController(): {
|
|
6257
6298
|
add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
6258
6299
|
getAll: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -58520,6 +58520,12 @@ function useSiteBillingItemService() {
|
|
|
58520
58520
|
} = useSiteBillingItemRepo();
|
|
58521
58521
|
const { updateById: _updateBuildingUnitById, getById: _getById } = useBuildingUnitRepo();
|
|
58522
58522
|
const { getAll } = useSiteBillingConfigurationRepo();
|
|
58523
|
+
function assertUnitAtSite(buildingUnit, site) {
|
|
58524
|
+
const siteId = site?.toString?.() ?? "";
|
|
58525
|
+
if (!siteId || (buildingUnit?.site?.toString() ?? "") !== siteId) {
|
|
58526
|
+
throw new import_node_server_utils179.UnauthorizedError("Not authorized.");
|
|
58527
|
+
}
|
|
58528
|
+
}
|
|
58523
58529
|
async function add(value) {
|
|
58524
58530
|
const session = import_node_server_utils179.useAtlas.getClient()?.startSession();
|
|
58525
58531
|
if (!session) {
|
|
@@ -58550,6 +58556,7 @@ function useSiteBillingItemService() {
|
|
|
58550
58556
|
const promises = value.units.map(async (unit) => {
|
|
58551
58557
|
const unitId = unit?._id?.toString() || "";
|
|
58552
58558
|
const buildingUnit = await _getById(unitId);
|
|
58559
|
+
assertUnitAtSite(buildingUnit, value.site);
|
|
58553
58560
|
const normalizedExistingBilling = (buildingUnit.billing || []).map(
|
|
58554
58561
|
(bill) => ({
|
|
58555
58562
|
_id: bill._id?.toString(),
|
|
@@ -58646,6 +58653,7 @@ function useSiteBillingItemService() {
|
|
|
58646
58653
|
unit._id?.toString() || "",
|
|
58647
58654
|
session
|
|
58648
58655
|
);
|
|
58656
|
+
assertUnitAtSite(buildingUnit, value.site ?? billing_item?.site);
|
|
58649
58657
|
const normalizedBilling = (buildingUnit.billing || []).map(
|
|
58650
58658
|
(bill) => ({
|
|
58651
58659
|
_id: bill._id?.toString() || "",
|
|
@@ -58686,7 +58694,7 @@ function useSiteBillingItemService() {
|
|
|
58686
58694
|
message: error.message
|
|
58687
58695
|
});
|
|
58688
58696
|
await session.abortTransaction();
|
|
58689
|
-
if (error instanceof import_node_server_utils179.BadRequestError) {
|
|
58697
|
+
if (error instanceof import_node_server_utils179.BadRequestError || error instanceof import_node_server_utils179.UnauthorizedError) {
|
|
58690
58698
|
throw error;
|
|
58691
58699
|
}
|
|
58692
58700
|
throw new import_node_server_utils179.BadRequestError("Failed to update Site Billing Item.");
|
|
@@ -58717,6 +58725,7 @@ function useSiteBillingItemController() {
|
|
|
58717
58725
|
return;
|
|
58718
58726
|
}
|
|
58719
58727
|
try {
|
|
58728
|
+
await requireSiteReach(req, value.site);
|
|
58720
58729
|
const question = await _add(value);
|
|
58721
58730
|
res.status(201).json({
|
|
58722
58731
|
message: "Site Billing Item added successfully.",
|
|
@@ -58761,6 +58770,7 @@ function useSiteBillingItemController() {
|
|
|
58761
58770
|
}
|
|
58762
58771
|
});
|
|
58763
58772
|
try {
|
|
58773
|
+
await requireSiteReach(req, site);
|
|
58764
58774
|
const data = await _getAll({
|
|
58765
58775
|
search,
|
|
58766
58776
|
page,
|
|
@@ -58789,6 +58799,7 @@ function useSiteBillingItemController() {
|
|
|
58789
58799
|
}
|
|
58790
58800
|
try {
|
|
58791
58801
|
const building = await _getById(id);
|
|
58802
|
+
await requireSiteReach(req, building?.site);
|
|
58792
58803
|
res.json({
|
|
58793
58804
|
message: "Successfully retrieved site billing item.",
|
|
58794
58805
|
data: { building }
|
|
@@ -58811,6 +58822,10 @@ function useSiteBillingItemController() {
|
|
|
58811
58822
|
return;
|
|
58812
58823
|
}
|
|
58813
58824
|
try {
|
|
58825
|
+
const current = await _getById(_id);
|
|
58826
|
+
await requireSiteReach(req, current?.site);
|
|
58827
|
+
if (req.body?.site)
|
|
58828
|
+
await requireSiteReach(req, req.body.site);
|
|
58814
58829
|
const result = await _updateById(_id, req.body);
|
|
58815
58830
|
res.status(200).json({ message: result });
|
|
58816
58831
|
return;
|
|
@@ -58830,6 +58845,8 @@ function useSiteBillingItemController() {
|
|
|
58830
58845
|
return;
|
|
58831
58846
|
}
|
|
58832
58847
|
try {
|
|
58848
|
+
const current = await _getById(_id);
|
|
58849
|
+
await requireSiteReach(req, current?.site);
|
|
58833
58850
|
await _deleteById(_id);
|
|
58834
58851
|
res.status(200).json({ message: "Successfully deleted site billing item." });
|
|
58835
58852
|
return;
|
|
@@ -58897,11 +58914,6 @@ function useSiteBillingConfigurationController() {
|
|
|
58897
58914
|
} = useSiteBillingConfigurationRepo();
|
|
58898
58915
|
const { add: _add } = useSiteBillingConfigurationService();
|
|
58899
58916
|
async function add(req, res, next) {
|
|
58900
|
-
const cookies = req.headers.cookie?.split(";").map((cookie) => cookie.trim().split("=")).reduce(
|
|
58901
|
-
(acc, [key, value2]) => ({ ...acc, [key]: value2 }),
|
|
58902
|
-
{}
|
|
58903
|
-
);
|
|
58904
|
-
req.body.createdBy = cookies?.["user"] ? cookies["user"].toString() : req.body.createdBy;
|
|
58905
58917
|
const data = { ...req.body };
|
|
58906
58918
|
const { error, value } = schemaBillingConfiguration.validate(data);
|
|
58907
58919
|
if (error) {
|
|
@@ -58909,7 +58921,8 @@ function useSiteBillingConfigurationController() {
|
|
|
58909
58921
|
return;
|
|
58910
58922
|
}
|
|
58911
58923
|
try {
|
|
58912
|
-
|
|
58924
|
+
await requireSiteReach(req, value.site);
|
|
58925
|
+
const question = await _add({ ...value, createdBy: callerId(req) });
|
|
58913
58926
|
res.status(201).json({
|
|
58914
58927
|
message: "Site Billing Configuration added successfully.",
|
|
58915
58928
|
data: question
|
|
@@ -58953,6 +58966,7 @@ function useSiteBillingConfigurationController() {
|
|
|
58953
58966
|
}
|
|
58954
58967
|
});
|
|
58955
58968
|
try {
|
|
58969
|
+
await requireSiteReach(req, site);
|
|
58956
58970
|
const data = await _getAll({
|
|
58957
58971
|
search,
|
|
58958
58972
|
page,
|
|
@@ -58981,6 +58995,7 @@ function useSiteBillingConfigurationController() {
|
|
|
58981
58995
|
}
|
|
58982
58996
|
try {
|
|
58983
58997
|
const building = await _getById(id);
|
|
58998
|
+
await requireSiteReach(req, building?.site);
|
|
58984
58999
|
res.json({
|
|
58985
59000
|
message: "Successfully retrieved site billing configuration.",
|
|
58986
59001
|
data: { building }
|
|
@@ -59003,6 +59018,10 @@ function useSiteBillingConfigurationController() {
|
|
|
59003
59018
|
return;
|
|
59004
59019
|
}
|
|
59005
59020
|
try {
|
|
59021
|
+
const current = await _getById(_id);
|
|
59022
|
+
await requireSiteReach(req, current?.site);
|
|
59023
|
+
if (req.body?.site)
|
|
59024
|
+
await requireSiteReach(req, req.body.site);
|
|
59006
59025
|
const result = await _updateById(_id, req.body);
|
|
59007
59026
|
res.status(200).json({ message: result });
|
|
59008
59027
|
return;
|
|
@@ -59022,6 +59041,8 @@ function useSiteBillingConfigurationController() {
|
|
|
59022
59041
|
return;
|
|
59023
59042
|
}
|
|
59024
59043
|
try {
|
|
59044
|
+
const current = await _getById(_id);
|
|
59045
|
+
await requireSiteReach(req, current?.site);
|
|
59025
59046
|
await _deleteById(_id);
|
|
59026
59047
|
res.status(200).json({ message: "Successfully deleted site billing configuration." });
|
|
59027
59048
|
return;
|