Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions docs/STORAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ Notes: This meets the requirement (2)
Parent level: `facilityId` (dynamic)
Level: `spaceId` (dynamic)

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

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

Expand Down Expand Up @@ -185,12 +185,25 @@ Notes: This meets the requirement (4)
#### otherItems

Parent level: `facilityId` (dynamic)
Level: `otherItems`
Level: `otherItemdId` (dynamic)

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

##### rates

Parent level: `facilityId.otherItemdId` (dynamic)
Level: `rates`

Key: `default`
Value: `videre.stays.lpms.Rates`
Description: Contains the `Rates` message protobuf describing the rate for this item.

Key: `YYYY-MM-DD` (dynamic)
Value: `videre.stays.lpms.Rates`
Description: Contains the `Rates` message protobuf for a per-day override of rates.

# CRUD

## Stubs (booking)
Expand Down Expand Up @@ -251,8 +264,8 @@ let items: ServiceItemData[];
const spaces = db.get('facilityId.spaces'); // insert correct leveldb query here
for (const space of object) {
// get generic metadata
const generic = db.get(`${facilityId}.${space}.metadata_generic`) as Item;
const specific = db.get(`${facilityId}.${space}.metadata`) as Space;
const generic = db.get(`${facilityId}.${space}.metadata`) as Item;
const specific = db.get(`${facilityId}.${space}.metadata_impl`) as Space;
generic.payload = Space.toBinary(specific);

items.push({
Expand All @@ -264,7 +277,7 @@ for (const space of object) {
// process all other items
const otherItems = db.get('facilityId.otherItems') as Item[];
for (const item of otherItems) {
const otherItem = db.get(`${facilityId}.otherItems.${item}`) as Item;
const otherItem = db.get(`${facilityId}.${item}.metadata`) as Item;
items.push({
item: utils.arrayify(utils.formatBytes32String(item)),
payload: Item.toBinary(otherItem)
Expand Down
15 changes: 7 additions & 8 deletions src/controllers/FacilityController.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { NextFunction, Request, Response } from 'express';
import type { AvailabilityDate } from '../services/DBService';
import type { FormattedDate } from '../services/DBService';
import { DateTime } from 'luxon';
import ApiError from '../exceptions/ApiError';
import { SpaceAvailabilityRepository } from '../repositories/SpaceAvailabilityRepository';
Expand All @@ -15,8 +15,8 @@ export class FacilityController {
const { facilityId, spaceId, date } = req.params;

const repository = new SpaceAvailabilityRepository(facilityId, spaceId);
const numSpaces = await repository.getSpaceAvailabilityNumSpaces(
date as AvailabilityDate
const numSpaces = await repository.getSpaceAvailability(
date as FormattedDate
);

return res.json({ numSpaces });
Expand All @@ -40,10 +40,9 @@ export class FacilityController {
}

const repository = new SpaceAvailabilityRepository(facilityId, spaceId);
await repository.createAvailabilityByDate(
date as AvailabilityDate,
Number(numSpaces)
);
await repository.setAvailabilityByDate(date as FormattedDate, {
numSpaces: Number(numSpaces)
});

return res.json({ success: true });
} catch (e) {
Expand All @@ -62,7 +61,7 @@ export class FacilityController {
const { numSpaces } = req.body;

const repository = new SpaceAvailabilityRepository(facilityId, spaceId);
await repository.createDefaultAvailability(Number(numSpaces));
await repository.setAvailabilityDefault({ numSpaces: Number(numSpaces) });

return res.json({ success: true });
} catch (e) {
Expand Down
13 changes: 8 additions & 5 deletions src/controllers/StorageController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { web3StorageKey, typedDataDomain } from '../config';
import { walletAccountsIndexes } from '../types';
import { Facility, Item, ItemType, Space } from '../proto/facility';
import facilityService from '../services/FacilityService';
import { FacilitySpaceLevelValues } from 'src/services/DBService';
import { FacilitySpaceValues } from 'src/services/DBService';
const { readFile } = promises;

export class StorageController {
Expand Down Expand Up @@ -75,7 +75,7 @@ export class StorageController {
]);

// Extract spaces from metadata
const spaces: Record<string, [string, FacilitySpaceLevelValues][]> = {};
const spaces: Record<string, [string, FacilitySpaceValues][]> = {};
const otherItems: Record<string, [string, Item][]> = {};

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

if (type === ItemType.SPACE) {
spaces[itemId] = [
['metadata_generic', generic as Item],
['metadata', (payload ? Space.fromBinary(payload) : {}) as Space]
['metadata', generic as Item],
[
'metadata_impl',
(payload ? Space.fromBinary(payload) : {}) as Space
]
];
} else {
otherItems[itemId] = [['metadata_generic', generic as Item]];
otherItems[itemId] = [['metadata', generic as Item]];
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/middlewares/AuthMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ApiError from '../exceptions/ApiError';
import tokenService from '../services/TokenService';
import userService from '../services/UserService';
import userRepository from '../repositories/UserRepository';
import { UserDTO } from '../types';

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

const userExists = await userService.getUserIdByLogin(userData.login);
const userExists = await userRepository.getUserIdByLogin(userData.login);

if (!userExists) {
return next(ApiError.UnauthorizedError());
}

const user = await userService.getUserById(userData.id);
const user = await userRepository.getUserById(userData.id);
req.user = userService.getUserDTO(user);
next();
} catch (e) {
Expand Down
149 changes: 134 additions & 15 deletions src/repositories/FacilityRepository.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import DBService from '../services/DBService';
import DBService, {
FacilityKey,
FacilityIndexKey,
FacilityValues,
FacilitySpaceValues
} from '../services/DBService';
import { Level } from 'level';
import { Facility } from '../proto/facility';
import { Item } from '../proto/facility';

export class FacilityRepository {
private dbService: DBService;
Expand All @@ -11,7 +16,9 @@ export class FacilityRepository {
this.db = DBService.getInstance().getDB();
}

public async getFacilityIds(): Promise<string[]> {
// --- facility index management

public async getAllFacilityIds(): Promise<string[]> {
try {
return await this.db.get<string, string[]>('facilities', {
valueEncoding: 'json'
Expand All @@ -24,26 +31,138 @@ export class FacilityRepository {
return [];
}

public async createFacility(
public async addFacilityToIndex(facilityId: string) {
const facilityIds = await this.getAllFacilityIds();

if (facilityIds.length > 0) {
const ids = new Set<string>(facilityIds);
ids.add(facilityId);
await this.db.put('facilities', Array.from(ids));
} else {
await this.db.put('facilities', [facilityId]);
}
}

public async delFacilityFromIndex(facilityId: string) {
const facilityIds = await this.getAllFacilityIds();

if (facilityIds.length > 0) {
const ids = new Set<string>(facilityIds);
if (ids.delete(facilityId)) {
await this.db.put('facilities', Array.from(ids));
}
}
}

// --- facility level getters / setters

public async setFacilityKey(
facilityId: string,
facility: Facility
key: FacilityKey | FacilityIndexKey,
value: FacilityValues
): Promise<void> {
const facilitySublevel = this.dbService.getFacilitySublevelDB(facilityId);
await this.dbService.getFacilityDB(facilityId).put(key, value);
}

await facilitySublevel.put('metadata', facility);
public async getFacilityKey(
facilityId: string,
key: FacilityKey | FacilityIndexKey
): Promise<FacilityValues> {
try {
return await this.dbService.getFacilityDB(facilityId).get(key);
} catch (e) {
if (e.status === 404) {
throw new Error(`Unable to get "${key}" of facility "${facilityId}"`);
}
throw e;
}
}

await this.createFacilityIndex(facilityId);
// --- items (space and otherItems) index management

public async getAllItemIds(
facilityId: string,
idx: FacilityIndexKey
): Promise<string[]> {
try {
return await this.dbService
.getFacilityDB(facilityId)
.get<string, string[]>(idx, {
valueEncoding: 'json'
});
} catch (e) {
if (e.status !== 404) {
throw e;
}
}
return [];
}

private async createFacilityIndex(facilityId: string) {
const facilitiesIds = await this.getFacilityIds();
public async addToIndex(
facilityId: string,
idx: FacilityIndexKey,
itemId: string
): Promise<void> {
const itemIds = await this.getAllItemIds(facilityId, idx);
const db = this.dbService.getFacilityDB(facilityId);

if (facilitiesIds.length > 0) {
const idsSet = new Set<string>(facilitiesIds);
idsSet.add(facilityId);
await this.db.put('facilities', Array.from(idsSet));
if (itemIds.length > 0) {
const ids = new Set<string>(itemIds);
ids.add(itemId);
await db.put(idx, Array.from(ids));
} else {
await this.db.put('facilities', [facilityId]);
await db.put(idx, [itemId]);
}
}

public async delFromIndex(
facilityId: string,
idx: FacilityIndexKey,
itemId: string
): Promise<void> {
const itemIds = await this.getAllItemIds(facilityId, idx);

if (itemIds.length > 0) {
const ids = new Set<string>(itemIds);
if (ids.delete(itemId)) {
await this.db.put(idx, Array.from(ids));
}
}
}

// --- item level (space and otherItems) getters / setters

public async setItemKey(
facilityId: string,
idx: FacilityIndexKey,
itemId: string,
key: string,
value: Item | FacilitySpaceValues
): Promise<void> {
await this.dbService
.getFacilityItemDB(facilityId, idx, itemId)
.put(key, value);
}

public async getItemKey(
facilityId: string,
idx: FacilityIndexKey,
itemId: string,
key: string
): Promise<Item | FacilitySpaceValues> {
try {
return await this.dbService
.getFacilityItemDB(facilityId, idx, itemId)
.get(key);
} catch (e) {
if (e.status === 404) {
throw new Error(
`Unable to get "${key}" of item "${itemId}" of facility "${facilityId}"`
);
}
throw e;
}
}
}

export default new FacilityRepository();
29 changes: 29 additions & 0 deletions src/repositories/MainRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import DBService from '../services/DBService';
import { Level } from 'level';

export class MainRepository {
private dbService: DBService;
private db: Level<string, string | string[]>;

constructor() {
this.dbService = DBService.getInstance();
this.db = DBService.getInstance().getDB();
}

public async getId(): Promise<number> {
try {
return Number(await this.db.get('user_db_increment')) + 1;
} catch (e) {
if (e.status === 404) {
return 1;
}
throw e;
}
}

public async setUserDBIncrement(id: string) {
await this.db.put('user_db_increment', id);
}
}

export default new MainRepository();
Loading