Skip to content

Commit 1c500d0

Browse files
authored
Merge pull request #39 from windingtree/feat/leveldb
Feat/leveldb
2 parents 98be7c6 + ca3f032 commit 1c500d0

25 files changed

+1487
-311
lines changed

docs/STORAGE.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ Notes: This meets the requirement (2)
102102
Parent level: `facilityId` (dynamic)
103103
Level: `spaceId` (dynamic)
104104

105-
Key: `metadata_generic`
105+
Key: `metadata`
106106
Value: `videre.stays.lpms.facility.Item`
107107
Description: Contains generic data for each item (name, photos etc)
108108

109-
Key: `metadata`
109+
Key: `metadata_impl`
110110
Value: `videre.stays.lpms.facility.Space`
111111
Description: Contains specific metadata for Spaces (views, sleeping arrangements etc).
112112

@@ -185,12 +185,25 @@ Notes: This meets the requirement (4)
185185
#### otherItems
186186

187187
Parent level: `facilityId` (dynamic)
188-
Level: `otherItems`
188+
Level: `otherItemdId` (dynamic)
189189

190-
Key: `itemId` (dynamic)
190+
Key: `metadata` (dynamic)
191191
Value: `videre.stays.lpms.facility.Item`
192192
Description: Contains generic data for the item (name, photos, etc)
193193

194+
##### rates
195+
196+
Parent level: `facilityId.otherItemdId` (dynamic)
197+
Level: `rates`
198+
199+
Key: `default`
200+
Value: `videre.stays.lpms.Rates`
201+
Description: Contains the `Rates` message protobuf describing the rate for this item.
202+
203+
Key: `YYYY-MM-DD` (dynamic)
204+
Value: `videre.stays.lpms.Rates`
205+
Description: Contains the `Rates` message protobuf for a per-day override of rates.
206+
194207
# CRUD
195208

