This commit is contained in:
Arda Özdere 2023-10-10 23:52:57 +02:00
parent fab0964610
commit 2a7f2a97a6
20 changed files with 39 additions and 39 deletions

View file

@ -36,13 +36,13 @@ app.use(
validateRequests: true,
// also validate our responses to the clients
validateResponses: true,
})
}),
);
// Instantiate dependencies and pass them to the respective components needed for our use cases
const budgetUseCases = BudgetService(
BudgetSummaryMongoRepository(),
BudgetMongoRepository()
BudgetMongoRepository(),
);
const expenseUseCases = ExpenseService(ExpenseMongoRepository());
app.use(ApiRouter(budgetUseCases, expenseUseCases));

View file

@ -20,7 +20,7 @@ if (environment.LOG_LEVEL === "debug") {
};
logger.debug(
`\x1B[0;36mMongoose:\x1B[0m: ${collectionName}.${methodName}` +
`(${methodArgs.map(msgMapper).join(", ")})`
`(${methodArgs.map(msgMapper).join(", ")})`,
);
});
}

View file

@ -5,7 +5,7 @@ class Limit {
if (amount < 0) {
throw new AppError(
"InvalidLimit",
`Limits cannot be negative: ${amount}`
`Limits cannot be negative: ${amount}`,
);
}
}

View file

