Q: Why do mountain climbers rope themselves together?

A:	To prevent the sensible ones from going home.
This commit is contained in:
Sebastien Castiel
2024-10-25 15:02:31 -04:00
parent 9bdc8a715c
commit c1c75fa260
29 changed files with 73 additions and 96 deletions

View File

@@ -9,7 +9,6 @@
"check-formatting": "prettier -c src", "check-formatting": "prettier -c src",
"prettier": "prettier -w src", "prettier": "prettier -w src",
"postinstall": "prisma generate", "postinstall": "prisma generate",
"build": "tsc"
}, },
"dependencies": { "dependencies": {
"@formatjs/intl-localematcher": "^0.5.4", "@formatjs/intl-localematcher": "^0.5.4",

View File

@@ -2,4 +2,4 @@ export {
appRouter, appRouter,
type AppRouter, type AppRouter,
type AppRouterOutput, type AppRouterOutput,
} from '@/trpc/routers/_app' } from './trpc/routers/_app'

View File

@@ -1,7 +1,7 @@
import { prisma } from '@/lib/prisma'
import { ExpenseFormValues, GroupFormValues } from '@/lib/schemas'
import { ActivityType, Expense } from '@prisma/client' import { ActivityType, Expense } from '@prisma/client'
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import { prisma } from './prisma'
import { ExpenseFormValues, GroupFormValues } from './schemas'
export function randomId() { export function randomId() {
return nanoid() return nanoid()

View File

@@ -1,6 +1,6 @@
import { getGroupExpenses } from '@/lib/api'
import { Participant } from '@prisma/client' import { Participant } from '@prisma/client'
import { match } from 'ts-pattern' import { match } from 'ts-pattern'
import { getGroupExpenses } from './api'
export type Balances = Record< export type Balances = Record<
Participant['id'], Participant['id'],
@@ -87,7 +87,10 @@ export function getPublicBalances(reimbursements: Reimbursement[]): Balances {
* This ensures that a participant executing a suggested reimbursement * This ensures that a participant executing a suggested reimbursement
* does not result in completely new repayment suggestions. * does not result in completely new repayment suggestions.
*/ */
function compareBalancesForReimbursements(b1: any, b2: any): number { function compareBalancesForReimbursements(
b1: { total: number; participantId: string },
b2: { total: number; participantId: string },
): number {
// positive balances come before negative balances // positive balances come before negative balances
if (b1.total > 0 && 0 > b2.total) { if (b1.total > 0 && 0 > b2.total) {
return -1 return -1
@@ -95,7 +98,7 @@ function compareBalancesForReimbursements(b1: any, b2: any): number {
return 1 return 1
} }
// if signs match, sort based on userid // if signs match, sort based on userid
return b1.participantId < b2.participantId ? -1 : 1 return b1.participantId.localeCompare(b2.participantId)
} }
export function getSuggestedReimbursements( export function getSuggestedReimbursements(

View File

@@ -2,7 +2,7 @@ import { PrismaClient } from '@prisma/client'
declare const global: Global & { prisma?: PrismaClient } declare const global: Global & { prisma?: PrismaClient }
export let p: PrismaClient = undefined as any as PrismaClient export let p: PrismaClient = undefined as unknown as PrismaClient
if (typeof window === 'undefined') { if (typeof window === 'undefined') {
// await delay(1000) // await delay(1000)

View File

@@ -1,4 +1,4 @@
import { getGroupExpenses } from '@/lib/api' import { getGroupExpenses } from './api'
export function getTotalGroupSpending( export function getTotalGroupSpending(
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>, expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>,
@@ -55,14 +55,15 @@ export function getTotalActiveUserShare(
// Calculate the user's share based on their percentage of the total expense // Calculate the user's share based on their percentage of the total expense
total += (expense.amount * userPaidFor.shares) / 10000 // Assuming shares are out of 10000 for percentage total += (expense.amount * userPaidFor.shares) / 10000 // Assuming shares are out of 10000 for percentage
break break
case 'BY_SHARES': case 'BY_SHARES': // Calculate the user's share based on their shares relative to the total shares
// Calculate the user's share based on their shares relative to the total shares {
const totalShares = paidFors.reduce( const totalShares = paidFors.reduce(
(sum, paidFor) => sum + paidFor.shares, (sum, paidFor) => sum + paidFor.shares,
0, 0,
) )
total += (expense.amount * userPaidFor.shares) / totalShares total += (expense.amount * userPaidFor.shares) / totalShares
break break
}
} }
}) })

View File

@@ -1,21 +0,0 @@
import { defaultShouldDehydrateQuery, QueryClient } from '@tanstack/react-query'
import superjson from 'superjson'
export function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 30 * 1000,
},
dehydrate: {
serializeData: superjson.serialize,
shouldDehydrateQuery: (query) =>
defaultShouldDehydrateQuery(query) ||
query.state.status === 'pending',
},
hydrate: {
deserializeData: superjson.deserialize,
},
},
})
}

