Compare commits
No commits in common. "7046c5adc99ecf90a0ae89e1e4cdeae35a8a74fb" and "0c70c66cf26be96f7ee8c45f280c267553d216ec" have entirely different histories.
7046c5adc9
...
0c70c66cf2
@ -8,7 +8,7 @@
|
|||||||
"start": "next start --port 4000",
|
"start": "next start --port 4000",
|
||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"seed": "node -r dotenv/config ./src/bootstrap/boundaries/db/seed.js"
|
"seed": "node -r dotenv/config ./src/bootstrap/db/seed.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^2.1.5",
|
"@heroicons/react": "^2.1.5",
|
||||||
@ -16,7 +16,6 @@
|
|||||||
"@radix-ui/react-slot": "^1.1.0",
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"fp-ts": "^2.16.9",
|
|
||||||
"lucide-react": "^0.454.0",
|
"lucide-react": "^0.454.0",
|
||||||
"next": "15.0.2",
|
"next": "15.0.2",
|
||||||
"postgres": "^3.4.5",
|
"postgres": "^3.4.5",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import fetchCustomerInvoicesUsecase from "@/feature/core/customer-invoice/domain/usecase/fetch-customer-invoices-usecase";
|
import fetchCustomerInvoicesUsecase from "@/feature/core/customer-invoice/domain/usecase/fetch-customer-invoices-usecase";
|
||||||
|
|
||||||
export default async function latestInvoicesController() {
|
export default function latestInvoicesController() {
|
||||||
return await fetchCustomerInvoicesUsecase()
|
return fetchCustomerInvoicesUsecase()
|
||||||
}
|
}
|
@ -2,15 +2,12 @@ import CreateRandomInvoiceContainer from '@/app/dashboard/components/client/crea
|
|||||||
import latestInvoicesController from '@/app/dashboard/components/server/latest-invoices/latest-invoices-controller';
|
import latestInvoicesController from '@/app/dashboard/components/server/latest-invoices/latest-invoices-controller';
|
||||||
import { ArrowPathIcon } from '@heroicons/react/24/outline';
|
import { ArrowPathIcon } from '@heroicons/react/24/outline';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { isLeft } from 'fp-ts/lib/Either';
|
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
|
||||||
export default async function LatestInvoices() {
|
export default async function LatestInvoices() {
|
||||||
const latestInvoices = await latestInvoicesController();
|
const latestInvoices = await latestInvoicesController();
|
||||||
|
|
||||||
if (isLeft(latestInvoices)) return <div>Error</div>
|
const invoices = latestInvoices.map((invoice, i) => {
|
||||||
|
|
||||||
const invoices = latestInvoices.right.map((invoice, i) => {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={invoice.id}
|
key={invoice.id}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { revalidatePath } from 'next/cache';
|
import { revalidatePath } from 'next/cache';
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
import { sql } from '@/bootstrap/boundaries/db/db';
|
import { sql } from '@/bootstrap/db/db';
|
||||||
|
|
||||||
const FormSchema = z.object({
|
const FormSchema = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import { Either } from "fp-ts/lib/Either";
|
|
||||||
import { TaskEither } from "fp-ts/lib/TaskEither";
|
|
||||||
import BaseFailure from "@/feature/common/failures/base-failure";
|
|
||||||
|
|
||||||
type ApiTask<ResponseType> = TaskEither<BaseFailure, ResponseType>;
|
|
||||||
export type ApiEither<ResponseType> = Either<BaseFailure, ResponseType>;
|
|
||||||
|
|
||||||
export default ApiTask;
|
|
@ -1,22 +0,0 @@
|
|||||||
import { makeFailureMessage } from "@/feature/common/failures/failure-helpers";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a class called BaseFailure that extends the Error class. It is
|
|
||||||
* used as a base class for creating custom failure classes.
|
|
||||||
*/
|
|
||||||
export default abstract class BaseFailure {
|
|
||||||
/* ------------------------------- Attributes ------------------------------- */
|
|
||||||
private readonly BASE_FAILURE_MESSAGE = "failure";
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* Use this message as key lang for failure messages
|
|
||||||
*/
|
|
||||||
message = this.BASE_FAILURE_MESSAGE;
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
constructor(key: string) {
|
|
||||||
this.message = makeFailureMessage(this.message, key);
|
|
||||||
}
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import BaseDevFailure from "@/feature/common/failures/dev/base-dev-failure";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Failure for needed arguments in a method but sent wrong one
|
|
||||||
*/
|
|
||||||
export default class ArgumentsFailure extends BaseDevFailure {
|
|
||||||
/* ------------------------------- Constructor ------------------------------ */
|
|
||||||
constructor() {
|
|
||||||
super("arguments");
|
|
||||||
}
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
import BaseFailure from "@/feature/common/failures/base-failure";
|
|
||||||
|
|
||||||
export default abstract class BaseDevFailure extends BaseFailure {}
|
|
@ -1,10 +0,0 @@
|
|||||||
import BaseDevFailure from "@/feature/common/failures/dev/base-dev-failure";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a failure of not having specific dependency
|
|
||||||
*/
|
|
||||||
export default class DependencyFailure extends BaseDevFailure {
|
|
||||||
constructor() {
|
|
||||||
super("DependencyFailure");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
import BaseFailure from "@/feature/common/failures/base-failure";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is supposed to save previous failure of TaskEither
|
|
||||||
* to prevent it from loosing and overriding by the new one.
|
|
||||||
*
|
|
||||||
* Usage example:
|
|
||||||
* ```ts
|
|
||||||
* tryCatch(
|
|
||||||
* async () => {
|
|
||||||
* ...
|
|
||||||
* throw ValidationFailure();
|
|
||||||
* ...
|
|
||||||
* },
|
|
||||||
* (reason) => failureOr(reason, new UserCreationFailure()),
|
|
||||||
* )
|
|
||||||
* ```
|
|
||||||
* In this example `failureOr` will return already throwed
|
|
||||||
* instance of `BaseFailure` which is `ValidationFailure`.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param reason is throwed object.
|
|
||||||
* Basically it can be default `Error` or instance of `BaseFailure`.
|
|
||||||
* @param failure instance of `BaseFailure` that will be returned
|
|
||||||
* if reason is not instance of `BaseFailure`.
|
|
||||||
* @returns `BaseFailure`
|
|
||||||
*/
|
|
||||||
export function failureOr(reason: unknown, failure: BaseFailure): BaseFailure {
|
|
||||||
if (reason instanceof BaseFailure) {
|
|
||||||
return reason;
|
|
||||||
}
|
|
||||||
return failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a function that maps a BaseFailure instance to a new BaseFailure instance of type IfType using the provided mapping function.
|
|
||||||
* @param f A function that maps an instance of IfType to a new instance of BaseFailure.
|
|
||||||
* @param ctor A constructor function for IfType.
|
|
||||||
* @returns A function that maps a BaseFailure instance to a new BaseFailure instance of type IfType.
|
|
||||||
*/
|
|
||||||
export function mapToFailureFrom<IfType extends BaseFailure>(
|
|
||||||
f: (t: IfType) => BaseFailure,
|
|
||||||
ctor: new (...args: never[]) => IfType,
|
|
||||||
): (t: BaseFailure) => BaseFailure {
|
|
||||||
return mapIfInstance<IfType, BaseFailure>(f, ctor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps an instance of a class to a response using a provided function.
|
|
||||||
*
|
|
||||||
* @template IfType - The type of the instance to map.
|
|
||||||
* @template Response - The type of the response to map to.
|
|
||||||
* @param {function} f - The function to use to map the instance to a response.
|
|
||||||
* @param {new (...args: never[]) => IfType} ctor - The constructor function of the instance to map.
|
|
||||||
* @returns {(t: IfType | Response) => IfType | Response} - A function that maps the instance to a response using the provided function.
|
|
||||||
*/
|
|
||||||
export function mapIfInstance<IfType, Response>(
|
|
||||||
f: (t: IfType) => Response,
|
|
||||||
ctor: new (...args: never[]) => IfType,
|
|
||||||
) {
|
|
||||||
return (t: IfType | Response) => {
|
|
||||||
if (t instanceof ctor) {
|
|
||||||
return f(t);
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a function to a value if it is not an instance of a given class.
|
|
||||||
* @template IfType The type of the value to be mapped.
|
|
||||||
* @template Response The type of the mapped value.
|
|
||||||
* @param {function} f The function to map the value with.
|
|
||||||
* @param {new (...args: never[]) => IfType} ctor The class to check the value against.
|
|
||||||
* @returns {function} A function that maps the value if it is not an instance of the given class.
|
|
||||||
*/
|
|
||||||
export function mapIfNotInstance<IfType, Response>(
|
|
||||||
f: (t: IfType) => Response,
|
|
||||||
ctor: new (...args: never[]) => IfType,
|
|
||||||
) {
|
|
||||||
return (t: IfType | Response) => {
|
|
||||||
if (t! instanceof ctor) {
|
|
||||||
return f(t);
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets Message key and it'll add it to the failure message key hierarchy
|
|
||||||
*/
|
|
||||||
export function makeFailureMessage(message: string, key: string) {
|
|
||||||
if (!key) return message;
|
|
||||||
return `${message}.${key}`;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import BaseFailure from "./base-failure";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Failure for HTTP response when response dosn't have base structure
|
|
||||||
*/
|
|
||||||
export default class NetworkFailure extends BaseFailure {
|
|
||||||
/* ------------------------------- Constructor ------------------------------ */
|
|
||||||
constructor() {
|
|
||||||
super("network");
|
|
||||||
}
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import BaseFailure from "./base-failure";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Failure for params failure
|
|
||||||
*/
|
|
||||||
export default class ParamsFailure extends BaseFailure {
|
|
||||||
/* ------------------------------- Constructor ------------------------------ */
|
|
||||||
constructor() {
|
|
||||||
super("params");
|
|
||||||
}
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
}
|
|
@ -1,12 +1,7 @@
|
|||||||
import { sql } from "@/bootstrap/boundaries/db/db";
|
import { sql } from "@/bootstrap/db/db";
|
||||||
import ApiTask from "@/feature/common/data/api-task";
|
|
||||||
import { failureOr } from "@/feature/common/failures/failure-helpers";
|
|
||||||
import NetworkFailure from "@/feature/common/failures/network-failure";
|
|
||||||
import { formatCurrency } from "@/feature/common/feature-helpers";
|
import { formatCurrency } from "@/feature/common/feature-helpers";
|
||||||
import CustomerInvoice from "@/feature/core/customer-invoice/domain/entity/customer-invoice";
|
import CustomerInvoice from "@/feature/core/customer-invoice/domain/entity/customer-invoice";
|
||||||
import CustomerInvoiceRepo from "@/feature/core/customer-invoice/domain/i-repo/customer-invoice-repo";
|
import CustomerInvoiceRepo from "@/feature/core/customer-invoice/domain/i-repo/customer-invoice-repo";
|
||||||
import { pipe } from "fp-ts/lib/function";
|
|
||||||
import { tryCatch } from "fp-ts/lib/TaskEither";
|
|
||||||
import postgres from "postgres";
|
import postgres from "postgres";
|
||||||
|
|
||||||
type customerInvoiceDbResponse = {
|
type customerInvoiceDbResponse = {
|
||||||
@ -18,25 +13,23 @@ type customerInvoiceDbResponse = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class CustomerInvoiceDbRepo implements CustomerInvoiceRepo {
|
export default class CustomerInvoiceDbRepo implements CustomerInvoiceRepo {
|
||||||
fetchList(): ApiTask<CustomerInvoice[]> {
|
async fetchList(): Promise<CustomerInvoice[]> {
|
||||||
|
try {
|
||||||
|
const data = await sql`
|
||||||
|
SELECT invoices.amount, customers.name, customers.image_url, customers.email, invoices.id
|
||||||
|
FROM invoices
|
||||||
|
JOIN customers ON invoices.customer_id = customers.id
|
||||||
|
ORDER BY invoices.date DESC
|
||||||
|
LIMIT 20 ` as postgres.RowList<customerInvoiceDbResponse[]>;
|
||||||
|
|
||||||
return pipe(
|
return this.customerInvoicesDto(data)
|
||||||
tryCatch(
|
} catch (error) {
|
||||||
async () => {
|
console.error('Database Error:', error);
|
||||||
const response = await sql`
|
throw new Error('Failed to fetch the latest invoices.');
|
||||||
SELECT invoices.amount, customers.name, customers.image_url, customers.email, invoices.id
|
}
|
||||||
FROM invoices
|
|
||||||
JOIN customers ON invoices.customer_id = customers.id
|
|
||||||
ORDER BY invoices.date DESC
|
|
||||||
LIMIT 20 ` as postgres.RowList<customerInvoiceDbResponse[]>;
|
|
||||||
|
|
||||||
return this.customerInvoicesDto(response)
|
|
||||||
},
|
|
||||||
(l) => failureOr(l, new NetworkFailure())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private customerInvoicesDto(dbCustomers: customerInvoiceDbResponse[]): CustomerInvoice[] {
|
private customerInvoicesDto(dbCustomers: customerInvoiceDbResponse[]): CustomerInvoice[] {
|
||||||
return dbCustomers.map((customer) => this.customerInvoiceDto(customer));
|
return dbCustomers.map((customer) => this.customerInvoiceDto(customer));
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import ApiTask from "@/feature/common/data/api-task"
|
|
||||||
import CustomerInvoice from "@/feature/core/customer-invoice/domain/entity/customer-invoice"
|
import CustomerInvoice from "@/feature/core/customer-invoice/domain/entity/customer-invoice"
|
||||||
|
|
||||||
export default interface CustomerInvoiceRepo {
|
export default interface CustomerInvoiceRepo {
|
||||||
fetchList(): ApiTask<CustomerInvoice[]>
|
fetchList(): Promise<CustomerInvoice[]>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const customerInvoiceRepoKey = "customerInvoiceRepoKey"
|
export const customerInvoiceRepoKey = "customerInvoiceRepoKey"
|
@ -1,12 +1,12 @@
|
|||||||
import { ApiEither } from "@/feature/common/data/api-task";
|
"use server"
|
||||||
import serverDi from "@/feature/common/server-di";
|
import serverDi from "@/feature/common/server-di";
|
||||||
import CustomerInvoice from "@/feature/core/customer-invoice/domain/entity/customer-invoice";
|
import CustomerInvoice from "@/feature/core/customer-invoice/domain/entity/customer-invoice";
|
||||||
import CustomerInvoiceRepo, { customerInvoiceRepoKey } from "@/feature/core/customer-invoice/domain/i-repo/customer-invoice-repo";
|
import CustomerInvoiceRepo, { customerInvoiceRepoKey } from "@/feature/core/customer-invoice/domain/i-repo/customer-invoice-repo";
|
||||||
import { customerInvoiceModuleKey } from "@/feature/core/customer-invoice/invoice-module-key";
|
import { customerInvoiceModuleKey } from "@/feature/core/customer-invoice/invoice-module-key";
|
||||||
import { connection } from "next/server";
|
import { connection } from "next/server";
|
||||||
|
|
||||||
export default async function fetchCustomerInvoicesUsecase(): Promise<ApiEither<CustomerInvoice[]>> {
|
export default async function fetchCustomerInvoicesUsecase(): Promise<CustomerInvoice[]> {
|
||||||
connection()
|
connection()
|
||||||
const repo = serverDi(customerInvoiceModuleKey).resolve<CustomerInvoiceRepo>(customerInvoiceRepoKey)
|
const repo = serverDi(customerInvoiceModuleKey).resolve<CustomerInvoiceRepo>(customerInvoiceRepoKey)
|
||||||
return repo.fetchList()()
|
return repo.fetchList()
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { sql } from "@/bootstrap/boundaries/db/db";
|
import { sql } from "@/bootstrap/db/db";
|
||||||
import { formatCurrency } from "@/feature/common/feature-helpers";
|
import { formatCurrency } from "@/feature/common/feature-helpers";
|
||||||
import Customer from "@/feature/core/customer/domain/entity/customer";
|
import Customer from "@/feature/core/customer/domain/entity/customer";
|
||||||
import CustomerRepo from "@/feature/core/customer/domain/i-repo/customer-repo";
|
import CustomerRepo from "@/feature/core/customer/domain/i-repo/customer-repo";
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import ApiTask from "@/feature/common/data/api-task"
|
|
||||||
import Customer from "@/feature/core/customer/domain/entity/customer"
|
import Customer from "@/feature/core/customer/domain/entity/customer"
|
||||||
|
|
||||||
export default interface CustomerRepo {
|
export default interface CustomerRepo {
|
||||||
fetchList(query: string): ApiTask<Customer[]>
|
fetchList(query: string): Promise<Customer[]>
|
||||||
fetchCustomersAmount(): Promise<number>
|
fetchCustomersAmount(): Promise<number>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { sql } from "@/bootstrap/boundaries/db/db";
|
import { sql } from "@/bootstrap/db/db";
|
||||||
import { formatCurrency } from "@/feature/common/feature-helpers";
|
import { formatCurrency } from "@/feature/common/feature-helpers";
|
||||||
import InvoiceRepo from "@/feature/core/invoice/domain/i-repo/invoice-repo";
|
import InvoiceRepo from "@/feature/core/invoice/domain/i-repo/invoice-repo";
|
||||||
import { InvoiceParam } from "@/feature/core/invoice/domain/param/invoice-param";
|
import { InvoiceParam } from "@/feature/core/invoice/domain/param/invoice-param";
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import ApiTask from "@/feature/common/data/api-task"
|
|
||||||
import { InvoiceParam } from "@/feature/core/invoice/domain/param/invoice-param"
|
import { InvoiceParam } from "@/feature/core/invoice/domain/param/invoice-param"
|
||||||
import InvoiceStatusSummary from "@/feature/core/invoice/domain/value-object/invoice-status"
|
import InvoiceStatusSummary from "@/feature/core/invoice/domain/value-object/invoice-status"
|
||||||
|
|
||||||
export default interface InvoiceRepo {
|
export default interface InvoiceRepo {
|
||||||
fetchAllInvoicesAmount(): Promise<number>
|
fetchAllInvoicesAmount(): Promise<number>
|
||||||
fetchInvoicesStatusSummary(): Promise<InvoiceStatusSummary>
|
fetchInvoicesStatusSummary(): Promise<InvoiceStatusSummary>
|
||||||
createInvoice(params: InvoiceParam): ApiTask<string>
|
createInvoice(params: InvoiceParam): Promise<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const invoiceRepoKey = "invoiceRepoKey"
|
export const invoiceRepoKey = "invoiceRepoKey"
|
@ -1,24 +1,19 @@
|
|||||||
"use server"
|
"use server"
|
||||||
import { ApiEither } from "@/feature/common/data/api-task";
|
|
||||||
import ParamsFailure from "@/feature/common/failures/params-failure";
|
|
||||||
import serverDi from "@/feature/common/server-di";
|
import serverDi from "@/feature/common/server-di";
|
||||||
import InvoiceRepo, { invoiceRepoKey } from "@/feature/core/invoice/domain/i-repo/invoice-repo";
|
import InvoiceRepo, { invoiceRepoKey } from "@/feature/core/invoice/domain/i-repo/invoice-repo";
|
||||||
import { InvoiceParam, invoiceSchema } from "@/feature/core/invoice/domain/param/invoice-param";
|
import { InvoiceParam, invoiceSchema } from "@/feature/core/invoice/domain/param/invoice-param";
|
||||||
import { invoiceModuleKey } from "@/feature/core/invoice/invoice-module-key";
|
import { invoiceModuleKey } from "@/feature/core/invoice/invoice-module-key";
|
||||||
import { pipe } from "fp-ts/lib/function";
|
|
||||||
import { chain, fromNullable, left, map, right } from "fp-ts/lib/TaskEither";
|
|
||||||
|
|
||||||
export default async function createInvoiceUsecase(params: InvoiceParam): Promise<ApiEither<string>> {
|
export default async function createInvoiceUsecase(params: InvoiceParam): Promise<string | {errorMessage: string}> {
|
||||||
|
const isParamsValid = invoiceSchema.safeParse(params)
|
||||||
|
|
||||||
|
if (!isParamsValid) {
|
||||||
|
return {
|
||||||
|
errorMessage: "Please pass correct params"
|
||||||
|
}
|
||||||
|
}
|
||||||
const repo = serverDi(invoiceModuleKey).resolve<InvoiceRepo>(invoiceRepoKey)
|
const repo = serverDi(invoiceModuleKey).resolve<InvoiceRepo>(invoiceRepoKey)
|
||||||
|
|
||||||
return pipe(
|
return repo.createInvoice(params)
|
||||||
fromNullable(new ParamsFailure())(params),
|
|
||||||
map((params) => invoiceSchema.safeParse(params)),
|
|
||||||
chain((params) => {
|
|
||||||
const isParamsValid = invoiceSchema.safeParse(params)
|
|
||||||
if (!isParamsValid.success) left(new ParamsFailure())
|
|
||||||
return right(params.data as InvoiceParam)
|
|
||||||
}),
|
|
||||||
chain((params) => repo.createInvoice(params))
|
|
||||||
)()
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { sql } from "@/bootstrap/boundaries/db/db";
|
import { sql } from "@/bootstrap/db/db";
|
||||||
import Revenue from "@/feature/core/revenue/domain/entity/revenue";
|
import Revenue from "@/feature/core/revenue/domain/entity/revenue";
|
||||||
import RevenueRepo from "@/feature/core/revenue/domain/i-repo/revenue-repo";
|
import RevenueRepo from "@/feature/core/revenue/domain/i-repo/revenue-repo";
|
||||||
import { connection } from "next/server";
|
import { connection } from "next/server";
|
||||||
|
@ -25,6 +25,6 @@
|
|||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/bootstrap/boundaries/db/seed.js", "src/bootstrap/boundaries/db/placeholder-data.js"],
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/bootstrap/db/seed.js", "src/bootstrap/db/placeholder-data.js"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
}
|
}
|
||||||
|
@ -2125,11 +2125,6 @@ form-data@^4.0.0:
|
|||||||
combined-stream "^1.0.8"
|
combined-stream "^1.0.8"
|
||||||
mime-types "^2.1.12"
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
fp-ts@^2.16.9:
|
|
||||||
version "2.16.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.16.9.tgz#99628fc5e0bb3b432c4a16d8f4455247380bae8a"
|
|
||||||
integrity sha512-+I2+FnVB+tVaxcYyQkHUq7ZdKScaBlX53A41mxQtpIccsfyv8PzdzP7fzp2AY832T4aoK6UZ5WRX/ebGd8uZuQ==
|
|
||||||
|
|
||||||
fs-minipass@^2.0.0:
|
fs-minipass@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
|
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user