Skip to content

Commit

Permalink
Merge pull request #69 from letehaha/feat/improve-shared-types
Browse files Browse the repository at this point in the history
feat: Move backend-related types out of shared-types
  • Loading branch information
letehaha authored Jul 8, 2023
2 parents b1d3757 + 00fa17c commit 7220803
Show file tree
Hide file tree
Showing 42 changed files with 940 additions and 668 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"editor.insertSpaces": true,
"editor.tabSize": 2
}
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default {
'shared-types': '<rootDir>/shared-types',
'@routes/(.*)': '<rootDir>/src/routes/$1',
'@middlewares/(.*)': '<rootDir>/src/middlewares/$1',
'@common/(.*)': '<rootDir>/src/common/$1',
'@controllers/(.*)': '<rootDir>/src/controllers/$1',
'@models/(.*)': '<rootDir>/src/models/$1',
'@js/(.*)': '<rootDir>/src/js/$1',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@js": "src/js",
"@routes": "src/routes",
"@middlewares": "src/middlewares",
"@common": "src/common",
"@controllers": "src/controllers",
"@models": "src/models",
"@services": "src/services",
Expand Down
10 changes: 6 additions & 4 deletions shared-types/error-codes/api.ts → shared-types/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export enum ERROR_CODES {
export enum API_RESPONSE_STATUS {
error = 'error',
success = 'success',
}

export enum API_ERROR_CODES {
// general
tooManyRequests = 'TOO_MANY_REQUESTS',
notFound = 'NOT_FOUND',
Expand All @@ -17,9 +22,6 @@ export enum ERROR_CODES {
monobankUserNotExist = 'MONOBANK_USER_NOT_EXIST',
monobankTokenInvalid = 'MONOBANK_USER_TOKEN_INVALID',

// transactions service
txServiceUpdateBalance = 'CANNOT_UPDATE_BALANCE',

// crypto/binance
cryptoBinanceBothAPIKeysDoesNotexist = 10101,
cryptoBinancePublicAPIKeyNotDefined = 10102,
Expand Down
File renamed without changes.
20 changes: 3 additions & 17 deletions shared-types/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
import type { Response } from 'express';

export enum RESPONSE_STATUS {
error = 'error',
success = 'success',
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Send<ResBody = any, T = Response<ResBody>> = (body?: ResBody) => T;
export interface CustomResponse extends Response {
json: Send<{
status: RESPONSE_STATUS,
response?: unknown,
}, this>
}

export enum ACCOUNT_TYPES {
system = 'system',
monobank = 'monobank',
Expand All @@ -40,4 +24,6 @@ export enum CATEGORY_TYPES {
internal = 'internal',
}

export * from './error-codes';
export * from './api';
export * from './models';
export * as endpointsTypes from './routes';
57 changes: 57 additions & 0 deletions shared-types/models/external-services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* More info here:
*
* @link https://api.monobank.ua/docs/#tag/Kliyentski-personalni-dani/paths/~1personal~1client-info/get
*/
export interface ExternalMonobankClientInfoResponse {
clientId: string;
name: string;
webHookUrl: string;
permissions: string;
accounts: {
id: string;
sendId: string;
balance: number;
creditLimit: number;
type: 'black' | 'white' | 'platinum' | 'iron' | 'fop' | 'yellow' | 'eAid';
currencyCode: number;
cashbackType: 'None' | 'UAH' | 'Miles';
maskedPan: string[];
iban: string;
}[];
jars: {
id: string;
sendId: string;
title: string;
description: string;
currencyCode: number;
balance: number;
goal: number;
}[]
}

/**
* More info
*
* @link https://api.monobank.ua/docs/#tag/Kliyentski-personalni-dani/paths/~1personal~1webhook/post
*/
export type ExternalMonobankTransactionResponse = {
id: string;
time: number;
description: string;
mcc: number;
originalMcc: number;
hold: boolean;
amount: number;
operationAmount: number;
currencyCode: number;
commissionRate: number;
cashbackAmount: number;
balance: number;
comment: string;
receiptId: string;
invoiceId: string;
counterEdrpou: string;
counterIban: string;
counterName: string;
}
95 changes: 95 additions & 0 deletions shared-types/models/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
ACCOUNT_TYPES,
CATEGORY_TYPES,
TRANSACTION_TYPES,
PAYMENT_TYPES,
} from 'shared-types';
import { ExternalMonobankTransactionResponse } from './external-services';
export * from './external-services';

export interface UserModel {
id: number;
username: string;
email: string;
password?: string;
firstName: string;
lastName: string;
middleName: string;
avatar: string;
totalBalance: number;
defaultCategoryId: number;
}


export interface CategoryModel {
color: string;
id: number;
imageUrl: null | string;
name: string;
parentId: null | number;
subCategories: CategoryModel[];
type: CATEGORY_TYPES;
userId: number;
}

export interface AccountModel {
systemType: ACCOUNT_TYPES.system,
id: number;
name: string;
currentBalance: number;
refCurrentBalance: number;
creditLimit: number;
refCreditLimit: number;
accountTypeId: number;
currencyId: number;
userId: number;
}

export interface MonobankAccountModel {
id: number;
systemType: ACCOUNT_TYPES.monobank,
accountId: string;
balance: number;
creditLimit: number;
cashbackType: string;
maskedPan: string[];
type: string;
iban: string;
isEnabled: boolean;
name: string;
createdAt?: string;
updatedAt?: string;
monoUserId: number;
currencyId: number;
accountTypeId: number;
}

export interface MonobankUserModel {
id: number;
clientId: string;
name: string;
webHookUrl?: string
systemUserId: number;
apiToken: string;
}

export interface MonobankTrasnactionModel {
id: number;
originalId: ExternalMonobankTransactionResponse['id'];
description: ExternalMonobankTransactionResponse['description'];
amount: ExternalMonobankTransactionResponse['amount'];
time: Date;
operationAmount: ExternalMonobankTransactionResponse['operationAmount'];
commissionRate: ExternalMonobankTransactionResponse['commissionRate'];
cashbackAmount: ExternalMonobankTransactionResponse['cashbackAmount'];
balance: ExternalMonobankTransactionResponse['balance'];
hold: ExternalMonobankTransactionResponse['hold'];
userId: number;
categoryId: number;
transactionType: TRANSACTION_TYPES;
paymentType: PAYMENT_TYPES;
monoAccountId: number;
currencyId: number;
accountType: ACCOUNT_TYPES;
note: string;
}
4 changes: 4 additions & 0 deletions shared-types/routes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './monobank';

export type BodyPayload<T> = T
export type QueryPayload<T> = T
19 changes: 19 additions & 0 deletions shared-types/routes/monobank.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MonobankUserModel } from 'shared-types';
import { BodyPayload } from './index'

export interface UpdateMonobankTransactionBody extends BodyPayload<{
id: number;
categoryId?: number;
note?: string;
}> {}

export interface PairMonobankAccountBody extends BodyPayload<{
token: MonobankUserModel['apiToken']
}> {}

export interface UpdateMonobankUserBody extends BodyPayload<{
apiToken?: string;
name?: string;
webHookUrl?: string;
clientId?: string;
}> {}
17 changes: 17 additions & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Response } from 'express';
import { Transaction } from 'sequelize/types';
import { API_RESPONSE_STATUS } from 'shared-types';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Send<ResBody = any, T = Response<ResBody>> = (body?: ResBody) => T;
export interface CustomResponse extends Response {
json: Send<{
status: API_RESPONSE_STATUS,
response?: unknown,
}, this>
}


export interface GenericSequelizeModelAttributes {
transaction?: Transaction,
}
11 changes: 6 additions & 5 deletions src/controllers/account-types.controller.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { RESPONSE_STATUS, CustomResponse, ERROR_CODES } from 'shared-types';
import * as AccountTypes from '../models/AccountTypes.model';
import { API_ERROR_CODES, API_RESPONSE_STATUS } from 'shared-types';
import { CustomResponse } from '@common/types';
import * as AccountTypes from '@models/AccountTypes.model';

export const getAccountTypes = async (req, res: CustomResponse) => {
try {
const data = await AccountTypes.getAccountTypes();

return res.status(200).json({
status: RESPONSE_STATUS.success,
status: API_RESPONSE_STATUS.success,
response: data,
});
} catch (err) {
return res.status(500).json({
status: RESPONSE_STATUS.error,
status: API_RESPONSE_STATUS.error,
response: {
message: 'Unexpected error.',
code: ERROR_CODES.unexpected,
code: API_ERROR_CODES.unexpected,
},
});
}
Expand Down
34 changes: 16 additions & 18 deletions src/controllers/accounts.controller.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { RESPONSE_STATUS, CustomResponse } from 'shared-types';

import * as accountsService from '../services/accounts.service';

import * as Accounts from '../models/Accounts.model';
import { API_RESPONSE_STATUS } from 'shared-types';
import { CustomResponse } from '@common/types';
import * as accountsService from '@services/accounts.service';

export const getAccounts = async (req, res: CustomResponse, next) => {
const { id: userId } = req.user;

try {
const accounts = await Accounts.getAccounts({ userId });
const accounts = await accountsService.getAccounts({ userId });

return res.status(200).json({
status: RESPONSE_STATUS.success,
status: API_RESPONSE_STATUS.success,
response: accounts,
});
} catch (err) {
Expand All @@ -24,11 +22,11 @@ export const getAccountById = async (req, res: CustomResponse, next) => {
const { id: userId } = req.user;

try {
const accounts = await Accounts.getAccountById({ userId, id });
const account = await accountsService.getAccountById({ userId, id });

return res.status(200).json({
status: RESPONSE_STATUS.success,
response: accounts,
status: API_RESPONSE_STATUS.success,
response: account,
});
} catch (err) {
return next(err);
Expand All @@ -46,7 +44,7 @@ export const createAccount = async (req, res, next) => {
const { id: userId } = req.user;

try {
const data = await Accounts.createAccount({
const account = await accountsService.createAccount({
accountTypeId,
currencyId,
name,
Expand All @@ -56,8 +54,8 @@ export const createAccount = async (req, res, next) => {
});

return res.status(200).json({
status: RESPONSE_STATUS.success,
response: data,
status: API_RESPONSE_STATUS.success,
response: account,
});
} catch (err) {
return next(err);
Expand All @@ -76,7 +74,7 @@ export const updateAccount = async (req, res, next) => {
} = req.body;

try {
const data = await accountsService.updateAccount({
const account = await accountsService.updateAccount({
id,
userId,

Expand All @@ -88,8 +86,8 @@ export const updateAccount = async (req, res, next) => {
});

return res.status(200).json({
status: RESPONSE_STATUS.success,
response: data,
status: API_RESPONSE_STATUS.success,
response: account,
});
} catch (err) {
return next(err);
Expand All @@ -100,9 +98,9 @@ export const deleteAccount = async (req, res, next) => {
const { id } = req.params;

try {
await Accounts.deleteAccountById({ id });
await accountsService.deleteAccountById({ id });

return res.status(200).json({ status: RESPONSE_STATUS.success });
return res.status(200).json({ status: API_RESPONSE_STATUS.success });
} catch (err) {
return next(err);
}
Expand Down
Loading

0 comments on commit 7220803

Please sign in to comment.