fix: role handlers

This commit is contained in:
Kirill 2023-03-17 17:42:31 +00:00
parent ed8b9970e5
commit a6a578998e
36 changed files with 2010 additions and 2059 deletions

@ -1,22 +1,22 @@
# Server Options # Server Options
HTTP_HOST=localhost HTTP_HOST=localhost
HTTP_PORT=8080 HTTP_PORT=8080
# Auth service # Auth service
AUTH_SERVICE_HOST=http://localhost AUTH_SERVICE_HOST=http://localhost
AUTH_SERVICE_PORT=8081 AUTH_SERVICE_PORT=8081
# Database Options # Database Options
DB_HOST=127.0.0.1 DB_HOST=127.0.0.1
DB_PORT=27017 DB_PORT=27017
DB_USERNAME=admin DB_USERNAME=admin
DB_PASSWORD=admin DB_PASSWORD=admin
DB_NAME=admin DB_NAME=admin
# Other # Other
PUBLIC_ACCESS_SECRET_KEY=`-----BEGIN PUBLIC KEY----- PUBLIC_ACCESS_SECRET_KEY=`-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69 MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69
80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B 80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B
dA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y dA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y
+3GyaOY536H47qyXAgMBAAE= +3GyaOY536H47qyXAgMBAAE=
-----END PUBLIC KEY-----` -----END PUBLIC KEY-----`