View File

@@ -1,7 +1,6 @@
import { categoriesRouter } from '@/trpc/routers/categories'
import { groupsRouter } from '@/trpc/routers/groups'
import { inferRouterOutputs } from '@trpc/server' import { inferRouterOutputs } from '@trpc/server'
import { createTRPCRouter } from '../init' import { createTRPCRouter } from '../init'
import { categoriesRouter } from './categories'
export const appRouter = createTRPCRouter({ export const appRouter = createTRPCRouter({
groups: groupsRouter, groups: groupsRouter,

View File

@@ -1,5 +1,5 @@
import { createTRPCRouter } from '@/trpc/init' import { createTRPCRouter } from '../../init'
import { listCategoriesProcedure } from '@/trpc/routers/categories/list.procedure' import { listCategoriesProcedure } from './list.procedure'
export const categoriesRouter = createTRPCRouter({ export const categoriesRouter = createTRPCRouter({
list: listCategoriesProcedure, list: listCategoriesProcedure,

View File

@@ -1,5 +1,5 @@
import { getCategories } from '@/lib/api' import { getCategories } from '../../../lib/api'
import { baseProcedure } from '@/trpc/init' import { baseProcedure } from '../../init'
export const listCategoriesProcedure = baseProcedure.query(async () => { export const listCategoriesProcedure = baseProcedure.query(async () => {
return { categories: await getCategories() } return { categories: await getCategories() }

View File

@@ -1,5 +1,5 @@
import { createTRPCRouter } from '@/trpc/init' import { createTRPCRouter } from '../../../init'
import { listGroupActivitiesProcedure } from '@/trpc/routers/groups/activities/list.procedure' import { listGroupActivitiesProcedure } from './list.procedure'
export const activitiesRouter = createTRPCRouter({ export const activitiesRouter = createTRPCRouter({
list: listGroupActivitiesProcedure, list: listGroupActivitiesProcedure,

View File

@@ -1,6 +1,6 @@
import { getActivities } from '@/lib/api'
import { baseProcedure } from '@/trpc/init'
import { z } from 'zod' import { z } from 'zod'
import { getActivities } from '../../../../lib/api'
import { baseProcedure } from '../../../init'
export const listGroupActivitiesProcedure = baseProcedure export const listGroupActivitiesProcedure = baseProcedure
.input( .input(

View File

@@ -1,5 +1,5 @@
import { createTRPCRouter } from '@/trpc/init' import { createTRPCRouter } from '../../../init'
import { listGroupBalancesProcedure } from '@/trpc/routers/groups/balances/list.procedure' import { listGroupBalancesProcedure } from './list.procedure'
export const groupBalancesRouter = createTRPCRouter({ export const groupBalancesRouter = createTRPCRouter({
list: listGroupBalancesProcedure, list: listGroupBalancesProcedure,

View File

@@ -1,11 +1,11 @@
import { getGroupExpenses } from '@/lib/api' import { z } from 'zod'
import { getGroupExpenses } from '../../../../lib/api'
import { import {
getBalances, getBalances,
getPublicBalances, getPublicBalances,
getSuggestedReimbursements, getSuggestedReimbursements,
} from '@/lib/balances' } from '../../../../lib/balances'
import { baseProcedure } from '@/trpc/init' import { baseProcedure } from '../../../init'
import { z } from 'zod'
export const listGroupBalancesProcedure = baseProcedure export const listGroupBalancesProcedure = baseProcedure
.input(z.object({ groupId: z.string().min(1) })) .input(z.object({ groupId: z.string().min(1) }))

View File

@@ -1,7 +1,7 @@
import { createGroup } from '@/lib/api'
import { groupFormSchema } from '@/lib/schemas'
import { baseProcedure } from '@/trpc/init'
import { z } from 'zod' import { z } from 'zod'
import { createGroup } from '../../../lib/api'
import { groupFormSchema } from '../../../lib/schemas'
import { baseProcedure } from '../../init'
export const createGroupProcedure = baseProcedure export const createGroupProcedure = baseProcedure
.input( .input(

View File

@@ -1,7 +1,7 @@
import { createExpense } from '@/lib/api'
import { expenseFormSchema } from '@/lib/schemas'
import { baseProcedure } from '@/trpc/init'
import { z } from 'zod' import { z } from 'zod'
import { createExpense } from '../../../../lib/api'
import { expenseFormSchema } from '../../../../lib/schemas'
import { baseProcedure } from '../../../init'
export const createGroupExpenseProcedure = baseProcedure export const createGroupExpenseProcedure = baseProcedure
.input( .input(

View File

@@ -1,6 +1,6 @@
import { deleteExpense } from '@/lib/api'
import { baseProcedure } from '@/trpc/init'
import { z } from 'zod' import { z } from 'zod'
import { deleteExpense } from '../../../../lib/api'
import { baseProcedure } from '../../../init'
export const deleteGroupExpenseProcedure = baseProcedure export const deleteGroupExpenseProcedure = baseProcedure
.input( .input(

View File

@@ -1,7 +1,7 @@
import { getExpense } from '@/lib/api'
import { baseProcedure } from '@/trpc/init'
import { TRPCError } from '@trpc/server' import { TRPCError } from '@trpc/server'
import { z } from 'zod' import { z } from 'zod'
import { getExpense } from '../../../../lib/api'
import { baseProcedure } from '../../../init'
export const getGroupExpenseProcedure = baseProcedure export const getGroupExpenseProcedure = baseProcedure
.input(z.object({ groupId: z.string().min(1), expenseId: z.string().min(1) })) .input(z.object({ groupId: z.string().min(1), expenseId: z.string().min(1) }))

View File

@@ -1,9 +1,9 @@
import { createTRPCRouter } from '@/trpc/init' import { createTRPCRouter } from '../../../init'
import { createGroupExpenseProcedure } from '@/trpc/routers/groups/expenses/create.procedure' import { createGroupExpenseProcedure } from './create.procedure'
import { deleteGroupExpenseProcedure } from '@/trpc/routers/groups/expenses/delete.procedure' import { deleteGroupExpenseProcedure } from './delete.procedure'
import { getGroupExpenseProcedure } from '@/trpc/routers/groups/expenses/get.procedure' import { getGroupExpenseProcedure } from './get.procedure'
import { listGroupExpensesProcedure } from '@/trpc/routers/groups/expenses/list.procedure' import { listGroupExpensesProcedure } from './list.procedure'
import { updateGroupExpenseProcedure } from '@/trpc/routers/groups/expenses/update.procedure' import { updateGroupExpenseProcedure } from './update.procedure'
export const groupExpensesRouter = createTRPCRouter({ export const groupExpensesRouter = createTRPCRouter({
list: listGroupExpensesProcedure, list: listGroupExpensesProcedure,

View File

@@ -1,6 +1,6 @@
import { getGroupExpenses } from '@/lib/api'
import { baseProcedure } from '@/trpc/init'
import { z } from 'zod' import { z } from 'zod'
import { getGroupExpenses } from '../../../../lib/api'
import { baseProcedure } from '../../../init'
export const listGroupExpensesProcedure = baseProcedure export const listGroupExpensesProcedure = baseProcedure
.input( .input(

View File

@@ -1,7 +1,7 @@
import { updateExpense } from '@/lib/api'
import { expenseFormSchema } from '@/lib/schemas'
import { baseProcedure } from '@/trpc/init'
import { z } from 'zod' import { z } from 'zod'
import { updateExpense } from '../../../../lib/api'
import { expenseFormSchema } from '../../../../lib/schemas'
import { baseProcedure } from '../../../init'
export const updateGroupExpenseProcedure = baseProcedure export const updateGroupExpenseProcedure = baseProcedure
.input( .input(

View File

@@ -1,6 +1,6 @@
import { getGroup } from '@/lib/api'
import { baseProcedure } from '@/trpc/init'
import { z } from 'zod' import { z } from 'zod'
import { getGroup } from '../../../lib/api'
import { baseProcedure } from '../../init'
export const getGroupProcedure = baseProcedure export const getGroupProcedure = baseProcedure
.input(z.object({ groupId: z.string().min(1) })) .input(z.object({ groupId: z.string().min(1) }))

View File

@@ -1,7 +1,7 @@
import { getGroup, getGroupExpensesParticipants } from '@/lib/api'
import { baseProcedure } from '@/trpc/init'
import { TRPCError } from '@trpc/server' import { TRPCError } from '@trpc/server'
import { z } from 'zod' import { z } from 'zod'
import { getGroup, getGroupExpensesParticipants } from '../../../lib/api'
import { baseProcedure } from '../../init'
export const getGroupDetailsProcedure = baseProcedure export const getGroupDetailsProcedure = baseProcedure
.input(z.object({ groupId: z.string().min(1) })) .input(z.object({ groupId: z.string().min(1) }))

View File

@@ -1,13 +1,13 @@
import { createTRPCRouter } from '@/trpc/init' import { createTRPCRouter } from '../../init'
import { activitiesRouter } from '@/trpc/routers/groups/activities' import { activitiesRouter } from './activities'
import { groupBalancesRouter } from '@/trpc/routers/groups/balances' import { groupBalancesRouter } from './balances'
import { createGroupProcedure } from '@/trpc/routers/groups/create.procedure' import { createGroupProcedure } from './create.procedure'
import { groupExpensesRouter } from '@/trpc/routers/groups/expenses' import { groupExpensesRouter } from './expenses'
import { getGroupProcedure } from '@/trpc/routers/groups/get.procedure' import { getGroupProcedure } from './get.procedure'
import { groupStatsRouter } from '@/trpc/routers/groups/stats'
import { updateGroupProcedure } from '@/trpc/routers/groups/update.procedure'
import { getGroupDetailsProcedure } from './getDetails.procedure' import { getGroupDetailsProcedure } from './getDetails.procedure'
import { listGroupsProcedure } from './list.procedure' import { listGroupsProcedure } from './list.procedure'
import { groupStatsRouter } from './stats'
import { updateGroupProcedure } from './update.procedure'
export const groupsRouter = createTRPCRouter({ export const groupsRouter = createTRPCRouter({
expenses: groupExpensesRouter, expenses: groupExpensesRouter,

View File

@@ -1,6 +1,6 @@
import { getGroups } from '@/lib/api'
import { baseProcedure } from '@/trpc/init'
import { z } from 'zod' import { z } from 'zod'
import { getGroups } from '../../../lib/api'
import { baseProcedure } from '../../init'
export const listGroupsProcedure = baseProcedure export const listGroupsProcedure = baseProcedure
.input( .input(

View File

@@ -1,11 +1,11 @@
import { getGroupExpenses } from '@/lib/api' import { z } from 'zod'
import { getGroupExpenses } from '../../../../lib/api'
import { import {
getTotalActiveUserPaidFor, getTotalActiveUserPaidFor,
getTotalActiveUserShare, getTotalActiveUserShare,
getTotalGroupSpending, getTotalGroupSpending,
} from '@/lib/totals' } from '../../../../lib/totals'
import { baseProcedure } from '@/trpc/init' import { baseProcedure } from '../../../init'
import { z } from 'zod'
export const getGroupStatsProcedure = baseProcedure export const getGroupStatsProcedure = baseProcedure
.input( .input(

View File

@@ -1,5 +1,5 @@
import { createTRPCRouter } from '@/trpc/init' import { createTRPCRouter } from '../../../init'
import { getGroupStatsProcedure } from '@/trpc/routers/groups/stats/get.procedure' import { getGroupStatsProcedure } from './get.procedure'
export const groupStatsRouter = createTRPCRouter({ export const groupStatsRouter = createTRPCRouter({
get: getGroupStatsProcedure, get: getGroupStatsProcedure,

View File

@@ -1,7 +1,7 @@
import { updateGroup } from '@/lib/api'
import { groupFormSchema } from '@/lib/schemas'
import { baseProcedure } from '@/trpc/init'
import { z } from 'zod' import { z } from 'zod'
import { updateGroup } from '../../../lib/api'
import { groupFormSchema } from '../../../lib/schemas'
import { baseProcedure } from '../../init'
export const updateGroupProcedure = baseProcedure export const updateGroupProcedure = baseProcedure
.input( .input(

View File

@@ -12,10 +12,6 @@
"isolatedModules": true, "isolatedModules": true,
"jsx": "preserve", "jsx": "preserve",
"incremental": true, "incremental": true,
"paths": {
"@/*": ["./src/*"]
},
"outDir": "./dist",
"declaration": true "declaration": true
}, },
"include": ["./src/index.ts", "./reset.d.ts"], "include": ["./src/index.ts", "./reset.d.ts"],