- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 103
WIP: Compute balances in database #247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Draft
      
      
            FriesischScott
  wants to merge
  36
  commits into
  oss-apps:main
  
    
      
        
          
  
    
      Choose a base branch
      
     
    
      
        
      
      
        
          
          
        
        
          
            
              
              
              
  
           
        
        
          
            
              
              
           
        
       
     
  
        
          
            
          
            
          
        
       
    
      
from
FriesischScott:sql-balances
  
      
      
   
  
    
  
  
  
 
  
      
    base: main
Could not load branches
            
              
  
    Branch not found: {{ refName }}
  
            
                
      Loading
              
            Could not load tags
            
            
              Nothing to show
            
              
  
            
                
      Loading
              
            Are you sure you want to change the base?
            Some commits from the old base branch may be removed from the timeline,
            and old review comments may become outdated.
          
          
  
     Draft
                    Changes from all commits
      Commits
    
    
            Show all changes
          
          
            36 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      a9ed276
              
                Add typed query to get groups with balances
              
              
                FriesischScott beb89da
              
                Return groups without expenses
              
              
                FriesischScott df6a7ad
              
                Order groups descending by newest
              
              
                FriesischScott ab4c7ee
              
                Compute blances for group overview in db
              
              
                FriesischScott 56af112
              
                Compute balance list in db
              
              
                FriesischScott de25193
              
                Merge branch 'main' into sql-balances
              
              
                FriesischScott 24d1b99
              
                Include group id in all balances
              
              
                FriesischScott 70e58c6
              
                Fix linting
              
              
                FriesischScott a40ca8c
              
                Move prisma client to src/prisma/client
              
              
                FriesischScott cee753c
              
                Fix prettier warning
              
              
                FriesischScott 23fece2
              
                Use path alias to move prisma client
              
              
                FriesischScott b3002be
              
                gitignore prisma client files
              
              
                FriesischScott 20fb843
              
                Fix sql imports
              
              
                FriesischScott 44a3bdd
              
                Set prisma client output
              
              
                FriesischScott a36344d
              
                Run lint --fix
              
              
                FriesischScott cd32056
              
                Fix type issues
              
              
                FriesischScott c619e26
              
                Fix prettier warnings
              
              
                FriesischScott 646c2e0
              
                Add postgresql service container
              
              
                FriesischScott 7de67eb
              
                Run migrations before generating sql types
              
              
                FriesischScott bb996e9
              
                Merge branch 'main' into sql-balances
              
              
                FriesischScott fa22c43
              
                Remove sql types
              
              
                FriesischScott 1ff2229
              
                Fix workflow file
              
              
                FriesischScott 6ff9a98
              
                Fix bigint conversions
              
              
                FriesischScott 0e5b29c
              
                Fix lint
              
              
                FriesischScott bec3f4d
              
                Seed db for stress testing
              
              
                FriesischScott af4c06d
              
                Fix prettier warnings
              
              
                FriesischScott 2684a71
              
                Exclude seed.ts
              
              
                FriesischScott 4b02518
              
                Don't set prisma output folder
              
              
                FriesischScott c26dc4a
              
                Exclude deleted expenses from group balance
              
              
                FriesischScott 06eea78
              
                Update seed
              
              
                FriesischScott bca6c9d
              
                Add userid index to ExpenseParticipant
              
              
                FriesischScott 4dc3d38
              
                Merge branch 'main' into sql-balances
              
              
                FriesischScott 1f330a5
              
                Fix prettier warnings
              
              
                FriesischScott 3270d55
              
                Merge remote-tracking branch 'upstream/main' into sql-balances
              
              
                FriesischScott 510df2e
              
                Format SQL queries
              
              
                FriesischScott 391f161
              
                Switch service container to ossapps/postgres
              
              
                FriesischScott File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -11,7 +11,7 @@ | |
