diff --git a/apps/api/next.config.js b/apps/api/next.config.js index 68583ede..3f8b03f7 100644 --- a/apps/api/next.config.js +++ b/apps/api/next.config.js @@ -2,7 +2,7 @@ const nextConfig = { reactStrictMode: true, rewrites: () => [{ source: '/v1/:path*', destination: '/api/v1/:path*' }], - transpilePackages: ['@6pm/validation'], + transpilePackages: ['@6pm/validation', '@6pm/utilities'], } module.exports = nextConfig diff --git a/apps/api/package.json b/apps/api/package.json index 5866d62f..09ae1ff1 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -16,6 +16,7 @@ "check": "biome check" }, "dependencies": { + "@6pm/utilities": "workspace:^", "@6pm/validation": "workspace:^", "@clerk/backend": "^1.2.4", "@hono/clerk-auth": "^2.0.0", @@ -23,7 +24,6 @@ "@hono/zod-validator": "^0.2.2", "@prisma/client": "^5.16.0", "@vercel/blob": "^0.23.4", - "dayjs": "^1.11.11", "hono": "^4.4.8", "next": "^14.2.4", "openai": "^4.52.7", diff --git a/apps/api/v1/services/budget.service.ts b/apps/api/v1/services/budget.service.ts index db41e3d4..bb643b7d 100644 --- a/apps/api/v1/services/budget.service.ts +++ b/apps/api/v1/services/budget.service.ts @@ -1,11 +1,6 @@ +import { calculateBudgetPeriodStartEndDates } from '@6pm/utilities' import type { CreateBudget, UpdateBudget } from '@6pm/validation' -import { - type Budget, - BudgetPeriodType, - BudgetUserPermission, - type User, -} from '@prisma/client' -import { dayjsExtended } from '../../lib/dayjs' +import { type Budget, BudgetUserPermission, type User } from '@prisma/client' import prisma from '../../lib/prisma' import { inviteUserToBudget } from './budget-invitation.service' @@ -92,49 +87,12 @@ export async function isUserBudgetOwner({ export async function findBudget({ budgetId }: { budgetId: string }) { return prisma.budget.findUnique({ where: { id: budgetId }, + include: { + periodConfig: true, + }, }) } -/** - * Given an anchor date and period type, - * calculate the start and end dates of the budget period. - * Example: - * - anchorDate: 2022-01-15 - * - periodType: MONTHLY - * - startDate: 2022-01-01 - * - endDate: 2022-01-31 - */ -function calculateBudgetPeriodStartEndDates({ - anchorDate, - type, -}: { - anchorDate: Date - type: BudgetPeriodType -}) { - switch (type) { - case BudgetPeriodType.MONTHLY: - return { - startDate: dayjsExtended(anchorDate).startOf('month').toDate(), - endDate: dayjsExtended(anchorDate).endOf('month').toDate(), - } - case BudgetPeriodType.QUARTERLY: - return { - startDate: dayjsExtended(anchorDate).startOf('quarter').toDate(), - endDate: dayjsExtended(anchorDate).endOf('quarter').toDate(), - } - case BudgetPeriodType.YEARLY: - return { - startDate: dayjsExtended(anchorDate).startOf('year').toDate(), - endDate: dayjsExtended(anchorDate).endOf('year').toDate(), - } - default: - return { - startDate: null, - endDate: null, - } - } -} - export async function createBudget({ user, data, diff --git a/packages/utilities/README.md b/packages/utilities/README.md new file mode 100644 index 00000000..15eb7445 --- /dev/null +++ b/packages/utilities/README.md @@ -0,0 +1 @@ +# @6pm/utilities diff --git a/packages/utilities/biome.json b/packages/utilities/biome.json new file mode 100644 index 00000000..3e231518 --- /dev/null +++ b/packages/utilities/biome.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json", + "extends": ["../../biome.json"], + "files": { + "include": ["**/*.ts", "**/*.tsx"] + } +} diff --git a/packages/utilities/package.json b/packages/utilities/package.json new file mode 100644 index 00000000..a648c1e6 --- /dev/null +++ b/packages/utilities/package.json @@ -0,0 +1,17 @@ +{ + "name": "@6pm/utilities", + "version": "1.0.0", + "description": "Shared utilities between apps", + "main": "src/index.ts", + "scripts": { + "check": "biome check" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@6pm/validation": "workspace:^", + "@prisma/client": "^5.16.0", + "dayjs": "^1.11.11" + } +} diff --git a/apps/api/lib/dayjs.ts b/packages/utilities/src/date/dayjs.ts similarity index 100% rename from apps/api/lib/dayjs.ts rename to packages/utilities/src/date/dayjs.ts diff --git a/packages/utilities/src/date/period.ts b/packages/utilities/src/date/period.ts new file mode 100644 index 00000000..0fadb292 --- /dev/null +++ b/packages/utilities/src/date/period.ts @@ -0,0 +1,47 @@ +import { BudgetPeriodType } from '@prisma/client' +import { dayjsExtended } from './dayjs' + +/** + * Given an anchor date and period type, + * calculate the start and end dates of the budget period. + * Example: + * - anchorDate: 2022-01-15 + * - periodType: MONTHLY + * - startDate: 2022-01-01 + * - endDate: 2022-01-31 + */ +export function calculateBudgetPeriodStartEndDates({ + anchorDate, + type, +}: { + anchorDate: Date + type: BudgetPeriodType +}) { + switch (type) { + case BudgetPeriodType.WEEKLY: + return { + startDate: dayjsExtended(anchorDate).startOf('week').toDate(), + endDate: dayjsExtended(anchorDate).endOf('week').toDate(), + } + case BudgetPeriodType.MONTHLY: + return { + startDate: dayjsExtended(anchorDate).startOf('month').toDate(), + endDate: dayjsExtended(anchorDate).endOf('month').toDate(), + } + case BudgetPeriodType.QUARTERLY: + return { + startDate: dayjsExtended(anchorDate).startOf('quarter').toDate(), + endDate: dayjsExtended(anchorDate).endOf('quarter').toDate(), + } + case BudgetPeriodType.YEARLY: + return { + startDate: dayjsExtended(anchorDate).startOf('year').toDate(), + endDate: dayjsExtended(anchorDate).endOf('year').toDate(), + } + default: + return { + startDate: null, + endDate: null, + } + } +} diff --git a/packages/utilities/src/index.ts b/packages/utilities/src/index.ts new file mode 100644 index 00000000..785e764b --- /dev/null +++ b/packages/utilities/src/index.ts @@ -0,0 +1,2 @@ +export * from './date/dayjs' +export * from './date/period' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5839062d..0523371b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: apps/api: dependencies: + '@6pm/utilities': + specifier: workspace:^ + version: link:../../packages/utilities '@6pm/validation': specifier: workspace:^ version: link:../../packages/validation @@ -47,9 +50,6 @@ importers: '@vercel/blob': specifier: ^0.23.4 version: 0.23.4 - dayjs: - specifier: ^1.11.11 - version: 1.11.11 hono: specifier: ^4.4.8 version: 4.4.8 @@ -343,6 +343,18 @@ importers: packages/currency: {} + packages/utilities: + dependencies: + '@6pm/validation': + specifier: workspace:^ + version: link:../validation + '@prisma/client': + specifier: ^5.16.0 + version: 5.16.0(prisma@5.16.0) + dayjs: + specifier: ^1.11.11 + version: 1.11.11 + packages/validation: dependencies: '@prisma/client':