Compare commits
	
		
			3 Commits
		
	
	
		
			3b18a15494
			...
			29633e0e95
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 29633e0e95 | |||
| 0e05924585 | |||
| dfc2d1b2eb | 
| @ -50,8 +50,8 @@ func NewUserRepository(db *sql.DB) repo.UserRepository { | ||||
| func (ur *userRepository) Create( | ||||
| 	ctx context.Context, | ||||
| 	transaction interface{}, | ||||
| 	u *model.User, | ||||
| ) (*model.User, error) { | ||||
| 	u *model.UserPO, | ||||
| ) (*model.UserPO, error) { | ||||
| 	timeoutCtx, cancel := context.WithTimeout(ctx, insertTimeout) | ||||
| 	defer cancel() | ||||
|  | ||||
| @ -76,7 +76,7 @@ func (ur *userRepository) Create( | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &model.User{ | ||||
| 	return &model.UserPO{ | ||||
| 		ID:        int(userDB.ID), | ||||
| 		Email:     userDB.Email, | ||||
| 		FirstName: userDB.FirstName, | ||||
| @ -88,7 +88,7 @@ func (ur *userRepository) Create( | ||||
| } | ||||
|  | ||||
| // GetByEmail if not found, return nil for user but not error. | ||||
| func (ur *userRepository) GetByEmail(ctx context.Context, email string) (*model.User, error) { | ||||
| func (ur *userRepository) GetByEmail(ctx context.Context, email string) (*model.UserPO, error) { | ||||
| 	queries := sqlc.New(ur.db) | ||||
| 	userDB, err := queries.GetUserByEmail(ctx, email) | ||||
| 	if errors.Is(err, pgx.ErrNoRows) { | ||||
| @ -98,7 +98,7 @@ func (ur *userRepository) GetByEmail(ctx context.Context, email string) (*model. | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &model.User{ | ||||
| 	return &model.UserPO{ | ||||
| 		ID:        int(userDB.ID), | ||||
| 		Email:     userDB.Email, | ||||
| 		FirstName: userDB.FirstName, | ||||
|  | ||||
| @ -24,15 +24,40 @@ package model | ||||
|  | ||||
| import "time" | ||||
|  | ||||
| type Event struct { | ||||
| 	ID              int | ||||
| type EventCreateDTO struct { | ||||
| 	Name        string `json:"name"        binding:"requiered"` | ||||
| 	Description string `json:"description"` | ||||
| 	OwnerID     int    `json:"owner_id"    binding:"requiered,number"` | ||||
| } | ||||
|  | ||||
| type EventPO struct { | ||||
| 	ID int | ||||
|  | ||||
| 	Name            string | ||||
| 	Description     string | ||||
| 	Users           []*User | ||||
| 	Expenses        []*Expense | ||||
| 	TotalAmount     int | ||||
| 	DefaultCurrency string | ||||
| 	OwnerID         int | ||||
|  | ||||
| 	CreatedAt time.Time | ||||
| 	UpdatedAt time.Time | ||||
| } | ||||
|  | ||||
| type Event struct { | ||||
| 	ID int | ||||
|  | ||||
| 	Name        string | ||||
| 	Description string | ||||
|  | ||||
| 	// lazy get using participation join | ||||
| 	Users []*User | ||||
| 	// lazy get | ||||
| 	Expenses []*Expense | ||||
|  | ||||
| 	TotalAmount     Money | ||||
| 	DefaultCurrency Currency | ||||
| 	CreatedBy       User | ||||
| 	CreatedAt       time.Time | ||||
| 	UpdatedAt       time.Time | ||||
| 	Owner           User | ||||
|  | ||||
| 	CreatedAt time.Time | ||||
| 	UpdatedAt time.Time | ||||
| } | ||||
|  | ||||
| @ -24,19 +24,48 @@ package model | ||||
|  | ||||
| import "time" | ||||
|  | ||||
| type ExpenseDetail struct { | ||||
| type ExpenseDTO struct { | ||||
| 	Amount       Money         `json:"money"         binding:"required,number"` | ||||
| 	PayerIDs     []int         `json:"payer_ids"     binding:"required"` | ||||
| 	RecipientIDs []int         `json:"recipient_ids" binding:"required"` | ||||
| 	EventID      int           `json:"event_id"      binding:"required"` | ||||
| 	Detail       ExpenseDetail `json:"detail"` | ||||
| } | ||||
|  | ||||
| type ExpensePO struct { | ||||
| 	ID int | ||||
|  | ||||
| 	Amount   int | ||||
| 	Currency string | ||||
| 	EventID  int | ||||
|  | ||||
| 	// ExpenseDetail | ||||
| 	Name  string | ||||
| 	Place string | ||||
|  | ||||
| 	CreatedAt time.Time | ||||
| 	UpdatedAt time.Time | ||||
| } | ||||
|  | ||||
| type ExpenseDetail struct { | ||||
| 	Name  string `json:"name"` | ||||
| 	Place string `json:"place"` | ||||
| } | ||||
|  | ||||
| type Expense struct { | ||||
| 	ID           int | ||||
| 	Amount       Money | ||||
| 	Currency     Currency | ||||
| 	PayerIDs     []int | ||||
| 	ID int | ||||
|  | ||||
| 	Amount Money | ||||
|  | ||||
| 	// Lazy aggregate using Transaction join | ||||
| 	PayerIDs []int | ||||
|  | ||||
| 	// Lazy aggregate using Transaction join | ||||
| 	RecipientIDs []int | ||||
| 	EventID      int | ||||
| 	Detail       ExpenseDetail | ||||
| 	CreatedAt    time.Time | ||||
| 	UpdatedAt    time.Time | ||||
|  | ||||
| 	EventID int | ||||
| 	Detail  ExpenseDetail | ||||
|  | ||||
| 	CreatedAt time.Time | ||||
| 	UpdatedAt time.Time | ||||
| } | ||||
|  | ||||
| @ -36,8 +36,8 @@ const ( | ||||
| ) | ||||
|  | ||||
| type Money struct { | ||||
| 	ammount  int | ||||
| 	currency Currency | ||||
| 	Amount   int      `json:"amount"   binding:"required,number"` | ||||
| 	Currency Currency `json:"currency" binding:"required"` | ||||
| } | ||||
|  | ||||
| func MakeMoney(amount int, currency Currency) Money { | ||||
| @ -46,10 +46,10 @@ func MakeMoney(amount int, currency Currency) Money { | ||||
|  | ||||
| func Add(cur Currency, money ...Money) Money { | ||||
| 	var sum Money | ||||
| 	sum.currency = cur | ||||
| 	sum.Currency = cur | ||||
|  | ||||
| 	for _, m := range money { | ||||
| 		sum.ammount += m.ammount | ||||
| 		sum.Amount += m.Amount | ||||
| 	} | ||||
|  | ||||
| 	return sum | ||||
| @ -58,9 +58,9 @@ func Add(cur Currency, money ...Money) Money { | ||||
| func Diff(cur Currency, money1 Money, money2 Money) Money { | ||||
| 	var diff Money | ||||
|  | ||||
| 	diff.currency = cur | ||||
| 	diff.Currency = cur | ||||
|  | ||||
| 	diff.ammount = money1.ammount - money2.ammount | ||||
| 	diff.Amount = money1.Amount - money2.Amount | ||||
|  | ||||
| 	return diff | ||||
| } | ||||
|  | ||||
							
								
								
									
										39
									
								
								internal/howmuch/model/participation.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								internal/howmuch/model/participation.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| // MIT License | ||||
| // | ||||
| // Copyright (c) 2024 vinchent <vinchent@vinchent.xyz> | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in all | ||||
| // copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| // SOFTWARE. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import "time" | ||||
|  | ||||
| type ParticipationPO Participation | ||||
|  | ||||
| // Participation is the association between Users and Events | ||||
| type Participation struct { | ||||
| 	ID int | ||||
|  | ||||
| 	UserID          int | ||||
| 	EventID         int | ||||
| 	InvitedByUserID int | ||||
|  | ||||
| 	CreatedAt time.Time | ||||
| 	UpdatedAt time.Time | ||||
| } | ||||
							
								
								
									
										41
									
								
								internal/howmuch/model/transaction.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								internal/howmuch/model/transaction.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| // MIT License | ||||
| // | ||||
| // Copyright (c) 2024 vinchent <vinchent@vinchent.xyz> | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in all | ||||
| // copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| // SOFTWARE. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import "time" | ||||
|  | ||||
| type TransactionPO Transaction | ||||
|  | ||||
| // Transaction is the association between Expenses and Users | ||||
| type Transaction struct { | ||||
| 	ID int | ||||
|  | ||||
| 	ExpenseID Expense | ||||
| 	UserID    int | ||||
| 	Amount    int | ||||
| 	Currency  string | ||||
| 	IsIncome  bool | ||||
|  | ||||
| 	CreatedAt time.Time | ||||
| 	UpdatedAt time.Time | ||||
| } | ||||
| @ -36,13 +36,30 @@ type UserExistDTO struct { | ||||
| 	Password string `json:"password" binding:"required"` | ||||
| } | ||||
|  | ||||
| // User model | ||||
| type User struct { | ||||
| 	ID        int | ||||
| type UserPO struct { | ||||
| 	ID int | ||||
|  | ||||
| 	Email     string | ||||
| 	FirstName string | ||||
| 	LastName  string | ||||
| 	Password  string | ||||
|  | ||||
| 	CreatedAt time.Time | ||||
| 	UpdatedAt time.Time | ||||
| } | ||||
|  | ||||
| // User model | ||||
| type User struct { | ||||
| 	ID int | ||||
|  | ||||
| 	Email     string | ||||
| 	FirstName string | ||||
| 	LastName  string | ||||
| 	Password  string | ||||
|  | ||||
| 	// Lazy aggregate with the Participation join | ||||
| 	EventIDs []int | ||||
|  | ||||
| 	CreatedAt time.Time | ||||
| 	UpdatedAt time.Time | ||||
| } | ||||
|  | ||||
| @ -29,6 +29,6 @@ import ( | ||||
| ) | ||||
|  | ||||
| type UserRepository interface { | ||||
| 	Create(ctx context.Context, transaction interface{}, u *model.User) (*model.User, error) | ||||
| 	GetByEmail(ctx context.Context, email string) (*model.User, error) | ||||
| 	Create(ctx context.Context, transaction interface{}, u *model.UserPO) (*model.UserPO, error) | ||||
| 	GetByEmail(ctx context.Context, email string) (*model.UserPO, error) | ||||
| } | ||||
|  | ||||
| @ -37,8 +37,8 @@ type TestUserRepository struct{} | ||||
| func (tur *TestUserRepository) Create( | ||||
| 	ctx context.Context, | ||||
| 	transaction interface{}, | ||||
| 	u *model.User, | ||||
| ) (*model.User, error) { | ||||
| 	u *model.UserPO, | ||||
| ) (*model.UserPO, error) { | ||||
| 	user := *u | ||||
|  | ||||
| 	user.ID = 123 | ||||
| @ -50,11 +50,11 @@ func (tur *TestUserRepository) Create( | ||||
| 	return &user, nil | ||||
| } | ||||
|  | ||||
| func (ur *TestUserRepository) GetByEmail(ctx context.Context, email string) (*model.User, error) { | ||||
| func (ur *TestUserRepository) GetByEmail(ctx context.Context, email string) (*model.UserPO, error) { | ||||
| 	hashedPwd, _ := bcrypt.GenerateFromPassword([]byte("strongHashed"), 12) | ||||
| 	switch email { | ||||
| 	case "a@b.c": | ||||
| 		return &model.User{ | ||||
| 		return &model.UserPO{ | ||||
| 			ID:       123, | ||||
| 			Email:    "a@b.c", | ||||
| 			Password: string(hashedPwd), | ||||
|  | ||||
| @ -82,7 +82,7 @@ func (uuc *userUsecase) Create(ctx context.Context, u *model.UserCreateDTO) (*mo | ||||
| 	data, err := uuc.dbRepo.Transaction( | ||||
| 		ctx, | ||||
| 		func(txCtx context.Context, tx interface{}) (interface{}, error) { | ||||
| 			created, err := uuc.userRepo.Create(txCtx, tx, &model.User{ | ||||
| 			created, err := uuc.userRepo.Create(txCtx, tx, &model.UserPO{ | ||||
| 				Email:     u.Email, | ||||
| 				Password:  u.Password, | ||||
| 				FirstName: u.FirstName, | ||||
| @ -113,7 +113,20 @@ func (uuc *userUsecase) Create(ctx context.Context, u *model.UserCreateDTO) (*mo | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	user := data.(*model.User) | ||||
| 	userPO := data.(*model.UserPO) | ||||
|  | ||||
| 	user := &model.User{ | ||||
| 		ID:        userPO.ID, | ||||
| 		Email:     userPO.Email, | ||||
| 		Password:  userPO.Password, | ||||
| 		FirstName: userPO.FirstName, | ||||
| 		LastName:  userPO.LastName, | ||||
|  | ||||
| 		EventIDs: []int{}, // Unfilled | ||||
|  | ||||
| 		CreatedAt: userPO.CreatedAt, | ||||
| 		UpdatedAt: userPO.UpdatedAt, | ||||
| 	} | ||||
|  | ||||
| 	return user, nil | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	