| # database | ||
| /prisma/db.sqlite | ||
| /prisma/db.sqlite-journal | ||
|  | ||
| /src/prisma/client | ||
| # next.js | ||
| /.next/ | ||
| /out/ | ||
|  | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| import { PrismaClient, SplitType, User, Group } from '@prisma/client'; | ||
| import { randomInt } from 'crypto'; | ||
|  | ||
| const prisma = new PrismaClient(); | ||
|  | ||
| async function createUsers() { | ||
| const data = Array.from({ length: 1000 }, (value, index) => index).map((i) => { | ||
| return { | ||
| name: `user${i}`, | ||
| email: `user${i}@example.com`, | ||
| currency: 'USD', | ||
| }; | ||
| }); | ||
| const users = await prisma.user.createMany({ | ||
| data: data, | ||
| }); | ||
| return prisma.user.findMany({ | ||
| orderBy: { | ||
| id: 'asc', | ||
| }, | ||
| }); | ||
| } | ||
|  | ||
| async function createGroups(users: User[]) { | ||
| if (users.length) { | ||
| for (let i = 0; i < 100; i++) { | ||
| const s = i * 10; | ||
| const e = (i + 1) * 10 - 1; | ||
|  | ||
| // group of 10 | ||
| const group = await prisma.group.create({ | ||
| data: { | ||
| name: `Group_10_${i}`, | ||
| publicId: `Group-10-${i}`, | ||
| defaultCurrency: 'EUR', | ||
| userId: users[s].id, | ||
| }, | ||
| }); | ||
|  | ||
| await prisma.groupUser.createMany({ | ||
| data: users.slice(s, e).map((u) => { | ||
| return { | ||
| groupId: group.id, | ||
| userId: u.id, | ||
| }; | ||
| }), | ||
| }); | ||
| } | ||
| } | ||
|  | ||
| const group = await prisma.group.create({ | ||
| data: { | ||
| name: `Group_30`, | ||
| publicId: `Group-30`, | ||
| defaultCurrency: 'EUR', | ||
| userId: users[0].id, | ||
| }, | ||
| }); | ||
|  | ||
| await prisma.groupUser.createMany({ | ||
| data: users.slice(0, 29).map((u) => { | ||
| return { | ||
| groupId: group.id, | ||
| userId: u.id, | ||
| }; | ||
| }), | ||
| }); | ||
|  | ||
| return prisma.group.findMany({ | ||
| include: { | ||
| groupUsers: true, | ||
| }, | ||
| }); | ||
| } | ||
|  | ||
| async function createExpenses(groups: Group[]) { | ||
| const currencies = ['EUR', 'USD']; | ||
| for (const gid in groups) { | ||
| const group = groups[gid]; | ||
| for (let i = 0; i < 10000; i++) { | ||
| const c = randomInt(0, 2); | ||
| const amount = BigInt(randomInt(1000, 10000)); | ||
|  | ||
| const expense = await prisma.expense.create({ | ||
| data: { | ||
| name: `Expense Group ${group.id} ${i}`, | ||
| paidBy: group.groupUsers[0].userId, | ||
| addedBy: group.groupUsers[0].userId, | ||
| category: 'general', | ||
| currency: currencies[c], | ||
| amount: amount, | ||
| groupId: group.id, | ||
| splitType: SplitType.EQUAL, | ||
| }, | ||
| }); | ||
|  | ||
| await prisma.expenseParticipant.createMany({ | ||
| data: [ | ||
| { expenseId: expense.id, userId: group.groupUsers[0].userId, amount: amount }, | ||
| ...group.groupUsers.slice(1).map((u) => { | ||
| return { | ||
| expenseId: expense.id, | ||
| userId: u.userId, | ||
| amount: -amount / BigInt(group.groupUsers.length), | ||
| }; | ||
| }), | ||
| ], | ||
| }); | ||
| } | ||
| } | ||
| } | ||
|  | ||
| async function main() { | ||
| const users = await createUsers(); | ||
| const groups = await createGroups(users); | ||
| await createExpenses(groups); | ||
| console.log('Seeded db with users, groups and expenses'); | ||
| } | ||
|  | ||
| main() | ||
| .catch((e) => { | ||
| console.error(e); | ||
| process.exit(1); | ||
| }) | ||
| .finally(() => { | ||
| prisma.$disconnect().catch(console.log); | ||
| }); | 
        
          
          
            2 changes: 2 additions & 0 deletions
          
          2 
        
  prisma/migrations/20250618113146_add_expense_participant_userid_index/migration.sql
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| -- CreateIndex | ||
| CREATE INDEX "ExpenseParticipant_userId_idx" ON "ExpenseParticipant" USING HASH ("userId"); | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| -- @param {Int} $1:id of the group | ||
| SELECT | ||
| "groupId", | ||
| "userId" AS "borrowedBy", | ||
| "paidBy", | ||
| "currency", | ||
| CAST(Coalesce(-1 * sum("ExpenseParticipant".amount), 0) AS BIGINT) AS amount | ||
| FROM | ||
| "Expense" | ||
| JOIN "ExpenseParticipant" ON "ExpenseParticipant"."expenseId" = "Expense".id | ||
| WHERE | ||
| "groupId" = $1 | ||
| AND "userId" != "paidBy" | ||
| AND "Expense"."deletedAt" IS NULL | ||
| GROUP BY | ||
| "userId", | ||
| "paidBy", | ||
| "currency", | ||
| "groupId" | ||
| ORDER BY | ||
| "currency" | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| -- @param {Int} $1:id of the user | ||
| SELECT | ||
| "Group"."id", | ||
| "Group".name, | ||
| CAST(Coalesce(sum("ExpenseParticipant".amount), 0) AS BIGINT) AS balance, | ||
| Coalesce("Expense".currency, "Group"."defaultCurrency") AS currency, | ||
| "Group"."archivedAt" | ||
| FROM | ||
| "GroupUser" | ||
| JOIN "Group" ON "GroupUser"."groupId" = "Group".id | ||
| LEFT JOIN "Expense" ON "Expense"."groupId" = "Group".id | ||
| LEFT JOIN "ExpenseParticipant" ON "Expense".id = "ExpenseParticipant"."expenseId" | ||
| WHERE | ||
| "GroupUser"."userId" = $1 | ||
| AND "deletedAt" IS NULL | ||
| AND ("ExpenseParticipant"."userId" = $1 | ||
| OR "Expense".id IS NULL) | ||
| GROUP BY | ||
| "Group".id, | ||
| "Group".name, | ||
| "Expense".currency | ||
| ORDER BY | ||
| "Group"."createdAt" DESC, | ||
| balance DESC | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
      
      Oops, something went wrong.
        
    
  
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.