196209
## Stubs (booking)
@@ -251,8 +264,8 @@ let items: ServiceItemData[];
251264
const spaces = db.get('facilityId.spaces'); // insert correct leveldb query here
252265
for (const space of object) {
253266
// get generic metadata
254-
const generic = db.get(`${facilityId}.${space}.metadata_generic`) as Item;
255-
const specific = db.get(`${facilityId}.${space}.metadata`) as Space;
267+
const generic = db.get(`${facilityId}.${space}.metadata`) as Item;
268+
const specific = db.get(`${facilityId}.${space}.metadata_impl`) as Space;
256269
generic.payload = Space.toBinary(specific);
257270

258271
items.push({
@@ -264,7 +277,7 @@ for (const space of object) {
264277
// process all other items
265278
const otherItems = db.get('facilityId.otherItems') as Item[];
266279
for (const item of otherItems) {
267-
const otherItem = db.get(`${facilityId}.otherItems.${item}`) as Item;
280+
const otherItem = db.get(`${facilityId}.${item}.metadata`) as Item;
268281
items.push({
269282
item: utils.arrayify(utils.formatBytes32String(item)),
270283
payload: Item.toBinary(otherItem)

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
},
4343
"dependencies": {
4444
"@protobuf-ts/plugin": "^2.6.0",
45-
"@windingtree/stays-models": "^2.0.0",
45+
"@windingtree/stays-models": "^2.0.1",
4646
"@windingtree/videre-sdk": "^0.5.0",
4747
"axios": "^0.27.2",
4848
"bcrypt": "^5.0.1",
@@ -88,7 +88,7 @@
8888
"@types/luxon": "^2.3.2",
8989
"@typescript-eslint/eslint-plugin": "^5.27.0",
9090
"@typescript-eslint/parser": "^5.27.0",
91-
"@windingtree/videre-contracts": "^0.2.0-alpha.1",
91+
"@windingtree/videre-contracts": "^1.0.2",
9292
"chai": "^4.3.6",
9393
"conventional-changelog-cli": "^2.2.2",
9494
"eslint": "^8.16.0",

src/controllers/FacilityController.ts

Lines changed: 163 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
import type { NextFunction, Request, Response } from 'express';
2-
import type { AvailabilityDate } from '../services/DBService';
2+
import type {
3+
FacilityIndexKey,
4+
FormattedDate,
5+
ModifiersKey,
6+
ModifiersValues
7+
} from '../services/DBService';
38
import { DateTime } from 'luxon';
49
import ApiError from '../exceptions/ApiError';
510
import { SpaceAvailabilityRepository } from '../repositories/SpaceAvailabilityRepository';
11+
import {
12+
FacilityModifierRepository,
13+
ItemModifierRepository
14+
} from '../repositories/ModifierRepository';
615

716
export class FacilityController {
817
// Returns availability of the space
@@ -15,8 +24,8 @@ export class FacilityController {
1524
const { facilityId, spaceId, date } = req.params;
1625

1726
const repository = new SpaceAvailabilityRepository(facilityId, spaceId);
18-
const numSpaces = await repository.getSpaceAvailabilityNumSpaces(
19-
date as AvailabilityDate
27+
const numSpaces = await repository.getSpaceAvailability(
28+
date as FormattedDate
2029
);
2130

2231
return res.json({ numSpaces });
@@ -40,10 +49,9 @@ export class FacilityController {
4049
}
4150

4251
const repository = new SpaceAvailabilityRepository(facilityId, spaceId);
43-
await repository.createAvailabilityByDate(
44-
date as AvailabilityDate,
45-
Number(numSpaces)
46-
);
52+
await repository.setAvailabilityByDate(date as FormattedDate, {
53+
numSpaces: Number(numSpaces)
54+
});
4755

4856
return res.json({ success: true });
4957
} catch (e) {
@@ -62,13 +70,160 @@ export class FacilityController {
6270
const { numSpaces } = req.body;
6371

6472
const repository = new SpaceAvailabilityRepository(facilityId, spaceId);
65-
await repository.createDefaultAvailability(Number(numSpaces));
73+
await repository.setAvailabilityDefault({ numSpaces: Number(numSpaces) });
6674

6775
return res.json({ success: true });
6876
} catch (e) {
6977
next(e);
7078
}
7179
};
80+
81+
// Returns modifier of facility
82+
getModifierOfFacility = async (
83+
req: Request,
84+
res: Response,
85+
next: NextFunction
86+
) => {
87+
try {
88+
const { facilityId, modifierKey } = req.params;
89+
90+
const repository = new FacilityModifierRepository(facilityId);
91+
const modifier = await repository.getModifier(
92+
modifierKey as ModifiersKey
93+
);
94+
95+
res.json(modifier);
96+
} catch (e) {
97+
next(e);
98+
}
99+
};
100+
101+
// Returns modifier of the item: `spaces` or `otherItems`
102+
getModifierOfItem = async (
103+
req: Request,
104+
res: Response,
105+
next: NextFunction
106+
) => {
107+
try {
108+
const { facilityId, itemKey, itemId, modifierKey } = req.params;
109+
110+
const repository = new ItemModifierRepository(
111+
facilityId,
112+
itemKey as FacilityIndexKey,
113+
itemId
114+
);
115+
116+
let modifier: ModifiersValues;
117+
118+
try {
119+
modifier = await repository.getModifier(modifierKey as ModifiersKey);
120+
} catch (e) {
121+
if (e.status !== 404) {
122+
throw e;
123+
}
124+
125+
// If item does not contain such modifier then try to lookup the facility
126+
const facilityRepository = new FacilityModifierRepository(facilityId);
127+
modifier = await facilityRepository.getModifier(
128+
modifierKey as ModifiersKey
129+
);
130+
}
131+
132+
res.json(modifier);
133+
} catch (e) {
134+
next(e);
135+
}
136+
};
137+
138+
// Creates a modifier for the facility
139+
createFacilityModifier = async (
140+
req: Request,
141+
res: Response,
142+
next: NextFunction
143+
) => {
144+
try {
145+
const { facilityId, modifierKey } = req.params;
146+
const modifier = req.body;
147+
148+
const repository = new FacilityModifierRepository(facilityId);
149+
await repository.setModifier(
150+
modifierKey as ModifiersKey,
151+
modifier as ModifiersValues
152+
);
153+
154+
res.json({ success: true });
155+
} catch (e) {
156+
next(e);
157+
}
158+
};
159+
160+
// Creates a modifier for the item: spaces or otherItems
161+
createItemModifier = async (
162+
req: Request,
163+
res: Response,
164+
next: NextFunction
165+
) => {
166+
try {
167+
const { facilityId, itemKey, itemId, modifierKey } = req.params;
168+
const modifier = req.body;
169+
170+
const repository = new ItemModifierRepository(
171+
facilityId,
172+
itemKey as FacilityIndexKey,
173+
itemId
174+
);
175+
176+
await repository.setModifier(
177+
modifierKey as ModifiersKey,
178+
modifier as ModifiersValues
179+
);
180+
181+
res.json({ success: true });
182+
} catch (e) {
183+
next(e);
184+
}
185+
};
186+
187+
// Removes a modifier from the facility
188+
removeModifierOfFacility = async (
189+
req: Request,
190+
res: Response,
191+
next: NextFunction
192+
) => {
193+
try {
194+
const { facilityId, modifierKey } = req.params;
195+
196+
const repository = new FacilityModifierRepository(facilityId);
197+
await repository.delModifier(modifierKey as ModifiersKey);
198+
199+
res.json({ success: true });
200+
} catch (e) {
201+
next(e);
202+
}
203+
};
204+
205+
// Removes modifier of the item: `spaces` or `otherItems`
206+
removeModifierOfItem = async (
207+
req: Request,
208+
res: Response,
209+
next: NextFunction
210+
) => {
211+
try {
212+
const { facilityId, itemKey, itemId, modifierKey } = req.params;
213+
214+
const repository = new ItemModifierRepository(
215+
facilityId,
216+
itemKey as FacilityIndexKey,
217+
itemId
218+
);
219+
220+
await repository.delModifier(modifierKey as ModifiersKey);
221+
222+
res.json({ success: true });
223+
} catch (e) {
224+
next(e);
225+
}
226+
};
72227
}
73228

74229
export default new FacilityController();

src/controllers/StorageController.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { web3StorageKey, typedDataDomain } from '../config';
1212
import { walletAccountsIndexes } from '../types';
1313
import { Facility, Item, ItemType, Space } from '../proto/facility';
1414
import facilityService from '../services/FacilityService';
15-
import { FacilitySpaceLevelValues } from 'src/services/DBService';
15+
import { FacilitySpaceValues } from 'src/services/DBService';
1616
const { readFile } = promises;
1717

1818
export class StorageController {
@@ -75,7 +75,7 @@ export class StorageController {
7575
]);
7676

7777
// Extract spaces from metadata
78-
const spaces: Record<string, [string, FacilitySpaceLevelValues][]> = {};
78+
const spaces: Record<string, [string, FacilitySpaceValues][]> = {};
7979
const otherItems: Record<string, [string, Item][]> = {};
8080

8181
for (const item of serviceProviderData.items) {
@@ -84,11 +84,14 @@ export class StorageController {
8484

8585
if (type === ItemType.SPACE) {
8686
spaces[itemId] = [
87-
['metadata_generic', generic as Item],
88-
['metadata', (payload ? Space.fromBinary(payload) : {}) as Space]
87+
['metadata', generic as Item],
88+
[
89+
'metadata_impl',
90+
(payload ? Space.fromBinary(payload) : {}) as Space
91+
]
8992
];
9093
} else {
91-
otherItems[itemId] = [['metadata_generic', generic as Item]];
94+
otherItems[itemId] = [['metadata', generic as Item]];
9295
}
9396
}
9497

src/exceptions/ApiError.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ export default class ApiError extends Error {
1414
return new ApiError(401, 'User is not authorized');
1515
}
1616

17-
static BadRequest(message, errors: ValidationError[] = []) {
17+
static BadRequest(message: string, errors: ValidationError[] = []) {
1818
return new ApiError(400, message, errors);
1919
}
2020

2121
static AccessDenied() {
2222
return new ApiError(403, 'Access denied');
2323
}
24+
25+
static NotFound(message: string) {
26+
return new ApiError(404, message || 'Not Found');
27+
}
2428
}

src/middlewares/AuthMiddleware.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ApiError from '../exceptions/ApiError';
22
import tokenService from '../services/TokenService';
33
import userService from '../services/UserService';
4+
import userRepository from '../repositories/UserRepository';
45
import { UserDTO } from '../types';
56

67
export default async (req, res, next) => {
@@ -21,13 +22,13 @@ export default async (req, res, next) => {
2122
return next(ApiError.UnauthorizedError());
2223
}
2324

24-
const userExists = await userService.getUserIdByLogin(userData.login);
25+
const userExists = await userRepository.getUserIdByLogin(userData.login);
2526

2627
if (!userExists) {
2728
return next(ApiError.UnauthorizedError());
2829
}
2930

30-
const user = await userService.getUserById(userData.id);
31+
const user = await userRepository.getUserById(userData.id);
3132
req.user = userService.getUserDTO(user);
3233
next();
3334
} catch (e) {

0 commit comments

Comments
 (0)