@ -7,7 +7,7 @@ const expressLogger = expressWinston.logger({
transports: [new winston.transports.Console()],
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple()
winston.format.simple(),
),
meta: true,
expressFormat: true,

View file

@ -11,9 +11,9 @@ logger.add(
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize({ all: true }),
winston.format.simple()
winston.format.simple(),
),
})
}),
);
/*

View file

@ -13,7 +13,7 @@ export class AppError extends Error {
public message: string,
public HTTPStatus: number = 500,
public isTrusted = true,
public cause?: unknown
public cause?: unknown,
) {
super(message);
}
@ -34,14 +34,14 @@ export const listenToErrorEvents = (httpServer: Http.Server): void => {
process.on("SIGTERM", () => {
logger.error(
"App received SIGTERM event, try to gracefully close the server"
"App received SIGTERM event, try to gracefully close the server",
);
terminateHttpServerAndExit();
});
process.on("SIGINT", () => {
logger.error(
"App received SIGINT event, try to gracefully close the server"
"App received SIGINT event, try to gracefully close the server",
);
terminateHttpServerAndExit();
});
@ -58,7 +58,7 @@ const handleError = (errorToHandle: unknown): void => {
} catch (handlingError: unknown) {
// Not using the logger here because it might have failed
process.stdout.write(
"The error handler failed, here are the handler failure and then the origin error that it tried to handle"
"The error handler failed, here are the handler failure and then the origin error that it tried to handle",
);
process.stdout.write(JSON.stringify(handlingError));
process.stdout.write(JSON.stringify(errorToHandle));
@ -86,8 +86,8 @@ const normalizeError = (errorToHandle: unknown): AppError => {
return new AppError(
"general-error",
`Error Handler received a none error instance with type - ${inputType}, value - ${util.inspect(
errorToHandle
)}`
errorToHandle,
)}`,
);
};
@ -95,7 +95,7 @@ export const errorHandler = (
err: Error,
_: Request,
res: Response,
next: NextFunction
next: NextFunction,
): void => {
if (typeof err === "object") {
const error = err as AppError;

View file

@ -27,7 +27,7 @@ const args = parse<Args>(
alias: "e",
},
},
{ partial: true }
{ partial: true },
);
// Set the env file

View file

@ -4,7 +4,7 @@ import { type BudgetId } from "../../../domain/budget";
import { BudgetSummaryModel } from "./models";
export const insertBudgetSummary: BudgetSummaryRepository["insert"] = async (
summary
summary,
) => {
const summaryEntity = BudgetSummaryEntityConverter.toEntity(summary);
const summaryModel = new BudgetSummaryModel(summaryEntity);
@ -13,7 +13,7 @@ export const insertBudgetSummary: BudgetSummaryRepository["insert"] = async (
};
export const findBudgetSummary: BudgetSummaryRepository["find"] = async (
budgetId: BudgetId
budgetId: BudgetId,
) => {
const found = await BudgetSummaryModel.findOne({ id: budgetId.value });
if (found != null) {

View file

@ -5,5 +5,5 @@ import type BudgetSummaryEntity from "../entity/budgetSummaryEntity";
export const BudgetSummaryModel = mongoose.model<BudgetSummaryEntity>(
"BudgetSummary",
budgetSummarySchema,
"budget-summaries"
"budget-summaries",
);

View file

@ -14,7 +14,7 @@ const budgetSummarySchema = new mongoose.Schema<BudgetSummaryEntity>(
endDate: Types.Date,
expenses: [expenseSchema],
},
{ strict: true, timestamps: true, versionKey: false }
{ strict: true, timestamps: true, versionKey: false },
);
export default budgetSummarySchema;

View file

@ -6,7 +6,7 @@ interface ExpenseRepository {
insert: (
budgetId: BudgetId,
spent: number,
expense: Expense
expense: Expense,
) => Promise<Expense | undefined>;
}

View file

@ -15,7 +15,7 @@ export const findAllExpensesForBudget: ExpenseRepository["findAllForBudget"] =
export const insertExpense: ExpenseRepository["insert"] = async (
budgetId,
spent,
expense
expense,
) => {
const expenseEntity = ExpenseEntityConverter.toEntity(expense);
const updatedSummary = await BudgetSummaryModel.findOneAndUpdate(
@ -24,10 +24,10 @@ export const insertExpense: ExpenseRepository["insert"] = async (
$set: { spent },
$push: { expenses: expenseEntity },
},
{ returnDocument: "after" }
{ returnDocument: "after" },
);
const updatedExpense = updatedSummary?.expenses.find(
(t) => t.id === expense.id.value
(t) => t.id === expense.id.value,
);
if (updatedExpense !== undefined) {
return ExpenseEntityConverter.toDomain(updatedExpense);

View file

@ -10,7 +10,7 @@ const expenseSchema = new mongoose.Schema<ExpenseEntity>(
amount: Types.Number,
date: Types.Date,
},
{ strict: true, _id: false }
{ strict: true, _id: false },
);
export default expenseSchema;

View file

@ -7,7 +7,7 @@ import type ExpenseUseCases from "../usecase/expense/expenseUseCases";
// Express router bundling all individual routes of our app
const ApiRouter = (
budgetUseCases: BudgetUseCases,
expenseUseCases: ExpenseUseCases
expenseUseCases: ExpenseUseCases,
): Router => {
const router = Router();
router.use(BudgetRouter(budgetUseCases));

View file

@ -51,7 +51,7 @@ export const deleteBudget =
const budgetId = new UUID(req.params.budgetId);
const deleteResult = await deleteBudget(budgetId);
res.sendStatus(
deleteResult.deleted ? StatusCodes.NO_CONTENT : StatusCodes.NOT_FOUND
deleteResult.deleted ? StatusCodes.NO_CONTENT : StatusCodes.NOT_FOUND,
);
};
@ -59,19 +59,19 @@ const BudgetRouter = (budgetUseCases: BudgetUseCases): Router => {
const router = Router();
router.post(
toExpressPath(apiPaths.createBudget),
asyncHandler(createBudget(budgetUseCases.createBudget))
asyncHandler(createBudget(budgetUseCases.createBudget)),
);
router.get(
toExpressPath(apiPaths.getBudgets),
asyncHandler(getBudgets(budgetUseCases.getBudgets))
asyncHandler(getBudgets(budgetUseCases.getBudgets)),
);
router.get(
toExpressPath(apiPaths.getBudgetSummary),
asyncHandler(getBudgetSummary(budgetUseCases.getBudgetSummary))
asyncHandler(getBudgetSummary(budgetUseCases.getBudgetSummary)),
);
router.delete(
toExpressPath(apiPaths.deleteBudget),
asyncHandler(deleteBudget(budgetUseCases.deleteBudget))
asyncHandler(deleteBudget(budgetUseCases.deleteBudget)),
);
return router;

View file

@ -25,7 +25,7 @@ const ExpenseRouter = (expenseUseCases: ExpenseUseCases): Router => {
const router = Router();
router.post(
toExpressPath(apiPaths.createExpense),
asyncHandler(createExpense(expenseUseCases.addToBudget))
asyncHandler(createExpense(expenseUseCases.addToBudget)),
);
return router;

View file

@ -23,7 +23,7 @@ describe("budgetService", () => {
// THEN
expect(insertBudgetMock).toBeCalledWith(expect.objectContaining(newBudget));
expect(insertedBudgetSummary).toEqual(
expect.objectContaining(expectedBudget)
expect.objectContaining(expectedBudget),
);
});
});

View file

@ -21,7 +21,7 @@ import type BudgetRepository from "../../repository/budget/budgetRepository";
class ClassicBudgetService implements BudgetUseCases {
constructor(
private readonly budgetSummaryRepo: BudgetSummaryRepository,
private readonly budgetRepo: BudgetRepository
private readonly budgetRepo: BudgetRepository,
) {}
async createBudget(newBudget: NewBudget): Promise<Budget> {
@ -48,7 +48,7 @@ class ClassicBudgetService implements BudgetUseCases {
}
async getBudgetSummary(
budgetId: BudgetId
budgetId: BudgetId,
): Promise<BudgetSummary | undefined> {
return await this.budgetSummaryRepo.find(budgetId);
}

View file

@ -6,7 +6,7 @@ import currency from "currency.js";
const addNewExpenseToBudget: (
findAll: ExpenseRepository["findAllForBudget"],
insert: ExpenseRepository["insert"]
insert: ExpenseRepository["insert"],
) => ExpenseUseCases["addToBudget"] =
(findAll, insert) => async (budgetId, newExpense) => {
const existingExpenses = await findAll(budgetId);
@ -34,15 +34,15 @@ const addNewExpenseToBudget: (
const calculateSpent = (expenses: Expense[], newExpense: Expense): number =>
expenses.reduce(
(prev, curr) => prev.add(curr.amount),
currency(newExpense.amount)
currency(newExpense.amount),
).value;
const ExpenseService: (
expenseRepository: ExpenseRepository
expenseRepository: ExpenseRepository,
) => ExpenseUseCases = (expenseRepository) => ({
addToBudget: addNewExpenseToBudget(
expenseRepository.findAllForBudget,
expenseRepository.insert
expenseRepository.insert,
),
});

View file

@ -9,7 +9,7 @@ interface ExpenseUseCases {
*/
addToBudget: (
budgetId: BudgetId,
newExpense: NewExpense
newExpense: NewExpense,
) => Promise<Expense | undefined>;
}