@ -1,3 +1,3 @@
# Hub Admin Panel Backend Service # Hub Admin Panel Backend Service
**Вся основная документация расположена в** [**Wiki**](https://penahub.gitlab.yandexcloud.net/pena-services/hub_admin_backend_service/-/wikis/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5) **Вся основная документация расположена в** [**Wiki**](https://penahub.gitlab.yandexcloud.net/pena-services/hub_admin_backend_service/-/wikis/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5)

@ -1,14 +1,14 @@
# Настройки сервера: # Настройки сервера:
В папке `./src/constants` лежат два файла конфигурации: В папке `./src/constants` лежат два файла конфигурации:
- `configurations.ts` - `configurations.ts`
- `default.ts` - `default.ts`
**configurations.ts** **configurations.ts**
Хранит в себе конфигурации сервиса, загружаемые через `ENV`. В основном хранит в себе данные о подключении к БД и адреса прослушивания запросов сервером. Хранит в себе конфигурации сервиса, загружаемые через `ENV`. В основном хранит в себе данные о подключении к БД и адреса прослушивания запросов сервером.
**default.ts** **default.ts**
Хранит в себе стандартные значения и настройки подключаемых модулей, такие как: `fastify`, `swagger`. Хранит в себе стандартные значения и настройки подключаемых модулей, такие как: `fastify`, `swagger`.

@ -1,38 +1,38 @@
# Swagger: # Swagger:
При запуске сервиса, документацию можно будет изучить по отдельной ссылке, которая выдаётся сервисом При запуске сервиса, документацию можно будет изучить по отдельной ссылке, которая выдаётся сервисом
**Ссылка на Swagger документацию**: `<hostname>/swagger` **Ссылка на Swagger документацию**: `<hostname>/swagger`
## Архитектура Swagger документации (Для разработчиков): ## Архитектура Swagger документации (Для разработчиков):
``` ```
├── privilege ├── privilege
│ ├── index.ts │ ├── index.ts
│ ├── inputs.ts │ ├── inputs.ts
│ ├── models.ts │ ├── models.ts
│ ├── responses.ts │ ├── responses.ts
├── tariff ├── tariff
│ ├── index.ts │ ├── index.ts
│ ├── inputs.ts │ ├── inputs.ts
│ ├── models.ts │ ├── models.ts
│ ├── responses.ts │ ├── responses.ts
├── role ├── role
│ ├── index.ts │ ├── index.ts
│ ├── inputs.ts │ ├── inputs.ts
│ ├── models.ts │ ├── models.ts
│ ├── responses.ts │ ├── responses.ts
├── account ├── account
│ ├── index.ts │ ├── index.ts
│ ├── inputs.ts │ ├── inputs.ts
│ ├── models.ts │ ├── models.ts
│ ├── responses.ts │ ├── responses.ts
``` ```
- Каждая из директорий является названием группы обработчиков (`routes`) - Каждая из директорий является названием группы обработчиков (`routes`)
- `index` выдаёт все схемы для генерации документации - `index` выдаёт все схемы для генерации документации
- `inputs` содержит в себе все входные данные, требуемые обработчику: _`params`_, _`querystring`_, _`body`_ - `inputs` содержит в себе все входные данные, требуемые обработчику: _`params`_, _`querystring`_, _`body`_
- `models` хранит в себе все бизнес модели: _`user`_, _`tariff`_, _`role`_ - `models` хранит в себе все бизнес модели: _`user`_, _`tariff`_, _`role`_

@ -1,23 +1,23 @@
import cors from "@fastify/cors"; import cors from "@fastify/cors";
import cookie from "@fastify/cookie"; import cookie from "@fastify/cookie";
import jwt from "@fastify/jwt"; import jwt from "@fastify/jwt";
import swagger from "@fastify/swagger"; import swagger from "@fastify/swagger";
import swaggerUI from "@fastify/swagger-ui"; import swaggerUI from "@fastify/swagger-ui";
import printRoutes from "@/plugins/print-routes"; import printRoutes from "@/plugins/print-routes";
import { DEFAULT } from "@/constants/default"; import { DEFAULT } from "@/constants/default";
import type { FastifyInstance } from "fastify"; import type { FastifyInstance } from "fastify";
import type { PluginsOptions } from "@/types/configuration/plugins-options"; import type { PluginsOptions } from "@/types/configuration/plugins-options";
export const registerFastifyPlugins = (fastify: FastifyInstance, options: PluginsOptions) => { export const registerFastifyPlugins = (fastify: FastifyInstance, options: PluginsOptions) => {
fastify.register(cors, options.cors); fastify.register(cors, options.cors);
fastify.register(cookie, options.cookie); fastify.register(cookie, options.cookie);
fastify.register(jwt, options.jwt); fastify.register(jwt, options.jwt);
fastify.register(swagger, DEFAULT.swaggerOptions); fastify.register(swagger, DEFAULT.swaggerOptions);
fastify.register(swaggerUI, DEFAULT.swaggerUIOptions); fastify.register(swaggerUI, DEFAULT.swaggerUIOptions);
fastify.register(printRoutes); fastify.register(printRoutes);
return fastify; return fastify;
}; };

@ -1,46 +1,46 @@
import type { FastifyServerOptions } from "fastify"; import type { FastifyServerOptions } from "fastify";
import type { FastifyDynamicSwaggerOptions } from "@fastify/swagger"; import type { FastifyDynamicSwaggerOptions } from "@fastify/swagger";
import type { FastifySwaggerUiOptions } from "@fastify/swagger-ui"; import type { FastifySwaggerUiOptions } from "@fastify/swagger-ui";
type Default = { type Default = {
readonly fastifyOptions: FastifyServerOptions; readonly fastifyOptions: FastifyServerOptions;
readonly swaggerOptions: FastifyDynamicSwaggerOptions; readonly swaggerOptions: FastifyDynamicSwaggerOptions;
readonly swaggerUIOptions: FastifySwaggerUiOptions; readonly swaggerUIOptions: FastifySwaggerUiOptions;
}; };
export const DEFAULT: Default = { export const DEFAULT: Default = {
fastifyOptions: { fastifyOptions: {
logger: true, logger: true,
ajv: { ajv: {
customOptions: { removeAdditional: "failing" }, customOptions: { removeAdditional: "failing" },
}, },
bodyLimit: 30 * 1024 * 1024, bodyLimit: 30 * 1024 * 1024,
}, },
swaggerOptions: { swaggerOptions: {
openapi: { openapi: {
info: { info: {
title: "Hub Admin Backend", title: "Hub Admin Backend",
description: "Тестирование сервиса админ панели хаба", description: "Тестирование сервиса админ панели хаба",
version: "0.1.0", version: "0.1.0",
}, },
components: { components: {
securitySchemes: { securitySchemes: {
bearer: { bearer: {
description: "Authorization header token, sample: Bearer <token>", description: "Authorization header token, sample: Bearer <token>",
type: "http", type: "http",
bearerFormat: "JWT", bearerFormat: "JWT",
scheme: "bearer", scheme: "bearer",
}, },
}, },
}, },
}, },
hideUntagged: true, hideUntagged: true,
}, },
swaggerUIOptions: { swaggerUIOptions: {
routePrefix: "/swagger", routePrefix: "/swagger",
uiConfig: { uiConfig: {
docExpansion: "full", docExpansion: "full",
deepLinking: false, deepLinking: false,
}, },
}, },
}; };

@ -1,137 +1,137 @@
import { Types } from "mongoose"; import { Types } from "mongoose";
import { AccountModel } from "@/models/account.model"; import { AccountModel } from "@/models/account.model";
import { RoleModel } from "@/models/role.model"; import { RoleModel } from "@/models/role.model";
import { getUser } from "@/clients/auth"; import { getUser } from "@/clients/auth";
import { validateEmptyFields } from "@/utils/validate-empty-fields"; import { validateEmptyFields } from "@/utils/validate-empty-fields";
import type { FastifyReply, FastifyRequest } from "fastify"; import type { FastifyReply, FastifyRequest } from "fastify";
import type { GetAccountRequest, SetAccountRoleRequest } from "./types"; import type { GetAccountRequest, SetAccountRoleRequest } from "./types";
export const getAllAccounts = async () => AccountModel.find({}).lean(); export const getAllAccounts = async () => AccountModel.find({}).lean();
export const createAccount = async (request: FastifyRequest, reply: FastifyReply) => { export const createAccount = async (request: FastifyRequest, reply: FastifyReply) => {
if (!Types.ObjectId.isValid(request.user.id)) { if (!Types.ObjectId.isValid(request.user.id)) {
reply.status(400); reply.status(400);
return new Error("invalid user id"); return new Error("invalid user id");
} }
const account = await AccountModel.findOne({ userId: request.user.id }).lean(); const account = await AccountModel.findOne({ userId: request.user.id }).lean();
if (account) { if (account) {
reply.status(409); reply.status(409);
return new Error("account already exist"); return new Error("account already exist");
} }
const user = await getUser({ id: request.user.id }); const user = await getUser({ id: request.user.id });
if (!user) { if (!user) {
reply.status(404); reply.status(404);
return new Error("user not found"); return new Error("user not found");
} }
const createdAccount = new AccountModel({ const createdAccount = new AccountModel({
userId: user._id, userId: user._id,
}); });
return createdAccount.save(); return createdAccount.save();
}; };
export const getAccount = async (request: GetAccountRequest, reply: FastifyReply) => { export const getAccount = async (request: GetAccountRequest, reply: FastifyReply) => {
const [getAccountRequestParams, error] = validateEmptyFields(request.params || {}, ["userId"]); const [getAccountRequestParams, error] = validateEmptyFields(request.params || {}, ["userId"]);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
if (!Types.ObjectId.isValid(getAccountRequestParams.userId)) { if (!Types.ObjectId.isValid(getAccountRequestParams.userId)) {
reply.status(400); reply.status(400);
return new Error("invalid user id"); return new Error("invalid user id");
} }
return AccountModel.findOne({ userId: getAccountRequestParams.userId }).lean(); return AccountModel.findOne({ userId: getAccountRequestParams.userId }).lean();
}; };
export const setAccountRole = async (request: SetAccountRoleRequest, reply: FastifyReply) => { export const setAccountRole = async (request: SetAccountRoleRequest, reply: FastifyReply) => {
const [setAccountRoleBody, error] = validateEmptyFields(request.body || {}, ["userId", "role"]); const [setAccountRoleBody, error] = validateEmptyFields(request.body || {}, ["userId", "role"]);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
const role = await RoleModel.findOne({ name: setAccountRoleBody.role }).lean(); const role = await RoleModel.findOne({ name: setAccountRoleBody.role }).lean();
if (!role) { if (!role) {
reply.status(404); reply.status(404);
return new Error("role not found"); return new Error("role not found");
} }
const account = await AccountModel.findOneAndUpdate( const account = await AccountModel.findOneAndUpdate(
{ userId: setAccountRoleBody.userId }, { userId: setAccountRoleBody.userId },
{ $set: { role: role.name } } { $set: { role: role.name } }
); );
if (!account) { if (!account) {
reply.status(404); reply.status(404);
return new Error("account not found"); return new Error("account not found");
} }
return account; return account;
}; };
export const removeAccount = async (request: FastifyRequest, reply: FastifyReply) => { export const removeAccount = async (request: FastifyRequest, reply: FastifyReply) => {
if (!Types.ObjectId.isValid(request.user.id)) { if (!Types.ObjectId.isValid(request.user.id)) {
reply.status(400); reply.status(400);
return new Error("invalid user id"); return new Error("invalid user id");
} }
const account = await AccountModel.findOneAndUpdate( const account = await AccountModel.findOneAndUpdate(
{ userId: request.user.id }, { userId: request.user.id },
{ $set: { isDeleted: true, deletedAt: new Date() } } { $set: { isDeleted: true, deletedAt: new Date() } }
).lean(); ).lean();
if (!account) { if (!account) {
reply.status(404); reply.status(404);
return new Error("account not found"); return new Error("account not found");
} }
return account; return account;
}; };
export const deleteAccount = async (request: FastifyRequest, reply: FastifyReply) => { export const deleteAccount = async (request: FastifyRequest, reply: FastifyReply) => {
if (!Types.ObjectId.isValid(request.user.id)) { if (!Types.ObjectId.isValid(request.user.id)) {
reply.status(400); reply.status(400);
return new Error("invalid user id"); return new Error("invalid user id");
} }
const account = await AccountModel.findByIdAndDelete({ userId: request.user.id }).lean(); const account = await AccountModel.findByIdAndDelete({ userId: request.user.id }).lean();
if (!account) { if (!account) {
reply.status(404); reply.status(404);
return new Error("account not found"); return new Error("account not found");
} }
return account; return account;
}; };
export const restoreAccount = async (request: FastifyRequest, reply: FastifyReply) => { export const restoreAccount = async (request: FastifyRequest, reply: FastifyReply) => {
if (!Types.ObjectId.isValid(request.user.id)) { if (!Types.ObjectId.isValid(request.user.id)) {
reply.status(400); reply.status(400);
return new Error("invalid user id"); return new Error("invalid user id");
} }
const account = await AccountModel.findOneAndUpdate( const account = await AccountModel.findOneAndUpdate(
{ userId: request.user.id }, { userId: request.user.id },
{ $set: { isDeleted: false } } { $set: { isDeleted: false } }
).lean(); ).lean();
if (!account) { if (!account) {
reply.status(404); reply.status(404);
return new Error("account not found"); return new Error("account not found");
} }
return account; return account;
}; };

@ -1,14 +1,14 @@
import type { FastifyRequest } from "fastify"; import type { FastifyRequest } from "fastify";
export type GetAccountRequest = FastifyRequest<{ export type GetAccountRequest = FastifyRequest<{
Params?: { Params?: {
userId?: string; userId?: string;
}; };
}>; }>;
export type SetAccountRoleRequest = FastifyRequest<{ export type SetAccountRoleRequest = FastifyRequest<{
Body: { Body: {
userId?: string; userId?: string;
role?: string; role?: string;
}; };
}>; }>;

@ -1,28 +1,28 @@
import type { Privilege } from "@/types/models/privilege.type"; import type { Privilege } from "@/types/models/privilege.type";
import type { RawPrivilege } from "./types"; import type { RawPrivilege } from "./types";
export const validatePrivilege = (privilege: RawPrivilege): Error | null => { export const validatePrivilege = (privilege: RawPrivilege): Error | null => {
const typeValues: typeof privilege.type[] = ["count", "day", "full"]; const typeValues: typeof privilege.type[] = ["count", "day", "full"];
if (!typeValues.includes(privilege.type)) { if (!typeValues.includes(privilege.type)) {
return new Error("invalid <type> value"); return new Error("invalid <type> value");
} }
if (isNaN(Number(privilege.price))) { if (isNaN(Number(privilege.price))) {
return new Error("price must be a number"); return new Error("price must be a number");
} }
return null; return null;
}; };
export const convertPrivilegiesToMap = (privilegies: Privilege[]) => { export const convertPrivilegiesToMap = (privilegies: Privilege[]) => {
return privilegies.reduce<Record<string, Privilege[]>>((accamulator, privilege) => { return privilegies.reduce<Record<string, Privilege[]>>((accamulator, privilege) => {
if (!accamulator[privilege.serviceKey]) { if (!accamulator[privilege.serviceKey]) {
accamulator[privilege.serviceKey] = []; accamulator[privilege.serviceKey] = [];
} }
accamulator[privilege.serviceKey].push(privilege); accamulator[privilege.serviceKey].push(privilege);
return accamulator; return accamulator;
}, {}); }, {});
}; };

@ -1,329 +1,280 @@
import { Types } from "mongoose"; import { Types } from "mongoose";
import { PrivilegeModel } from "@/models/privilege.model"; import { PrivilegeModel } from "@/models/privilege.model";
import { validateEmptyFields } from "@/utils/validate-empty-fields"; import { validateEmptyFields } from "@/utils/validate-empty-fields";
import { convertPrivilegiesToMap, validatePrivilege } from "./helpers"; import { convertPrivilegiesToMap, validatePrivilege } from "./helpers";
import type { FastifyReply } from "fastify"; import type { FastifyReply } from "fastify";
import type { import type {
GetServicePrivilegiesRequest, GetServicePrivilegiesRequest,
RegisterPrivilegeRequest, RegisterPrivilegeRequest,
GetPrivilegeRequest, GetPrivilegeRequest,
RegisterPrivilegiesRequest, RegisterPrivilegiesRequest,
RemovePrivilegeRequest, RemovePrivilegeRequest,
} from "./types"; } from "./types";
export const registerPrivilegies = async (request: RegisterPrivilegiesRequest, reply: FastifyReply) => { export const registerPrivilegies = async (request: RegisterPrivilegiesRequest, reply: FastifyReply) => {
const [requestBody, errorEmpty] = validateEmptyFields(request.body || {}, ["privilegies"]); const [requestBody, errorEmpty] = validateEmptyFields(request.body || {}, ["privilegies"]);
if (errorEmpty) { if (errorEmpty) {
reply.status(400); reply.status(400);
return errorEmpty; return errorEmpty;
} }
if (!requestBody.privilegies.length) { if (!requestBody.privilegies.length) {
reply.status(400); reply.status(400);
return new Error("empty privilege array"); return new Error("empty privilege array");
} }
for (const rawPrivilege of requestBody.privilegies) { for (const rawPrivilege of requestBody.privilegies) {
const errorInvalid = validatePrivilege(rawPrivilege); const errorInvalid = validatePrivilege(rawPrivilege);
if (errorInvalid) { if (errorInvalid) {
reply.status(400); reply.status(400);
return errorInvalid; return errorInvalid;
} }
} }
const updatePrivilegeRequests = requestBody.privilegies.map(async (privilege) => { const updatePrivilegeRequests = requestBody.privilegies.map(async (privilege) => {
await PrivilegeModel.updateOne( await PrivilegeModel.updateOne(
{ privilegeId: privilege.privilegeId }, { privilegeId: privilege.privilegeId },
{ {
$set: { $set: {
name: privilege.name, name: privilege.name,
privilegeId: privilege.privilegeId, privilegeId: privilege.privilegeId,
serviceKey: privilege.serviceKey, serviceKey: privilege.serviceKey,
description: privilege.description, description: privilege.description,
type: privilege.type, type: privilege.type,
value: privilege.value, value: privilege.value,
price: privilege.price, price: privilege.price,
isDeleted: false, isDeleted: false,
createdAt: new Date(), createdAt: new Date(),
}, },
}, },
{ upsert: true } { upsert: true }
).lean(); ).lean();
return privilege; return privilege;
}); });
return Promise.all(updatePrivilegeRequests); return Promise.all(updatePrivilegeRequests);
}; };
export const registerPrivilege = async (request: RegisterPrivilegeRequest, reply: FastifyReply) => { export const registerPrivilege = async (request: RegisterPrivilegeRequest, reply: FastifyReply) => {
const [requestBody, errorEmpty] = validateEmptyFields( const [requestBody, errorEmpty] = validateEmptyFields(
request.body || {}, request.body || {},
["name", "privilegeId", "serviceKey", "type", "description", "price", "value"], ["name", "privilegeId", "serviceKey", "type", "description", "price", "value"],
false false
); );
if (errorEmpty) { if (errorEmpty) {
reply.status(400); reply.status(400);
return errorEmpty; return errorEmpty;
} }
const errorInvalid = validatePrivilege(requestBody); const errorInvalid = validatePrivilege(requestBody);
if (errorInvalid) { if (errorInvalid) {
reply.status(400); reply.status(400);
return errorInvalid; return errorInvalid;
} }
const privilege = await PrivilegeModel.findOne({ privilegeId: requestBody.privilegeId }).lean(); const privilege = await PrivilegeModel.findOne({ privilegeId: requestBody.privilegeId }).lean();
if (privilege) { if (privilege) {
reply.status(409); reply.status(409);
return new Error("privilege already exist"); return new Error("privilege already exist");
} }
const newPrivilege = new PrivilegeModel({ const newPrivilege = new PrivilegeModel({
name: requestBody.name, name: requestBody.name,
privilegeId: requestBody.privilegeId, privilegeId: requestBody.privilegeId,
serviceKey: requestBody.serviceKey, serviceKey: requestBody.serviceKey,
description: requestBody.description, description: requestBody.description,
type: requestBody.type, type: requestBody.type,
value: requestBody.value, value: requestBody.value,
price: requestBody.price, price: requestBody.price,
}); });
return newPrivilege.save(); return newPrivilege.save();
}; };
export const getAllPrivilegies = async () => PrivilegeModel.find({ isDeleted: false }).lean(); export const getAllPrivilegies = async () => PrivilegeModel.find({ isDeleted: false }).lean();
export const getAllPrivilegiesMap = async () => { export const getAllPrivilegiesMap = async () => {
const privilegies = await PrivilegeModel.find({ isDeleted: false }).lean(); const privilegies = await PrivilegeModel.find({ isDeleted: false }).lean();
if (!privilegies.length) { if (!privilegies.length) {
return {}; return {};
} }
return convertPrivilegiesToMap(privilegies); return convertPrivilegiesToMap(privilegies);
}; };
export const getServicePrivilegies = async (request: GetServicePrivilegiesRequest, reply: FastifyReply) => { export const getServicePrivilegies = async (request: GetServicePrivilegiesRequest, reply: FastifyReply) => {
const [requestParams, error] = validateEmptyFields(request.params || {}, ["serviceKey"]); const [requestParams, error] = validateEmptyFields(request.params || {}, ["serviceKey"]);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
return PrivilegeModel.find({ serviceKey: requestParams.serviceKey, isDeleted: false }).lean(); return PrivilegeModel.find({ serviceKey: requestParams.serviceKey, isDeleted: false }).lean();
}; };
export const getPrivilege = async (request: GetPrivilegeRequest, reply: FastifyReply) => { export const getPrivilege = async (request: GetPrivilegeRequest, reply: FastifyReply) => {
const [requestParams, error] = validateEmptyFields(request.params || {}, ["privilegeId"]); const [requestParams, error] = validateEmptyFields(request.params || {}, ["privilegeId"]);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
if (!Types.ObjectId.isValid(requestParams.privilegeId)) { if (!Types.ObjectId.isValid(requestParams.privilegeId)) {
reply.status(400); reply.status(400);
return new Error("invalid id"); return new Error("invalid id");
} }
const privilege = await PrivilegeModel.findOne({ privilegeId: requestParams.privilegeId, isDeleted: false }).lean(); const privilege = await PrivilegeModel.findOne({ privilegeId: requestParams.privilegeId, isDeleted: false }).lean();
if (!privilege) { if (!privilege) {
reply.status(404); reply.status(404);
return new Error("privilege not found"); return new Error("privilege not found");
} }
return privilege; return privilege;
}; };
export const replacePrivilege = async (request: RegisterPrivilegeRequest, reply: FastifyReply) => { export const replacePrivilege = async (request: RegisterPrivilegeRequest, reply: FastifyReply) => {
const [requestBody, errorEmpty] = validateEmptyFields( const [requestBody, errorEmpty] = validateEmptyFields(
request.body || {}, request.body || {},
["name", "privilegeId", "serviceKey", "type", "description", "price", "value"], ["name", "privilegeId", "serviceKey", "type", "description", "price", "value"],
false false
); );
if (errorEmpty) { if (errorEmpty) {
reply.status(400); reply.status(400);
return errorEmpty; return errorEmpty;
} }
const errorInvalid = validatePrivilege(requestBody); const errorInvalid = validatePrivilege(requestBody);
if (errorInvalid) { if (errorInvalid) {
reply.status(400); reply.status(400);
return errorInvalid; return errorInvalid;
} }
const privilege = await PrivilegeModel.findOne({ privilegeId: requestBody.privilegeId }); const privilege = await PrivilegeModel.findOne({ privilegeId: requestBody.privilegeId });
if (!privilege) { if (!privilege) {
reply.status(404); reply.status(404);
return new Error("privilege not found"); return new Error("privilege not found");
} }
await privilege.replaceOne({ await privilege.replaceOne({
name: requestBody.name, name: requestBody.name,
privilegeId: requestBody.privilegeId, privilegeId: requestBody.privilegeId,
serviceKey: requestBody.serviceKey, serviceKey: requestBody.serviceKey,
description: requestBody.description, description: requestBody.description,
type: requestBody.type, type: requestBody.type,
value: requestBody.value, value: requestBody.value,
price: requestBody.price, price: requestBody.price,
updatedAt: new Date(), updatedAt: new Date(),
}); });
return Promise.all(replacePrivilegeRequests); return privilege;
}; };
export const removePrivilege = async (request: RemovePrivilegeRequest, reply: FastifyReply) => { export const removePrivilege = async (request: RemovePrivilegeRequest, reply: FastifyReply) => {
const [{ privilegeId }, error] = validateEmptyFields(request.body || {}, ["privilegeId"]); const [{ privilegeId }, error] = validateEmptyFields(request.body || {}, ["privilegeId"]);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
if (!Types.ObjectId.isValid(privilegeId)) { if (!Types.ObjectId.isValid(privilegeId)) {
reply.status(400); reply.status(400);
return new Error("invalid id"); return new Error("invalid id");
} }
const privilege = await PrivilegeModel.findOneAndUpdate( const privilege = await PrivilegeModel.findOneAndUpdate(
{ privilegeId }, { privilegeId },
{ $set: { isDeleted: true, deletedAt: new Date() } } { $set: { isDeleted: true, deletedAt: new Date() } }
); );
if (!privilege) { if (!privilege) {
reply.status(404); reply.status(404);
return new Error("privilege not found"); return new Error("privilege not found");
} }
return privilege; return privilege;
}; };
export const restorePrivilege = async (request: RemovePrivilegeRequest, reply: FastifyReply) => { export const replacePrivilegies = async (request: RegisterPrivilegiesRequest, reply: FastifyReply) => {
const [{ privilegeId }, error] = validateEmptyFields(request.body || {}, ["privilegeId"]); const [requestBody, errorEmpty] = validateEmptyFields(request.body || {}, ["privilegies"]);
if (error) { if (errorEmpty) {
reply.status(400); reply.status(400);
return error; return errorEmpty;
} }
if (!Types.ObjectId.isValid(privilegeId)) { if (!requestBody.privilegies.length) {
reply.status(400); reply.status(400);
return new Error("invalid id"); return new Error("empty privilege array");
} }
const privilege = await PrivilegeModel.findOneAndUpdate({ privilegeId }, { $set: { isDeleted: false } }); for (const rawPrivilege of requestBody.privilegies) {
const errorInvalid = validatePrivilege(rawPrivilege);
if (!privilege) {
reply.status(404); if (errorInvalid) {
return new Error("privilege not found"); reply.status(400);
} return errorInvalid;
}
return privilege; }
};
const replacePrivilegeRequests = requestBody.privilegies.map(async (privilege) => {
export const replacePrivilegies = async (request: RegisterPrivilegiesRequest, reply: FastifyReply) => { await PrivilegeModel.replaceOne(
const [requestBody, errorEmpty] = validateEmptyFields(request.body || {}, ["privilegies"]); { privilegeId: privilege.privilegeId },
{
if (errorEmpty) { name: privilege.name,
reply.status(400); privilegeId: privilege.privilegeId,
return errorEmpty; serviceKey: privilege.serviceKey,
} description: privilege.description,
type: privilege.type,
if (!requestBody.privilegies.length) { value: privilege.value,
reply.status(400); price: privilege.price,
return new Error("empty privilege array"); updatedAt: new Date(),
} isDeleted: false,
}
for (const rawPrivilege of requestBody.privilegies) { ).lean();
const errorInvalid = validatePrivilege(rawPrivilege);
return privilege;
if (errorInvalid) { });
reply.status(400);
return errorInvalid; return Promise.all(replacePrivilegeRequests);
} };
}
export const restorePrivilege = async (request: RemovePrivilegeRequest, reply: FastifyReply) => {
const replacePrivilegeRequests = requestBody.privilegies.map(async (privilege) => { const [{ privilegeId }, error] = validateEmptyFields(request.body || {}, ["privilegeId"]);
await PrivilegeModel.replaceOne(
{ privilegeId: privilege.privilegeId }, if (error) {
{ reply.status(400);
name: privilege.name, return error;
privilegeId: privilege.privilegeId, }
serviceKey: privilege.serviceKey,
description: privilege.description, if (!Types.ObjectId.isValid(privilegeId)) {
type: privilege.type, reply.status(400);
value: privilege.value, return new Error("invalid id");
price: privilege.price, }
updatedAt: new Date(),
isDeleted: false, const privilege = await PrivilegeModel.findOneAndUpdate({ privilegeId }, { $set: { isDeleted: false } });
}
).lean(); if (!privilege) {
reply.status(404);
return privilege; return new Error("privilege not found");
}); }
return Promise.all(replacePrivilegeRequests); return privilege;
}; };
export const removePrivilege = async (request: RemovePrivilegeRequest, reply: FastifyReply) => {
const [{ privilegeId }, error] = validateEmptyFields(request.body || {}, ["privilegeId"]);
if (error) {
reply.status(400);
return error;
}
if (!Types.ObjectId.isValid(privilegeId)) {
reply.status(400);
return new Error("invalid id");
}
const privilege = await PrivilegeModel.findOneAndUpdate(
{ privilegeId },
{ $set: { isDeleted: true, deletedAt: new Date() } }
);
if (!privilege) {
reply.status(404);
return new Error("privilege not found");
}
return privilege;
};
export const restorePrivilege = async (request: RemovePrivilegeRequest, reply: FastifyReply) => {
const [{ privilegeId }, error] = validateEmptyFields(request.body || {}, ["privilegeId"]);
if (error) {
reply.status(400);
return error;
}
if (!Types.ObjectId.isValid(privilegeId)) {
reply.status(400);
return new Error("invalid id");
}
const privilege = await PrivilegeModel.findOneAndUpdate({ privilegeId }, { $set: { isDeleted: false } });
if (!privilege) {
reply.status(404);
return new Error("privilege not found");
}
return privilege;
};

@ -1,39 +1,39 @@
import type { FastifyRequest } from "fastify"; import type { FastifyRequest } from "fastify";
export type RawPrivilege = { export type RawPrivilege = {
name?: string; name?: string;
privilegeId?: string; privilegeId?: string;
serviceKey?: string; serviceKey?: string;
description?: string; description?: string;
type?: string; type?: string;
value?: string; value?: string;
price?: number; price?: number;
}; };
export type RegisterPrivilegeRequest = FastifyRequest<{ export type RegisterPrivilegeRequest = FastifyRequest<{
Body?: RawPrivilege; Body?: RawPrivilege;
}>; }>;
export type RegisterPrivilegiesRequest = FastifyRequest<{ export type RegisterPrivilegiesRequest = FastifyRequest<{
Body?: { Body?: {
privilegies?: RawPrivilege[]; privilegies?: RawPrivilege[];
}; };
}>; }>;
export type GetServicePrivilegiesRequest = FastifyRequest<{ export type GetServicePrivilegiesRequest = FastifyRequest<{
Params?: { Params?: {
serviceKey?: string; serviceKey?: string;
}; };
}>; }>;
export type GetPrivilegeRequest = FastifyRequest<{ export type GetPrivilegeRequest = FastifyRequest<{
Params?: { Params?: {
privilegeId?: string; privilegeId?: string;
}; };
}>; }>;
export type RemovePrivilegeRequest = FastifyRequest<{ export type RemovePrivilegeRequest = FastifyRequest<{
Body?: { Body?: {
privilegeId?: string; privilegeId?: string;
}; };
}>; }>;

@ -1,22 +1,22 @@
import { validateEmptyFields } from "@/utils/validate-empty-fields"; import { validateEmptyFields } from "@/utils/validate-empty-fields";
import type { TariffMessage } from "@/types/messages/tariff-message.type"; import type { TariffMessage } from "@/types/messages/tariff-message.type";
import type { ObjectWithRequiredFields } from "@/types/object-with-required-fields"; import type { ObjectWithRequiredFields } from "@/types/object-with-required-fields";
export const validateTariff = (tariff?: TariffMessage): [ObjectWithRequiredFields<TariffMessage>, Error | null] => { export const validateTariff = (tariff?: TariffMessage): [ObjectWithRequiredFields<TariffMessage>, Error | null] => {
const [validatedTariff, errorEmpty] = validateEmptyFields( const [validatedTariff, errorEmpty] = validateEmptyFields(
tariff || {}, tariff || {},
["isCustom", "name", "price", "privilegieIDArray"], ["isCustom", "name", "price", "privilegieIDArray"],
false false
); );
if (errorEmpty) { if (errorEmpty) {
return [validatedTariff, errorEmpty]; return [validatedTariff, errorEmpty];
} }
if (isNaN(Number(validatedTariff.price))) { if (isNaN(Number(validatedTariff.price))) {
return [validatedTariff, new Error("invalid 'price' value")]; return [validatedTariff, new Error("invalid 'price' value")];
} }
return [validatedTariff, null]; return [validatedTariff, null];
}; };

@ -1,200 +1,200 @@
import { Types } from "mongoose"; import { Types } from "mongoose";
import { TariffModel } from "@/models/tariff.model"; import { TariffModel } from "@/models/tariff.model";
import { PrivilegeModel } from "@/models/privilege.model"; import { PrivilegeModel } from "@/models/privilege.model";
import { validateEmptyFields } from "@/utils/validate-empty-fields"; import { validateEmptyFields } from "@/utils/validate-empty-fields";
import { validateTariff } from "./helpers"; import { validateTariff } from "./helpers";
import type { FastifyReply } from "fastify"; import type { FastifyReply } from "fastify";
import type { Privilege } from "@/types/models/privilege.type"; import type { Privilege } from "@/types/models/privilege.type";
import type { CreateTariffRequest, GetTariffRequest, ReplaceTariffRequest, RemoveTariffRequest } from "./types"; import type { CreateTariffRequest, GetTariffRequest, ReplaceTariffRequest, RemoveTariffRequest } from "./types";
export const getTariffs = async () => TariffModel.find({}).lean(); export const getTariffs = async () => TariffModel.find({}).lean();
export const getTariff = async (request: GetTariffRequest, reply: FastifyReply) => { export const getTariff = async (request: GetTariffRequest, reply: FastifyReply) => {
const [requestParams, error] = validateEmptyFields(request.params || {}, ["id"]); const [requestParams, error] = validateEmptyFields(request.params || {}, ["id"]);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
if (!Types.ObjectId.isValid(requestParams.id)) { if (!Types.ObjectId.isValid(requestParams.id)) {
reply.status(400); reply.status(400);
return new Error("invalid id"); return new Error("invalid id");
} }
const tariff = await TariffModel.findById(requestParams.id).lean(); const tariff = await TariffModel.findById(requestParams.id).lean();
if (!tariff) { if (!tariff) {
reply.status(404); reply.status(404);
return new Error("tariff not found"); return new Error("tariff not found");
} }
return tariff; return tariff;
}; };
export const createTariff = async (request: CreateTariffRequest, reply: FastifyReply) => { export const createTariff = async (request: CreateTariffRequest, reply: FastifyReply) => {
const [requestBody, error] = validateTariff(request.body); const [requestBody, error] = validateTariff(request.body);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
for (const privilegeId of requestBody.privilegieIDArray) { for (const privilegeId of requestBody.privilegieIDArray) {
if (!Types.ObjectId.isValid(privilegeId)) { if (!Types.ObjectId.isValid(privilegeId)) {
reply.status(404); reply.status(404);
return new Error(`privilege id <${privilegeId}> invalid`); return new Error(`privilege id <${privilegeId}> invalid`);
} }
} }
const privilegies = await PrivilegeModel.find({ privilegeId: requestBody.privilegieIDArray }).lean(); const privilegies = await PrivilegeModel.find({ privilegeId: requestBody.privilegieIDArray }).lean();
const privilegiesMap = requestBody.privilegieIDArray.reduce<Record<string, Privilege>>((accamulator, privilegeId) => { const privilegiesMap = requestBody.privilegieIDArray.reduce<Record<string, Privilege>>((accamulator, privilegeId) => {
const findedPrivilege = privilegies.find((privilege) => privilege.privilegeId === privilegeId); const findedPrivilege = privilegies.find((privilege) => privilege.privilegeId === privilegeId);
if (!findedPrivilege) { if (!findedPrivilege) {
return accamulator; return accamulator;
} }
accamulator[privilegeId] = findedPrivilege; accamulator[privilegeId] = findedPrivilege;
return accamulator; return accamulator;
}, {}); }, {});
const newTariff = new TariffModel({ const newTariff = new TariffModel({
name: requestBody.name, name: requestBody.name,
price: requestBody.price, price: requestBody.price,
isCustom: requestBody.isCustom, isCustom: requestBody.isCustom,
privilegies: privilegiesMap, privilegies: privilegiesMap,
}); });
await newTariff.save(); await newTariff.save();
return newTariff; return newTariff;
}; };
export const replaceTariff = async (request: ReplaceTariffRequest, reply: FastifyReply) => { export const replaceTariff = async (request: ReplaceTariffRequest, reply: FastifyReply) => {
const [requestBody, error] = validateTariff(request.body || {}); const [requestBody, error] = validateTariff(request.body || {});
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
if (!Types.ObjectId.isValid(request.params?.id || "")) { if (!Types.ObjectId.isValid(request.params?.id || "")) {
reply.status(400); reply.status(400);
return new Error("invalid id"); return new Error("invalid id");
} }
const tariff = await TariffModel.findById(request.params?.id); const tariff = await TariffModel.findById(request.params?.id);
if (!tariff) { if (!tariff) {
reply.status(404); reply.status(404);
return new Error("tariff not found"); return new Error("tariff not found");
} }
for (const privilegeId of requestBody.privilegieIDArray) { for (const privilegeId of requestBody.privilegieIDArray) {
if (!Types.ObjectId.isValid(privilegeId)) { if (!Types.ObjectId.isValid(privilegeId)) {
reply.status(404); reply.status(404);
return new Error(`privilege id <${privilegeId}> invalid`); return new Error(`privilege id <${privilegeId}> invalid`);
} }
} }
const privilegies = await PrivilegeModel.find({ privilegeId: requestBody.privilegieIDArray }).lean(); const privilegies = await PrivilegeModel.find({ privilegeId: requestBody.privilegieIDArray }).lean();
const privilegiesMap = requestBody.privilegieIDArray.reduce<Record<string, Privilege>>((accamulator, privilegeId) => { const privilegiesMap = requestBody.privilegieIDArray.reduce<Record<string, Privilege>>((accamulator, privilegeId) => {
const findedPrivilege = privilegies.find((privilege) => privilege.privilegeId === privilegeId); const findedPrivilege = privilegies.find((privilege) => privilege.privilegeId === privilegeId);
if (!findedPrivilege) { if (!findedPrivilege) {
return accamulator; return accamulator;
} }
accamulator[privilegeId] = findedPrivilege; accamulator[privilegeId] = findedPrivilege;
return accamulator; return accamulator;
}, {}); }, {});
await tariff.replaceOne({ await tariff.replaceOne({
name: requestBody.name, name: requestBody.name,
price: requestBody.price, price: requestBody.price,
isCustom: requestBody.isCustom, isCustom: requestBody.isCustom,
privilegies: privilegiesMap, privilegies: privilegiesMap,
}); });
return tariff; return tariff;
}; };
export const removeTariff = async (request: RemoveTariffRequest, reply: FastifyReply) => { export const removeTariff = async (request: RemoveTariffRequest, reply: FastifyReply) => {
const [{ id }, error] = validateEmptyFields(request.body || {}, ["id"]); const [{ id }, error] = validateEmptyFields(request.body || {}, ["id"]);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
if (!Types.ObjectId.isValid(id)) { if (!Types.ObjectId.isValid(id)) {
reply.status(400); reply.status(400);
return new Error("invalid id"); return new Error("invalid id");
} }
const tariff = await TariffModel.findByIdAndUpdate(id, { const tariff = await TariffModel.findByIdAndUpdate(id, {
$set: { isDeleted: true, deletedAt: new Date() }, $set: { isDeleted: true, deletedAt: new Date() },
}).lean(); }).lean();
if (!tariff) { if (!tariff) {
reply.status(404); reply.status(404);
return new Error("tariff not found"); return new Error("tariff not found");
} }
return tariff; return tariff;
}; };
export const deleteTariff = async (request: RemoveTariffRequest, reply: FastifyReply) => { export const deleteTariff = async (request: RemoveTariffRequest, reply: FastifyReply) => {
const [{ id }, error] = validateEmptyFields(request.body || {}, ["id"]); const [{ id }, error] = validateEmptyFields(request.body || {}, ["id"]);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
if (!Types.ObjectId.isValid(id)) { if (!Types.ObjectId.isValid(id)) {
reply.status(400); reply.status(400);
return new Error("invalid id"); return new Error("invalid id");
} }
const tariff = await TariffModel.findByIdAndDelete(id).lean(); const tariff = await TariffModel.findByIdAndDelete(id).lean();
if (!tariff) { if (!tariff) {
reply.status(404); reply.status(404);
return new Error("tariff not found"); return new Error("tariff not found");
} }
return tariff; return tariff;
}; };
export const restoreTariff = async (request: RemoveTariffRequest, reply: FastifyReply) => { export const restoreTariff = async (request: RemoveTariffRequest, reply: FastifyReply) => {
const [{ id }, error] = validateEmptyFields(request.body || {}, ["id"]); const [{ id }, error] = validateEmptyFields(request.body || {}, ["id"]);
if (error) { if (error) {
reply.status(400); reply.status(400);
return error; return error;
} }
if (!Types.ObjectId.isValid(id)) { if (!Types.ObjectId.isValid(id)) {
reply.status(400); reply.status(400);
return new Error("invalid id"); return new Error("invalid id");
} }
const tariff = await TariffModel.findByIdAndUpdate(id, { $set: { isDeleted: false } }).lean(); const tariff = await TariffModel.findByIdAndUpdate(id, { $set: { isDeleted: false } }).lean();
if (!tariff) { if (!tariff) {
reply.status(404); reply.status(404);
return new Error("tariff not found"); return new Error("tariff not found");
} }
return tariff; return tariff;
}; };

@ -1,23 +1,23 @@
import type { FastifyRequest } from "fastify"; import type { FastifyRequest } from "fastify";
import type { TariffMessage } from "@/types/messages/tariff-message.type"; import type { TariffMessage } from "@/types/messages/tariff-message.type";
export type GetTariffRequest = FastifyRequest<{ export type GetTariffRequest = FastifyRequest<{
Params?: { Params?: {
id?: string; id?: string;
}; };
}>; }>;
export type RemoveTariffRequest = FastifyRequest<{ export type RemoveTariffRequest = FastifyRequest<{
Body?: { Body?: {
id?: string; id?: string;
}; };
}>; }>;
export type CreateTariffRequest = FastifyRequest<{ export type CreateTariffRequest = FastifyRequest<{
Body?: TariffMessage; Body?: TariffMessage;
}>; }>;
export type ReplaceTariffRequest = FastifyRequest<{ export type ReplaceTariffRequest = FastifyRequest<{
Body?: TariffMessage; Body?: TariffMessage;
Params?: { id?: string }; Params?: { id?: string };
}>; }>;

@ -1,32 +1,32 @@
import { Router } from "@/server/router"; import { Router } from "@/server/router";
import { import {
createAccount, createAccount,
getAccount, getAccount,
setAccountRole, setAccountRole,
getAllAccounts, getAllAccounts,
deleteAccount, deleteAccount,
removeAccount, removeAccount,
restoreAccount, restoreAccount,
} from "@/handlers/account"; } from "@/handlers/account";
import { verifyUser } from "@/handlers/auth/middleware"; import { verifyUser } from "@/handlers/auth/middleware";
import { import {
createAccountSchema, createAccountSchema,
getAccountSchema, getAccountSchema,
setAccountRoleSchema, setAccountRoleSchema,
getAccountsSchema, getAccountsSchema,
removeAccountSchema, removeAccountSchema,
restoreAccountSchema, restoreAccountSchema,
deleteAccountSchema, deleteAccountSchema,
} from "@/swagger/account"; } from "@/swagger/account";
export const setAccountRoutes = (router: Router): void => { export const setAccountRoutes = (router: Router): void => {
router.get("/", getAllAccounts, { schema: getAccountsSchema }); router.get("/", getAllAccounts, { schema: getAccountsSchema });
router.get("/:userId", getAccount, { schema: getAccountSchema }); router.get("/:userId", getAccount, { schema: getAccountSchema });
router.post("/", createAccount, { preHandler: [verifyUser], schema: createAccountSchema }); router.post("/", createAccount, { preHandler: [verifyUser], schema: createAccountSchema });
router.post("/restore", restoreAccount, { preHandler: [verifyUser], schema: restoreAccountSchema }); router.post("/restore", restoreAccount, { preHandler: [verifyUser], schema: restoreAccountSchema });
router.patch("/role", setAccountRole, { preHandler: [verifyUser], schema: setAccountRoleSchema }); router.patch("/role", setAccountRole, { preHandler: [verifyUser], schema: setAccountRoleSchema });
router.delete("/", removeAccount, { preHandler: [verifyUser], schema: removeAccountSchema }); router.delete("/", removeAccount, { preHandler: [verifyUser], schema: removeAccountSchema });
router.delete("/delete", deleteAccount, { preHandler: [verifyUser], schema: deleteAccountSchema }); router.delete("/delete", deleteAccount, { preHandler: [verifyUser], schema: deleteAccountSchema });
}; };

@ -1,40 +1,40 @@
import { Router } from "@/server/router"; import { Router } from "@/server/router";
import { import {
registerPrivilege, registerPrivilege,
getAllPrivilegies, getAllPrivilegies,
getAllPrivilegiesMap, getAllPrivilegiesMap,
getPrivilege, getPrivilege,
getServicePrivilegies, getServicePrivilegies,
replacePrivilege, replacePrivilege,
registerPrivilegies, registerPrivilegies,
removePrivilege, removePrivilege,
replacePrivilegies, replacePrivilegies,
restorePrivilege, restorePrivilege,
} from "@/handlers/privilege"; } from "@/handlers/privilege";
import { import {
getPrivilegiesSchema, getPrivilegiesSchema,
getPrivilegiesMapSchema, getPrivilegiesMapSchema,
getPrivilegeSchema, getPrivilegeSchema,
getServicePrivilegiesSchema, getServicePrivilegiesSchema,
registerPrivilegeSchema, registerPrivilegeSchema,
registerPrivilegiesSchema, registerPrivilegiesSchema,
replacePrivilegeSchema, replacePrivilegeSchema,
replacePrivilegiesSchema, replacePrivilegiesSchema,
removePrivilegeSchema, removePrivilegeSchema,
restorePrivilegeSchema, restorePrivilegeSchema,
} from "@/swagger/privilege"; } from "@/swagger/privilege";
export const setPrivilegeRoutes = (router: Router): void => { export const setPrivilegeRoutes = (router: Router): void => {
router.get("/", getAllPrivilegies, { schema: getPrivilegiesSchema }); router.get("/", getAllPrivilegies, { schema: getPrivilegiesSchema });
router.get("/service", getAllPrivilegiesMap, { schema: getPrivilegiesMapSchema }); router.get("/service", getAllPrivilegiesMap, { schema: getPrivilegiesMapSchema });
router.get("/:privilegeId", getPrivilege, { schema: getPrivilegeSchema }); router.get("/:privilegeId", getPrivilege, { schema: getPrivilegeSchema });
router.get("/service/:serviceKey", getServicePrivilegies, { schema: getServicePrivilegiesSchema }); router.get("/service/:serviceKey", getServicePrivilegies, { schema: getServicePrivilegiesSchema });
router.post("/", registerPrivilege, { schema: registerPrivilegeSchema }); router.post("/", registerPrivilege, { schema: registerPrivilegeSchema });
router.post("/many", registerPrivilegies, { schema: registerPrivilegiesSchema }); router.post("/many", registerPrivilegies, { schema: registerPrivilegiesSchema });
router.post("/restore/", restorePrivilege, { schema: restorePrivilegeSchema }); router.post("/restore/", restorePrivilege, { schema: restorePrivilegeSchema });
router.put("/", replacePrivilege, { schema: replacePrivilegeSchema }); router.put("/", replacePrivilege, { schema: replacePrivilegeSchema });
router.put("/many", replacePrivilegies, { schema: replacePrivilegiesSchema }); router.put("/many", replacePrivilegies, { schema: replacePrivilegiesSchema });
router.delete("/", removePrivilege, { schema: removePrivilegeSchema }); router.delete("/", removePrivilege, { schema: removePrivilegeSchema });
}; };

@ -1,32 +1,32 @@
import { Router } from "@/server/router"; import { Router } from "@/server/router";
import { import {
createTariff, createTariff,
replaceTariff, replaceTariff,
getTariff, getTariff,
getTariffs, getTariffs,
removeTariff, removeTariff,
restoreTariff, restoreTariff,
deleteTariff, deleteTariff,
} from "@/handlers/tariff"; } from "@/handlers/tariff";
import { verifyUser } from "@/handlers/auth/middleware"; import { verifyUser } from "@/handlers/auth/middleware";
import { import {
getTariffSchema, getTariffSchema,
getTariffsSchema, getTariffsSchema,
createTariffsSchema, createTariffsSchema,
replaceTariffsSchema, replaceTariffsSchema,
removeTariffsSchema, removeTariffsSchema,
restoreTariffsSchema, restoreTariffsSchema,
deleteTariffsSchema, deleteTariffsSchema,
} from "@/swagger/tariff"; } from "@/swagger/tariff";
export const setTariffRoutes = (router: Router): void => { export const setTariffRoutes = (router: Router): void => {
router.get("/", getTariffs, { schema: getTariffsSchema }); router.get("/", getTariffs, { schema: getTariffsSchema });
router.get("/:id", getTariff, { schema: getTariffSchema }); router.get("/:id", getTariff, { schema: getTariffSchema });
router.post("/", createTariff, { preHandler: [verifyUser], schema: createTariffsSchema }); router.post("/", createTariff, { preHandler: [verifyUser], schema: createTariffsSchema });
router.post("/restore", restoreTariff, { preHandler: [verifyUser], schema: restoreTariffsSchema }); router.post("/restore", restoreTariff, { preHandler: [verifyUser], schema: restoreTariffsSchema });
router.put("/:id", replaceTariff, { preHandler: [verifyUser], schema: replaceTariffsSchema }); router.put("/:id", replaceTariff, { preHandler: [verifyUser], schema: replaceTariffsSchema });
router.delete("/", removeTariff, { preHandler: [verifyUser], schema: removeTariffsSchema }); router.delete("/", removeTariff, { preHandler: [verifyUser], schema: removeTariffsSchema });
router.delete("/delete", deleteTariff, { preHandler: [verifyUser], schema: deleteTariffsSchema }); router.delete("/delete", deleteTariff, { preHandler: [verifyUser], schema: deleteTariffsSchema });
}; };

@ -1,61 +1,61 @@
import fastify, { FastifyInstance } from "fastify"; import fastify, { FastifyInstance } from "fastify";
import { connect as mongoConnect } from "mongoose"; import { connect as mongoConnect } from "mongoose";
import { Router } from "./router"; import { Router } from "./router";
import { registerFastifyPlugins } from "@/configuration/register-fastify-plugins"; import { registerFastifyPlugins } from "@/configuration/register-fastify-plugins";
import { combineRoutes } from "@/configuration/combine-routes"; import { combineRoutes } from "@/configuration/combine-routes";
import { constituteMongoURI } from "@/configuration/constitute-mongo-uri"; import { constituteMongoURI } from "@/configuration/constitute-mongo-uri";
import { DEFAULT } from "@/constants/default"; import { DEFAULT } from "@/constants/default";
import type { PluginsOptions } from "@/types/configuration/plugins-options"; import type { PluginsOptions } from "@/types/configuration/plugins-options";
import type { DatabaseOptions } from "@/types/configuration/database-options"; import type { DatabaseOptions } from "@/types/configuration/database-options";
type ServerOptions = { type ServerOptions = {
port?: number; port?: number;
host?: string; host?: string;
backlog?: number; backlog?: number;
}; };
type ServerArgs = { type ServerArgs = {
serverOptions?: ServerOptions; serverOptions?: ServerOptions;
pluginsOptions?: PluginsOptions; pluginsOptions?: PluginsOptions;
databaseOptions?: DatabaseOptions; databaseOptions?: DatabaseOptions;
}; };
export class Server { export class Server {
private fastify: FastifyInstance; private fastify: FastifyInstance;
private serverOptions?: ServerOptions; private serverOptions?: ServerOptions;
private databaseOptions?: DatabaseOptions; private databaseOptions?: DatabaseOptions;
/** /**
* Настройка сервера * Настройка сервера
* @param {ServerOptions} serverOptions объект настроек сервера. * @param {ServerOptions} serverOptions объект настроек сервера.
* @param {DatabaseOptions} databaseOptions объект настроек подключения к базе данных. * @param {DatabaseOptions} databaseOptions объект настроек подключения к базе данных.
* @param {PluginsOptions} pluginsOptions объект настроек плагинов fastify. * @param {PluginsOptions} pluginsOptions объект настроек плагинов fastify.
*/ */
constructor({ serverOptions, databaseOptions, pluginsOptions }: ServerArgs) { constructor({ serverOptions, databaseOptions, pluginsOptions }: ServerArgs) {
this.serverOptions = serverOptions; this.serverOptions = serverOptions;
this.databaseOptions = databaseOptions; this.databaseOptions = databaseOptions;
this.fastify = fastify(DEFAULT.fastifyOptions); this.fastify = fastify(DEFAULT.fastifyOptions);
if (pluginsOptions) { if (pluginsOptions) {
registerFastifyPlugins(this.fastify, pluginsOptions); registerFastifyPlugins(this.fastify, pluginsOptions);
} }
combineRoutes(new Router(this.fastify)); combineRoutes(new Router(this.fastify));
} }
public start = async () => { public start = async () => {
const fasticyConnection = this.fastify.listen(this.serverOptions); const fasticyConnection = this.fastify.listen(this.serverOptions);
const databaseConnection = this.databaseOptions ? mongoConnect(constituteMongoURI(this.databaseOptions)) : null; const databaseConnection = this.databaseOptions ? mongoConnect(constituteMongoURI(this.databaseOptions)) : null;
await Promise.all([databaseConnection, fasticyConnection]) await Promise.all([databaseConnection, fasticyConnection])
.then(() => { .then(() => {
this.fastify.swagger(); this.fastify.swagger();
console.info(`server started on ${this.serverOptions?.host}:${this.serverOptions?.port}`); console.info(`server started on ${this.serverOptions?.host}:${this.serverOptions?.port}`);
}) })
.catch((reason) => console.error(reason)); .catch((reason) => console.error(reason));
}; };
} }

@ -1,77 +1,77 @@
import type { import type {
FastifyInstance, FastifyInstance,
RouteHandlerMethod, RouteHandlerMethod,
RawRequestDefaultExpression, RawRequestDefaultExpression,
RawReplyDefaultExpression, RawReplyDefaultExpression,
RouteShorthandOptions, RouteShorthandOptions,
FastifyPluginOptions, FastifyPluginOptions,
RawServerDefault, RawServerDefault,
RouteGenericInterface, RouteGenericInterface,
} from "fastify"; } from "fastify";
type HandlerMethod<T extends RouteGenericInterface> = RouteHandlerMethod< type HandlerMethod<T extends RouteGenericInterface> = RouteHandlerMethod<
RawServerDefault, RawServerDefault,
RawRequestDefaultExpression<RawServerDefault>, RawRequestDefaultExpression<RawServerDefault>,
RawReplyDefaultExpression<RawServerDefault>, RawReplyDefaultExpression<RawServerDefault>,
T T
>; >;
export class Router { export class Router {
private fastifyInstance: FastifyInstance; private fastifyInstance: FastifyInstance;
constructor(fastifyInstance: FastifyInstance) { constructor(fastifyInstance: FastifyInstance) {
this.fastifyInstance = fastifyInstance; this.fastifyInstance = fastifyInstance;
} }
public group = (path: string, combineRoutes: (router: Router) => void) => { public group = (path: string, combineRoutes: (router: Router) => void) => {
this.fastifyInstance.register( this.fastifyInstance.register(
(server: FastifyInstance, opts: FastifyPluginOptions, done: () => void) => { (server: FastifyInstance, opts: FastifyPluginOptions, done: () => void) => {
const router = new Router(server); const router = new Router(server);
combineRoutes(router); combineRoutes(router);
done(); done();
}, },
{ prefix: path } { prefix: path }
); );
}; };
public get = <T extends RouteGenericInterface>( public get = <T extends RouteGenericInterface>(
path: string, path: string,
handler: HandlerMethod<T>, handler: HandlerMethod<T>,
options: RouteShorthandOptions = {} options: RouteShorthandOptions = {}
) => { ) => {
this.fastifyInstance.get(path, options, handler); this.fastifyInstance.get(path, options, handler);
}; };
public post = <T extends RouteGenericInterface>( public post = <T extends RouteGenericInterface>(
path: string, path: string,
handler: HandlerMethod<T>, handler: HandlerMethod<T>,
options: RouteShorthandOptions = {} options: RouteShorthandOptions = {}
) => { ) => {
this.fastifyInstance.post(path, options, handler); this.fastifyInstance.post(path, options, handler);
}; };
public put = <T extends RouteGenericInterface>( public put = <T extends RouteGenericInterface>(
path: string, path: string,
handler: HandlerMethod<T>, handler: HandlerMethod<T>,
options: RouteShorthandOptions = {} options: RouteShorthandOptions = {}
) => { ) => {
this.fastifyInstance.put(path, options, handler); this.fastifyInstance.put(path, options, handler);
}; };
public patch = <T extends RouteGenericInterface>( public patch = <T extends RouteGenericInterface>(
path: string, path: string,
handler: HandlerMethod<T>, handler: HandlerMethod<T>,
options: RouteShorthandOptions = {} options: RouteShorthandOptions = {}
) => { ) => {
this.fastifyInstance.patch(path, options, handler); this.fastifyInstance.patch(path, options, handler);
}; };
public delete = <T extends RouteGenericInterface>( public delete = <T extends RouteGenericInterface>(
path: string, path: string,
handler: HandlerMethod<T>, handler: HandlerMethod<T>,
options: RouteShorthandOptions = {} options: RouteShorthandOptions = {}
) => { ) => {
this.fastifyInstance.delete(path, options, handler); this.fastifyInstance.delete(path, options, handler);
}; };
} }

@ -1,64 +1,64 @@
import { getAccountParams, setAccountRoleBody } from "./inputs"; import { getAccountParams, setAccountRoleBody } from "./inputs";
import { import {
getAccountResponse, getAccountResponse,
createAccountResponse, createAccountResponse,
setAccountRoleResponse, setAccountRoleResponse,
getAccountsResponse, getAccountsResponse,
removeRoleResponse, removeRoleResponse,
} from "./responses"; } from "./responses";
import type { SwaggerSchema } from "@/types/swagger.type"; import type { SwaggerSchema } from "@/types/swagger.type";
export const getAccountsSchema: SwaggerSchema = { export const getAccountsSchema: SwaggerSchema = {
summary: "Получение информации об аккаунтах", summary: "Получение информации об аккаунтах",
description: "Получение всех аккаунтов из БД", description: "Получение всех аккаунтов из БД",
tags: ["account"], tags: ["account"],
response: getAccountsResponse, response: getAccountsResponse,
}; };
export const getAccountSchema: SwaggerSchema = { export const getAccountSchema: SwaggerSchema = {
summary: "Получение информации об аккаунте", summary: "Получение информации об аккаунте",
description: "Получение аккаунта по ID", description: "Получение аккаунта по ID",
tags: ["account"], tags: ["account"],
params: getAccountParams, params: getAccountParams,
response: getAccountResponse, response: getAccountResponse,
}; };
export const createAccountSchema: SwaggerSchema = { export const createAccountSchema: SwaggerSchema = {
summary: "Создание аккаунта", summary: "Создание аккаунта",
tags: ["account"], tags: ["account"],
response: createAccountResponse, response: createAccountResponse,
security: [{ bearer: [] }], security: [{ bearer: [] }],
}; };
export const setAccountRoleSchema: SwaggerSchema = { export const setAccountRoleSchema: SwaggerSchema = {
summary: "Присвоение роли пользователя", summary: "Присвоение роли пользователя",
tags: ["account"], tags: ["account"],
body: setAccountRoleBody, body: setAccountRoleBody,
response: setAccountRoleResponse, response: setAccountRoleResponse,
security: [{ bearer: [] }], security: [{ bearer: [] }],
}; };
export const removeAccountSchema: SwaggerSchema = { export const removeAccountSchema: SwaggerSchema = {
summary: "Удаление аккаунта", summary: "Удаление аккаунта",
description: "Помечает аккаунт удалённым, но не удаляет его из БД", description: "Помечает аккаунт удалённым, но не удаляет его из БД",
tags: ["account"], tags: ["account"],
response: removeRoleResponse, response: removeRoleResponse,
security: [{ bearer: [] }], security: [{ bearer: [] }],
}; };
export const deleteAccountSchema: SwaggerSchema = { export const deleteAccountSchema: SwaggerSchema = {
summary: "Удаление аккаунта", summary: "Удаление аккаунта",
description: "Удаляет аккаунт из БД окончательно", description: "Удаляет аккаунт из БД окончательно",
tags: ["account"], tags: ["account"],
response: removeRoleResponse, response: removeRoleResponse,
security: [{ bearer: [] }], security: [{ bearer: [] }],
}; };
export const restoreAccountSchema: SwaggerSchema = { export const restoreAccountSchema: SwaggerSchema = {
summary: "Восстановление аккаунта", summary: "Восстановление аккаунта",
description: "Восстанавливает аккаунт, который не был удалён окончательно", description: "Восстанавливает аккаунт, который не был удалён окончательно",
tags: ["account"], tags: ["account"],
response: removeRoleResponse, response: removeRoleResponse,
security: [{ bearer: [] }], security: [{ bearer: [] }],
}; };

@ -1,27 +1,27 @@
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
export const getAccountParams: SwaggerMessage = { export const getAccountParams: SwaggerMessage = {
type: "object", type: "object",
required: ["userId"], required: ["userId"],
properties: { properties: {
userId: { userId: {
type: "string", type: "string",
description: "ID пользователя", description: "ID пользователя",
}, },
}, },
}; };
export const setAccountRoleBody: SwaggerMessage = { export const setAccountRoleBody: SwaggerMessage = {
type: "object", type: "object",
required: ["userId", "role"], required: ["userId", "role"],
properties: { properties: {
userId: { userId: {
type: "string", type: "string",
description: "ID пользователя", description: "ID пользователя",
}, },
role: { role: {
type: "string", type: "string",
description: "название роли", description: "название роли",
}, },
}, },
}; };

@ -1,49 +1,49 @@
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
export const account: SwaggerMessage = { export const account: SwaggerMessage = {
description: "Аккаунт", description: "Аккаунт",
type: "object", type: "object",
properties: { properties: {
_id: { type: "string" }, _id: { type: "string" },
userId: { type: "string" }, userId: { type: "string" },
nickname: { type: "string" }, nickname: { type: "string" },
avatar: { type: "string" }, avatar: { type: "string" },
role: { type: "string" }, role: { type: "string" },
isDeleted: { type: "boolean" }, isDeleted: { type: "boolean" },
createdAt: { createdAt: {
type: "string", type: "string",
format: "date-time", format: "date-time",
}, },
updatedAt: { updatedAt: {
type: "string", type: "string",
format: "date-time", format: "date-time",
}, },
deletedAt: { deletedAt: {
type: "string", type: "string",
format: "date-time", format: "date-time",
}, },
}, },
examples: [ examples: [
{ {
_id: "807f1f77bcf81cd799439011", _id: "807f1f77bcf81cd799439011",
userId: "507f1f77bcf86cd799439011", userId: "507f1f77bcf86cd799439011",
nickname: "Ivanov Ivan Ivanovich", nickname: "Ivanov Ivan Ivanovich",
avatar: "/media/avatar/default-avatar.jpg", avatar: "/media/avatar/default-avatar.jpg",
role: "user", role: "user",
isDeleted: false, isDeleted: false,
createdAt: "2017-07-21T17:32:28Z", createdAt: "2017-07-21T17:32:28Z",
updatedAt: "2017-07-21T17:32:28Z", updatedAt: "2017-07-21T17:32:28Z",
}, },
{ {
_id: "807f1f77bcf81cd799439011", _id: "807f1f77bcf81cd799439011",
userId: "507f1f77bcf86cd799439011", userId: "507f1f77bcf86cd799439011",
nickname: "Ivanov Ivan Ivanovich", nickname: "Ivanov Ivan Ivanovich",
avatar: "/media/avatar/default-avatar.jpg", avatar: "/media/avatar/default-avatar.jpg",
role: "user", role: "user",
isDeleted: true, isDeleted: true,
createdAt: "2017-07-21T17:32:28Z", createdAt: "2017-07-21T17:32:28Z",
updatedAt: "2019-04-14T15:32:15Z", updatedAt: "2019-04-14T15:32:15Z",
deletedAt: "2021-08-17T13:23:44Z", deletedAt: "2021-08-17T13:23:44Z",
}, },
], ],
}; };

@ -1,40 +1,40 @@
import { swaggerError } from "@/utils/swagger-error"; import { swaggerError } from "@/utils/swagger-error";
import { account } from "./models"; import { account } from "./models";
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
export const getAccountsResponse: Record<string, SwaggerMessage> = { export const getAccountsResponse: Record<string, SwaggerMessage> = {
200: { 200: {
type: "array", type: "array",
description: "Массив аккаунтов", description: "Массив аккаунтов",
items: account, items: account,
}, },
}; };
export const getAccountResponse: Record<string, SwaggerMessage> = { export const getAccountResponse: Record<string, SwaggerMessage> = {
200: account, 200: account,
400: swaggerError(400, "invalid user id"), 400: swaggerError(400, "invalid user id"),
}; };
export const createAccountResponse: Record<string, SwaggerMessage> = { export const createAccountResponse: Record<string, SwaggerMessage> = {
200: account, 200: account,
400: swaggerError(400, "invalid user id"), 400: swaggerError(400, "invalid user id"),
401: swaggerError(401, "invalid token"), 401: swaggerError(401, "invalid token"),
404: swaggerError(404, "user not found"), 404: swaggerError(404, "user not found"),
409: swaggerError(409, "account already exist"), 409: swaggerError(409, "account already exist"),
}; };
export const setAccountRoleResponse: Record<string, SwaggerMessage> = { export const setAccountRoleResponse: Record<string, SwaggerMessage> = {
200: account, 200: account,
400: swaggerError(400, "invalid user id"), 400: swaggerError(400, "invalid user id"),
401: swaggerError(401, "invalid token"), 401: swaggerError(401, "invalid token"),
404: swaggerError(404, "user not found"), 404: swaggerError(404, "user not found"),
}; };
export const removeRoleResponse: Record<string, SwaggerMessage> = { export const removeRoleResponse: Record<string, SwaggerMessage> = {
200: account, 200: account,
400: swaggerError(400, "invalid user id"), 400: swaggerError(400, "invalid user id"),
401: swaggerError(401, "invalid token"), 401: swaggerError(401, "invalid token"),
404: swaggerError(404, "user not found"), 404: swaggerError(404, "user not found"),
}; };

@ -1,84 +1,84 @@
import { privilegeBody, registerPrivilegiesBody, getPrivilegeParams, getServicePrivilegiesParams } from "./inputs"; import { privilegeBody, registerPrivilegiesBody, getPrivilegeParams, getServicePrivilegiesParams } from "./inputs";
import { import {
getPrivilegeReponse, getPrivilegeReponse,
getPrivilegiesReponse, getPrivilegiesReponse,
getAllPrivilegiesMapReponse, getAllPrivilegiesMapReponse,
getAllPrivilegiesReponse, getAllPrivilegiesReponse,
registerPrivilegeResponse, registerPrivilegeResponse,
replacePrivilegeResponse, replacePrivilegeResponse,
registerPrivilegiesResponse, registerPrivilegiesResponse,
replacePrivilegiesResponse, replacePrivilegiesResponse,
removePrivilegeResponse, removePrivilegeResponse,
} from "./responses"; } from "./responses";
import type { SwaggerSchema } from "@/types/swagger.type"; import type { SwaggerSchema } from "@/types/swagger.type";
export const getPrivilegiesSchema: SwaggerSchema = { export const getPrivilegiesSchema: SwaggerSchema = {
summary: "Получение всех привелегий", summary: "Получение всех привелегий",
description: "Получение всех привелегий в виде массива", description: "Получение всех привелегий в виде массива",
tags: ["privilege"], tags: ["privilege"],
response: getAllPrivilegiesReponse, response: getAllPrivilegiesReponse,
}; };
export const getPrivilegiesMapSchema: SwaggerSchema = { export const getPrivilegiesMapSchema: SwaggerSchema = {
summary: "Получение всех привелегий", summary: "Получение всех привелегий",
description: "Получение всех привелегий в виде объекта ключ-значение, где ключём является serviceKey", description: "Получение всех привелегий в виде объекта ключ-значение, где ключём является serviceKey",
tags: ["privilege"], tags: ["privilege"],
response: getAllPrivilegiesMapReponse, response: getAllPrivilegiesMapReponse,
}; };
export const getPrivilegeSchema: SwaggerSchema = { export const getPrivilegeSchema: SwaggerSchema = {
summary: "Получение привилегии по ID", summary: "Получение привилегии по ID",
tags: ["privilege"], tags: ["privilege"],
params: getPrivilegeParams, params: getPrivilegeParams,
response: getPrivilegeReponse, response: getPrivilegeReponse,
}; };
export const getServicePrivilegiesSchema: SwaggerSchema = { export const getServicePrivilegiesSchema: SwaggerSchema = {
summary: "Получение привилегий сервиса", summary: "Получение привилегий сервиса",
tags: ["privilege"], tags: ["privilege"],
params: getServicePrivilegiesParams, params: getServicePrivilegiesParams,
response: getPrivilegiesReponse, response: getPrivilegiesReponse,
}; };
export const registerPrivilegeSchema: SwaggerSchema = { export const registerPrivilegeSchema: SwaggerSchema = {
summary: "Регистрация привелегии сервиса", summary: "Регистрация привелегии сервиса",
tags: ["privilege"], tags: ["privilege"],
body: privilegeBody, body: privilegeBody,
response: registerPrivilegeResponse, response: registerPrivilegeResponse,
}; };
export const registerPrivilegiesSchema: SwaggerSchema = { export const registerPrivilegiesSchema: SwaggerSchema = {
summary: "Регистрация привелегий сервиса", summary: "Регистрация привелегий сервиса",
tags: ["privilege"], tags: ["privilege"],
body: registerPrivilegiesBody, body: registerPrivilegiesBody,
response: registerPrivilegiesResponse, response: registerPrivilegiesResponse,
}; };
export const replacePrivilegeSchema: SwaggerSchema = { export const replacePrivilegeSchema: SwaggerSchema = {
summary: "Замена привилегии сервиса", summary: "Замена привилегии сервиса",
tags: ["privilege"], tags: ["privilege"],
body: privilegeBody, body: privilegeBody,
response: replacePrivilegeResponse, response: replacePrivilegeResponse,
}; };
export const replacePrivilegiesSchema: SwaggerSchema = { export const replacePrivilegiesSchema: SwaggerSchema = {
summary: "Замена привилегий сервиса", summary: "Замена привилегий сервиса",
tags: ["privilege"], tags: ["privilege"],
body: registerPrivilegiesBody, body: registerPrivilegiesBody,
response: replacePrivilegiesResponse, response: replacePrivilegiesResponse,
}; };
export const removePrivilegeSchema: SwaggerSchema = { export const removePrivilegeSchema: SwaggerSchema = {
summary: "Удаление привелегии", summary: "Удаление привелегии",
tags: ["privilege"], tags: ["privilege"],
body: getPrivilegeParams, body: getPrivilegeParams,
response: removePrivilegeResponse, response: removePrivilegeResponse,
}; };
export const restorePrivilegeSchema: SwaggerSchema = { export const restorePrivilegeSchema: SwaggerSchema = {
summary: "Восстановление привилегии", summary: "Восстановление привилегии",
tags: ["privilege"], tags: ["privilege"],
body: getPrivilegeParams, body: getPrivilegeParams,
response: removePrivilegeResponse, response: removePrivilegeResponse,
}; };

@ -1,62 +1,62 @@
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
export const privilegeBody: SwaggerMessage = { export const privilegeBody: SwaggerMessage = {
type: "object", type: "object",
required: ["name", "privilegeId", "serviceKey", "description", "type", "value", "price"], required: ["name", "privilegeId", "serviceKey", "description", "type", "value", "price"],
properties: { properties: {
name: { type: "string" }, name: { type: "string" },
privilegeId: { type: "string" }, privilegeId: { type: "string" },
serviceKey: { type: "string" }, serviceKey: { type: "string" },
description: { type: "string" }, description: { type: "string" },
type: { type: "string" }, type: { type: "string" },
value: { type: "string" }, value: { type: "string" },
price: { type: "number" }, price: { type: "number" },
}, },
examples: [ examples: [
{ {
name: "Количество попыток использования", name: "Количество попыток использования",
privilegeId: "507f1f77bcf86cd799439011", privilegeId: "507f1f77bcf86cd799439011",
serviceKey: "docx-templater-service", serviceKey: "docx-templater-service",
description: "Количество попыток использования", description: "Количество попыток использования",
type: "count", type: "count",
value: "200", value: "200",
price: 12300, price: 12300,
}, },
], ],
}; };
export const privilegiesBody: SwaggerMessage = { export const privilegiesBody: SwaggerMessage = {
type: "array", type: "array",
items: privilegeBody, items: privilegeBody,
}; };
export const registerPrivilegiesBody: SwaggerMessage = { export const registerPrivilegiesBody: SwaggerMessage = {
type: "object", type: "object",
properties: { properties: {
privilegies: privilegiesBody, privilegies: privilegiesBody,
}, },
}; };
export const getPrivilegeParams: SwaggerMessage = { export const getPrivilegeParams: SwaggerMessage = {
type: "object", type: "object",
required: ["privilegeId"], required: ["privilegeId"],
properties: { properties: {
privilegeId: { privilegeId: {
type: "string", type: "string",
description: "ID привилегии (privilegeId)", description: "ID привилегии (privilegeId)",
}, },
}, },
examples: [{ privilegeId: "507f1f77bcf86cd799439011" }], examples: [{ privilegeId: "507f1f77bcf86cd799439011" }],
}; };
export const getServicePrivilegiesParams: SwaggerMessage = { export const getServicePrivilegiesParams: SwaggerMessage = {
type: "object", type: "object",
required: ["serviceKey"], required: ["serviceKey"],
properties: { properties: {
serviceKey: { serviceKey: {
type: "string", type: "string",
description: "Ключ сервиса", description: "Ключ сервиса",
}, },
}, },
examples: [{ serviceKey: "docx-templater-service" }], examples: [{ serviceKey: "docx-templater-service" }],
}; };

@ -1,46 +1,46 @@
import type { SwaggerMessage, SwaggerValueType } from "@/types/swagger.type"; import type { SwaggerMessage, SwaggerValueType } from "@/types/swagger.type";
const privilegeExamples: SwaggerValueType[] = [ const privilegeExamples: SwaggerValueType[] = [
{ {
_id: "207f1f67bcf86cd799439011", _id: "207f1f67bcf86cd799439011",
name: "Количество попыток использования", name: "Количество попыток использования",
privilegeId: "507f1f77bcf86cd799439011", privilegeId: "507f1f77bcf86cd799439011",
serviceKey: "docx-templater-service", serviceKey: "docx-templater-service",
description: "Количество попыток использования", description: "Количество попыток использования",
type: "count", type: "count",
value: "200", value: "200",
price: 12300, price: 12300,
isDeleted: false, isDeleted: false,
createdAt: "2017-07-21T17:32:28Z", createdAt: "2017-07-21T17:32:28Z",
updatedAt: "2017-07-21T17:32:28Z", updatedAt: "2017-07-21T17:32:28Z",
}, },
]; ];
export const privilege: SwaggerMessage = { export const privilege: SwaggerMessage = {
type: "object", type: "object",
description: "Привилегия", description: "Привилегия",
properties: { properties: {
_id: { type: "string" }, _id: { type: "string" },
name: { type: "string" }, name: { type: "string" },
privilegeId: { type: "string" }, privilegeId: { type: "string" },
serviceKey: { type: "string" }, serviceKey: { type: "string" },
description: { type: "string" }, description: { type: "string" },
type: { type: "string" }, type: { type: "string" },
value: { type: "string" }, value: { type: "string" },
price: { type: "number" }, price: { type: "number" },
isDeleted: { type: "boolean" }, isDeleted: { type: "boolean" },
createdAt: { createdAt: {
type: "string", type: "string",
format: "date-time", format: "date-time",
}, },
updatedAt: { updatedAt: {
type: "string", type: "string",
format: "date-time", format: "date-time",
}, },
deletedAt: { deletedAt: {
type: "string", type: "string",
format: "date-time", format: "date-time",
}, },
}, },
examples: privilegeExamples, examples: privilegeExamples,
}; };

@ -1,95 +1,95 @@
import { swaggerError } from "@/utils/swagger-error"; import { swaggerError } from "@/utils/swagger-error";
import { privilege } from "./models"; import { privilege } from "./models";
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
export const getAllPrivilegiesReponse: Record<string, SwaggerMessage> = { export const getAllPrivilegiesReponse: Record<string, SwaggerMessage> = {
200: { 200: {
type: "array", type: "array",
description: "Привилегии", description: "Привилегии",
items: privilege, items: privilege,
}, },
}; };
export const getAllPrivilegiesMapReponse: Record<string, SwaggerMessage> = { export const getAllPrivilegiesMapReponse: Record<string, SwaggerMessage> = {
200: { 200: {
type: "object", type: "object",
description: "Привилегии", description: "Привилегии",
properties: { properties: {
additionalProperties: { additionalProperties: {
type: "array", type: "array",
description: "Привилегии", description: "Привилегии",
items: privilege, items: privilege,
}, },
}, },
additionalProperties: true, additionalProperties: true,
example: { example: {
"docx-templater-service": [ "docx-templater-service": [
{ {
_id: "63a7b01f1f4117cf861d6d1e", _id: "63a7b01f1f4117cf861d6d1e",
name: "Количество попыток использования", name: "Количество попыток использования",
privilegeId: "507f1f77bcf86cd799439011", privilegeId: "507f1f77bcf86cd799439011",
serviceKey: "docx-templater-service", serviceKey: "docx-templater-service",
description: "Количество попыток использования", description: "Количество попыток использования",
type: "count", type: "count",
value: "200", value: "200",
price: 12300, price: 12300,
updatedAt: "2022-12-25T02:47:52.405Z", updatedAt: "2022-12-25T02:47:52.405Z",
isDeleted: false, isDeleted: false,
createdAt: "2022-12-25T02:47:52.406Z", createdAt: "2022-12-25T02:47:52.406Z",
}, },
], ],
}, },
}, },
}; };
export const getPrivilegiesReponse: Record<string, SwaggerMessage> = { export const getPrivilegiesReponse: Record<string, SwaggerMessage> = {
200: { 200: {
type: "array", type: "array",
description: "Массив привилегий", description: "Массив привилегий",
items: privilege, items: privilege,
}, },
}; };
export const getPrivilegeReponse: Record<string, SwaggerMessage> = { export const getPrivilegeReponse: Record<string, SwaggerMessage> = {
200: privilege, 200: privilege,
400: swaggerError(400, "invalid id"), 400: swaggerError(400, "invalid id"),
404: swaggerError(404, "privilege not found"), 404: swaggerError(404, "privilege not found"),
}; };
export const registerPrivilegeResponse: Record<string, SwaggerMessage> = { export const registerPrivilegeResponse: Record<string, SwaggerMessage> = {
200: privilege, 200: privilege,
400: swaggerError(400, "price must be a number"), 400: swaggerError(400, "price must be a number"),
409: swaggerError(409, "privilege already exist"), 409: swaggerError(409, "privilege already exist"),
}; };
export const registerPrivilegiesResponse: Record<string, SwaggerMessage> = { export const registerPrivilegiesResponse: Record<string, SwaggerMessage> = {
200: { 200: {
type: "array", type: "array",
description: "Массив привилегий", description: "Массив привилегий",
items: privilege, items: privilege,
}, },
400: swaggerError(400, "price must be a number"), 400: swaggerError(400, "price must be a number"),
}; };
export const replacePrivilegeResponse: Record<string, SwaggerMessage> = { export const replacePrivilegeResponse: Record<string, SwaggerMessage> = {
200: privilege, 200: privilege,
400: swaggerError(400, "invalid 'type' value"), 400: swaggerError(400, "invalid 'type' value"),
404: swaggerError(404, "privilege not found"), 404: swaggerError(404, "privilege not found"),
}; };
export const replacePrivilegiesResponse: Record<string, SwaggerMessage> = { export const replacePrivilegiesResponse: Record<string, SwaggerMessage> = {
200: { 200: {
type: "array", type: "array",
description: "Массив привилегий", description: "Массив привилегий",
items: privilege, items: privilege,
}, },
400: swaggerError(400, "invalid 'type' value"), 400: swaggerError(400, "invalid 'type' value"),
}; };
export const removePrivilegeResponse: Record<string, SwaggerMessage> = { export const removePrivilegeResponse: Record<string, SwaggerMessage> = {
200: privilege, 200: privilege,
400: swaggerError(400, "invalid id"), 400: swaggerError(400, "invalid id"),
404: swaggerError(404, "privilege not found"), 404: swaggerError(404, "privilege not found"),
}; };

@ -1,32 +1,32 @@
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
export const role: SwaggerMessage = { export const role: SwaggerMessage = {
type: "object", type: "object",
description: "Роль", description: "Роль",
properties: { properties: {
_id: { type: "string" }, _id: { type: "string" },
name: { type: "string" }, name: { type: "string" },
permissions: { permissions: {
type: "object", type: "object",
additionalProperties: { type: "boolean" }, additionalProperties: { type: "boolean" },
}, },
}, },
examples: [ examples: [
{ {
_id: "638388e120c70c17eb123d37", _id: "638388e120c70c17eb123d37",
name: "user", name: "user",
permissions: { permissions: {
read: true, read: true,
write: false, write: false,
}, },
}, },
{ {
_id: "638388f720c70c17eb123d3a", _id: "638388f720c70c17eb123d3a",
name: "admin", name: "admin",
permissions: { permissions: {
read: true, read: true,
write: true, write: true,
}, },
}, },
], ],
}; };

@ -1,51 +1,51 @@
import { swaggerError } from "@/utils/swagger-error"; import { swaggerError } from "@/utils/swagger-error";
import { role } from "./models"; import { role } from "./models";
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
export const getRolesReponse: Record<string, SwaggerMessage> = { export const getRolesReponse: Record<string, SwaggerMessage> = {
200: { 200: {
type: "array", type: "array",
description: "Массив ролей", description: "Массив ролей",
items: role, items: role,
}, },
}; };
export const getRoleReponse: Record<string, SwaggerMessage> = { export const getRoleReponse: Record<string, SwaggerMessage> = {
200: role, 200: role,
400: swaggerError(400, "query is empty"), 400: swaggerError(400, "query is empty"),
404: swaggerError(404, "role not found"), 404: swaggerError(404, "role not found"),
}; };
export const createRoleReponse: Record<string, SwaggerMessage> = { export const createRoleReponse: Record<string, SwaggerMessage> = {
200: role, 200: role,
400: swaggerError(400, "field <name> is empty"), 400: swaggerError(400, "field <name> is empty"),
409: swaggerError(409, "role already exist"), 409: swaggerError(409, "role already exist"),
}; };
export const restoreRoleReponse: Record<string, SwaggerMessage> = { export const restoreRoleReponse: Record<string, SwaggerMessage> = {
200: role, 200: role,
400: swaggerError(400, "wrong id"), 400: swaggerError(400, "wrong id"),
404: swaggerError(404, "role by id not found"), 404: swaggerError(404, "role by id not found"),
409: swaggerError(409, "role not removed"), 409: swaggerError(409, "role not removed"),
}; };
export const updateRoleReponse: Record<string, SwaggerMessage> = { export const updateRoleReponse: Record<string, SwaggerMessage> = {
200: role, 200: role,
400: swaggerError(400, "either name or permissions must be filled"), 400: swaggerError(400, "either name or permissions must be filled"),
404: swaggerError(404, "role not found"), 404: swaggerError(404, "role not found"),
}; };
export const removeRoleReponse: Record<string, SwaggerMessage> = { export const removeRoleReponse: Record<string, SwaggerMessage> = {
200: role, 200: role,
400: swaggerError(400, "wrong id"), 400: swaggerError(400, "wrong id"),
404: swaggerError(404, "role by id not found"), 404: swaggerError(404, "role by id not found"),
409: swaggerError(409, "role already deleted"), 409: swaggerError(409, "role already deleted"),
}; };
export const deleteRoleReponse: Record<string, SwaggerMessage> = { export const deleteRoleReponse: Record<string, SwaggerMessage> = {
200: role, 200: role,
400: swaggerError(400, "wrong id"), 400: swaggerError(400, "wrong id"),
404: swaggerError(404, "role not found"), 404: swaggerError(404, "role not found"),
}; };

@ -1,66 +1,66 @@
import { getTariffParams, tariffBody, replaceTariffParams } from "./inputs"; import { getTariffParams, tariffBody, replaceTariffParams } from "./inputs";
import { import {
getTariffReponse, getTariffReponse,
getTariffsReponse, getTariffsReponse,
createTariffReponse, createTariffReponse,
replaceTariffReponse, replaceTariffReponse,
removeTariffReponse, removeTariffReponse,
} from "./responses"; } from "./responses";
import type { SwaggerSchema } from "@/types/swagger.type"; import type { SwaggerSchema } from "@/types/swagger.type";
export const getTariffSchema: SwaggerSchema = { export const getTariffSchema: SwaggerSchema = {
summary: "Получение тарифа", summary: "Получение тарифа",
tags: ["tariff"], tags: ["tariff"],
params: getTariffParams, params: getTariffParams,
response: getTariffReponse, response: getTariffReponse,
}; };
export const getTariffsSchema: SwaggerSchema = { export const getTariffsSchema: SwaggerSchema = {
summary: "Получение списка тарифов", summary: "Получение списка тарифов",
tags: ["tariff"], tags: ["tariff"],
response: getTariffsReponse, response: getTariffsReponse,
}; };
export const createTariffsSchema: SwaggerSchema = { export const createTariffsSchema: SwaggerSchema = {
summary: "Создание тарифа", summary: "Создание тарифа",
tags: ["tariff"], tags: ["tariff"],
body: tariffBody, body: tariffBody,
security: [{ bearer: [] }], security: [{ bearer: [] }],
response: createTariffReponse, response: createTariffReponse,
}; };
export const replaceTariffsSchema: SwaggerSchema = { export const replaceTariffsSchema: SwaggerSchema = {
summary: "Замена тарифа", summary: "Замена тарифа",
tags: ["tariff"], tags: ["tariff"],
params: replaceTariffParams, params: replaceTariffParams,
body: tariffBody, body: tariffBody,
security: [{ bearer: [] }], security: [{ bearer: [] }],
response: replaceTariffReponse, response: replaceTariffReponse,
}; };
export const removeTariffsSchema: SwaggerSchema = { export const removeTariffsSchema: SwaggerSchema = {
summary: "Удаление тарифа", summary: "Удаление тарифа",
description: "Помечает тариф удалённым, но не удаляет его из БД", description: "Помечает тариф удалённым, но не удаляет его из БД",
tags: ["tariff"], tags: ["tariff"],
body: getTariffParams, body: getTariffParams,
security: [{ bearer: [] }], security: [{ bearer: [] }],
response: removeTariffReponse, response: removeTariffReponse,
}; };
export const deleteTariffsSchema: SwaggerSchema = { export const deleteTariffsSchema: SwaggerSchema = {
summary: "Удаление тарифа", summary: "Удаление тарифа",
description: "Удаляет тариф из БД окончательно", description: "Удаляет тариф из БД окончательно",
tags: ["tariff"], tags: ["tariff"],
body: getTariffParams, body: getTariffParams,
security: [{ bearer: [] }], security: [{ bearer: [] }],
response: removeTariffReponse, response: removeTariffReponse,
}; };
export const restoreTariffsSchema: SwaggerSchema = { export const restoreTariffsSchema: SwaggerSchema = {
summary: "Восстановление тарифа", summary: "Восстановление тарифа",
tags: ["tariff"], tags: ["tariff"],
body: getTariffParams, body: getTariffParams,
security: [{ bearer: [] }], security: [{ bearer: [] }],
response: removeTariffReponse, response: removeTariffReponse,
}; };

@ -1,48 +1,48 @@
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
export const getTariffParams: SwaggerMessage = { export const getTariffParams: SwaggerMessage = {
type: "object", type: "object",
required: ["id"], required: ["id"],
properties: { properties: {
id: { id: {
type: "string", type: "string",
description: "ID тарифа", description: "ID тарифа",
}, },
}, },
examples: [{ id: "507f1f77bcf86cd799439011" }], examples: [{ id: "507f1f77bcf86cd799439011" }],
}; };
export const tariffBody: SwaggerMessage = { export const tariffBody: SwaggerMessage = {
type: "object", type: "object",
description: "Тариф", description: "Тариф",
required: ["name", "price", "isCustom", "privilegieIDArray"], required: ["name", "price", "isCustom", "privilegieIDArray"],
properties: { properties: {
name: { type: "string" }, name: { type: "string" },
price: { type: "number" }, price: { type: "number" },
isCustom: { type: "boolean" }, isCustom: { type: "boolean" },
privilegieIDArray: { privilegieIDArray: {
type: "array", type: "array",
items: { type: "string" }, items: { type: "string" },
}, },
}, },
examples: [ examples: [
{ {
name: "Использование сервисов", name: "Использование сервисов",
price: 14000, price: 14000,
isCustom: false, isCustom: false,
privilegieIDArray: ["507f1f77bcf86cd799439011"], privilegieIDArray: ["507f1f77bcf86cd799439011"],
}, },
], ],
}; };
export const replaceTariffParams: SwaggerMessage = { export const replaceTariffParams: SwaggerMessage = {
type: "object", type: "object",
required: ["id"], required: ["id"],
properties: { properties: {
id: { id: {
type: "string", type: "string",
description: "ID тарифа", description: "ID тарифа",
}, },
}, },
examples: [{ id: "63a7d47ba24613f98562bafa" }], examples: [{ id: "63a7d47ba24613f98562bafa" }],
}; };

@ -1,97 +1,97 @@
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
const privilege: SwaggerMessage = { const privilege: SwaggerMessage = {
type: "object", type: "object",
description: "Привилегия", description: "Привилегия",
properties: { properties: {
_id: { type: "string" }, _id: { type: "string" },
name: { type: "string" }, name: { type: "string" },
privilegeId: { type: "string" }, privilegeId: { type: "string" },
serviceKey: { type: "string" }, serviceKey: { type: "string" },
description: { type: "string" }, description: { type: "string" },
type: { type: "string" }, type: { type: "string" },
value: { type: "string" }, value: { type: "string" },
price: { type: "number" }, price: { type: "number" },
}, },
examples: [ examples: [
{ {
_id: "507f1f77bcf86cd799439011", _id: "507f1f77bcf86cd799439011",
name: "Количество попыток использования", name: "Количество попыток использования",
privilegeId: "507f1f77bcf86cd799439011", privilegeId: "507f1f77bcf86cd799439011",
serviceKey: "docx-templater-service", serviceKey: "docx-templater-service",
description: "Количество попыток использования сервиса генерации шаблонов", description: "Количество попыток использования сервиса генерации шаблонов",
type: "count", type: "count",
value: "200", value: "200",
price: 12300, price: 12300,
}, },
], ],
}; };
export const tariff: SwaggerMessage = { export const tariff: SwaggerMessage = {
type: "object", type: "object",
description: "Тариф", description: "Тариф",
properties: { properties: {
_id: { type: "string" }, _id: { type: "string" },
name: { type: "string" }, name: { type: "string" },
price: { type: "number" }, price: { type: "number" },
isCustom: { type: "boolean" }, isCustom: { type: "boolean" },
privilegies: { privilegies: {
type: "object", type: "object",
additionalProperties: privilege, additionalProperties: privilege,
}, },
isDeleted: { type: "boolean" }, isDeleted: { type: "boolean" },
createdAt: { createdAt: {
type: "string", type: "string",
format: "date-time", format: "date-time",
}, },
updatedAt: { updatedAt: {
type: "string", type: "string",
format: "date-time", format: "date-time",
}, },
deletedAt: { deletedAt: {
type: "string", type: "string",
format: "date-time", format: "date-time",
}, },
}, },
examples: [ examples: [
{ {
name: "Использование сервисов", name: "Использование сервисов",
price: 14000, price: 14000,
isCustom: false, isCustom: false,
privilegies: { privilegies: {
"507f1f77bcf86cd799439011": { "507f1f77bcf86cd799439011": {
name: "507f1f77bcf86cd799439011", name: "507f1f77bcf86cd799439011",
privilegeId: "507f1f77bcf86cd799439011", privilegeId: "507f1f77bcf86cd799439011",
serviceKey: "docx-templater-service", serviceKey: "docx-templater-service",
description: "Количество попыток использования", description: "Количество попыток использования",
type: "count", type: "count",
value: "200", value: "200",
price: 12300, price: 12300,
}, },
}, },
isDeleted: false, isDeleted: false,
createdAt: "2017-07-21T17:32:28Z", createdAt: "2017-07-21T17:32:28Z",
updatedAt: "2017-07-21T17:32:28Z", updatedAt: "2017-07-21T17:32:28Z",
}, },
{ {
name: "user", name: "user",
price: 14000, price: 14000,
isCustom: false, isCustom: false,
privilegies: { privilegies: {
"507f1f77bcf86cd799439011": { "507f1f77bcf86cd799439011": {
name: "507f1f77bcf86cd799439011", name: "507f1f77bcf86cd799439011",
privilegeId: "507f1f77bcf86cd799439011", privilegeId: "507f1f77bcf86cd799439011",
serviceKey: "docx-templater-service", serviceKey: "docx-templater-service",
description: "Количество попыток использования", description: "Количество попыток использования",
type: "count", type: "count",
value: "200", value: "200",
price: 12300, price: 12300,
}, },
}, },
isDeleted: true, isDeleted: true,
createdAt: "2017-07-21T17:32:28Z", createdAt: "2017-07-21T17:32:28Z",
updatedAt: "2019-04-14T15:32:15Z", updatedAt: "2019-04-14T15:32:15Z",
deletedAt: "2021-08-17T13:23:44Z", deletedAt: "2021-08-17T13:23:44Z",
}, },
], ],
}; };

@ -1,40 +1,40 @@
import { swaggerError } from "@/utils/swagger-error"; import { swaggerError } from "@/utils/swagger-error";
import { tariff } from "./models"; import { tariff } from "./models";
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
export const getTariffReponse: Record<string, SwaggerMessage> = { export const getTariffReponse: Record<string, SwaggerMessage> = {
200: tariff, 200: tariff,
400: swaggerError(400, "invalid id"), 400: swaggerError(400, "invalid id"),
404: swaggerError(404, "tariff not found"), 404: swaggerError(404, "tariff not found"),
}; };
export const getTariffsReponse: Record<string, SwaggerMessage> = { export const getTariffsReponse: Record<string, SwaggerMessage> = {
200: { 200: {
type: "array", type: "array",
description: "Массив тарифов", description: "Массив тарифов",
items: tariff, items: tariff,
}, },
}; };
export const createTariffReponse: Record<string, SwaggerMessage> = { export const createTariffReponse: Record<string, SwaggerMessage> = {
200: tariff, 200: tariff,
400: swaggerError(400, "invalid 'price' value"), 400: swaggerError(400, "invalid 'price' value"),
401: swaggerError(400, "invalid user id"), 401: swaggerError(400, "invalid user id"),
404: swaggerError(404, "privilege with id <privilegeId> not found"), 404: swaggerError(404, "privilege with id <privilegeId> not found"),
}; };
export const replaceTariffReponse: Record<string, SwaggerMessage> = { export const replaceTariffReponse: Record<string, SwaggerMessage> = {
200: tariff, 200: tariff,
400: swaggerError(400, "invalid id"), 400: swaggerError(400, "invalid id"),
401: swaggerError(400, "invalid user id"), 401: swaggerError(400, "invalid user id"),
404: swaggerError(404, "tariff not found"), 404: swaggerError(404, "tariff not found"),
}; };
export const removeTariffReponse: Record<string, SwaggerMessage> = { export const removeTariffReponse: Record<string, SwaggerMessage> = {
200: tariff, 200: tariff,
400: swaggerError(400, "invalid id"), 400: swaggerError(400, "invalid id"),
401: swaggerError(400, "invalid user id"), 401: swaggerError(400, "invalid user id"),
404: swaggerError(404, "tariff not found"), 404: swaggerError(404, "tariff not found"),
}; };

@ -1,9 +1,9 @@
import type { Eloquent } from "../models/eloquent.type"; import type { Eloquent } from "../models/eloquent.type";
import type { Tariff } from "../models/tariff.type"; import type { Tariff } from "../models/tariff.type";
import type { ObjectWithPossibleFields } from "../object-with-possible-fields"; import type { ObjectWithPossibleFields } from "../object-with-possible-fields";
export type TariffMessage = ObjectWithPossibleFields< export type TariffMessage = ObjectWithPossibleFields<
Omit<Tariff, keyof Eloquent | "privilegies"> & { Omit<Tariff, keyof Eloquent | "privilegies"> & {
privilegieIDArray: string[]; privilegieIDArray: string[];
} }
>; >;

@ -1,50 +1,50 @@
import type { FastifySchema } from "fastify"; import type { FastifySchema } from "fastify";
export type SwaggerValueType = export type SwaggerValueType =
| string | string
| number | number
| boolean | boolean
| null | null
| SwaggerValueType[] | SwaggerValueType[]
| { [key: string]: SwaggerValueType }; | { [key: string]: SwaggerValueType };
type SwaggerMediaType = "object" | "string" | "integer" | "boolean" | "array" | "number"; type SwaggerMediaType = "object" | "string" | "integer" | "boolean" | "array" | "number";
type SwaggerMediaFormat = type SwaggerMediaFormat =
| "binary" | "binary"
| "base64" | "base64"
| "uuid" | "uuid"
| "email" | "email"
| "date" | "date"
| "date-time" | "date-time"
| "password" | "password"
| "byte" | "byte"
| "uri" | "uri"
| "hostname" | "hostname"
| "ipv4" | "ipv4"
| "ipv6"; | "ipv6";
export type SwaggerMessage = { export type SwaggerMessage = {
type?: SwaggerMediaType; type?: SwaggerMediaType;
description?: string; description?: string;
format?: SwaggerMediaFormat; format?: SwaggerMediaFormat;
pattern?: string; pattern?: string;
nullable?: boolean; nullable?: boolean;
uniqueItems?: boolean; uniqueItems?: boolean;
writeOnly?: boolean; writeOnly?: boolean;
readOnly?: boolean; readOnly?: boolean;
items?: SwaggerMessage; items?: SwaggerMessage;
additionalProperties?: SwaggerMessage | boolean; additionalProperties?: SwaggerMessage | boolean;
properties?: Record<string, SwaggerMessage | Record<string, SwaggerValueType>>; properties?: Record<string, SwaggerMessage | Record<string, SwaggerValueType>>;
examples?: SwaggerValueType[]; examples?: SwaggerValueType[];
example?: SwaggerValueType; example?: SwaggerValueType;
required?: string[]; required?: string[];
oneOf?: SwaggerMessage[]; oneOf?: SwaggerMessage[];
allOf?: SwaggerMessage[]; allOf?: SwaggerMessage[];
}; };
export type SwaggerSchema = FastifySchema & { export type SwaggerSchema = FastifySchema & {
params?: SwaggerMessage; params?: SwaggerMessage;
body?: SwaggerMessage; body?: SwaggerMessage;
querystring?: SwaggerMessage; querystring?: SwaggerMessage;
response?: Record<number, SwaggerMessage>; response?: Record<number, SwaggerMessage>;
}; };

@ -1,20 +1,20 @@
import type { SwaggerMessage } from "@/types/swagger.type"; import type { SwaggerMessage } from "@/types/swagger.type";
const STATUS_CODE_MAP: Record<number, string> = { const STATUS_CODE_MAP: Record<number, string> = {
400: "Bad Request", 400: "Bad Request",
401: "Unauthorized", 401: "Unauthorized",
404: "Not Found", 404: "Not Found",
409: "Conflict", 409: "Conflict",
500: "Internal Server Error", 500: "Internal Server Error",
}; };
export const swaggerError = (code: number, message: string): SwaggerMessage => ({ export const swaggerError = (code: number, message: string): SwaggerMessage => ({
type: "object", type: "object",
description: STATUS_CODE_MAP[code], description: STATUS_CODE_MAP[code],
properties: { properties: {
statusCode: { type: "integer" }, statusCode: { type: "integer" },
error: { type: "string" }, error: { type: "string" },
message: { type: "string" }, message: { type: "string" },
}, },
examples: [{ statusCode: code, error: STATUS_CODE_MAP[code], message: message }], examples: [{ statusCode: code, error: STATUS_CODE_MAP[code], message: message }],
}); });