feat(account): #49 replace group_id with user_id, as data sharing is a whole new complicated topic
All checks were successful
Build Docker Image / Build-Docker-Image (push) Successful in 7m51s
Build and Push Docker Image / Build-And-Push-Docker-Image (push) Successful in 3m10s

This commit was merged in pull request #60.
This commit is contained in:
2025-05-08 13:19:46 +02:00
parent 8f392fb0a8
commit 511c4ca22b
8 changed files with 42 additions and 43 deletions

View File

@@ -8,13 +8,13 @@ import (
"github.com/jmoiron/sqlx"
)
// While it may be duplicated to check for groupIds in the database access, it serves as a security layer
// While it may be duplicated to check for userId in the database access, it serves as a security layer
type Account interface {
Insert(groupId uuid.UUID, account *types.Account) error
Update(groupId uuid.UUID, account *types.Account) error
GetAll(groupId uuid.UUID) ([]*types.Account, error)
Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, error)
Delete(groupId uuid.UUID, id uuid.UUID) error
Insert(userId uuid.UUID, account *types.Account) error
Update(userId uuid.UUID, account *types.Account) error
GetAll(userId uuid.UUID) ([]*types.Account, error)
Get(userId uuid.UUID, id uuid.UUID) (*types.Account, error)
Delete(userId uuid.UUID, id uuid.UUID) error
}
type AccountSqlite struct {
@@ -25,11 +25,11 @@ func NewAccountSqlite(db *sqlx.DB) *AccountSqlite {
return &AccountSqlite{db: db}
}
func (db AccountSqlite) Insert(groupId uuid.UUID, account *types.Account) error {
func (db AccountSqlite) Insert(userId uuid.UUID, account *types.Account) error {
_, err := db.db.Exec(`
INSERT INTO account (id, group_id, name, current_balance, oink_balance, created_at, created_by)
VALUES (?,?,?,?,?,?,?)`, account.Id, groupId, account.Name, 0, 0, account.CreatedAt, account.CreatedBy)
INSERT INTO account (id, user_id, name, current_balance, oink_balance, created_at, created_by)
VALUES (?,?,?,?,?,?,?)`, account.Id, userId, account.Name, 0, 0, account.CreatedAt, account.CreatedBy)
if err != nil {
log.Error("Error inserting account: %v", err)
return types.ErrInternal
@@ -38,7 +38,7 @@ func (db AccountSqlite) Insert(groupId uuid.UUID, account *types.Account) error
return nil
}
func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error {
func (db AccountSqlite) Update(userId uuid.UUID, account *types.Account) error {
log.Info("Updating account: %v", account)
r, err := db.db.Exec(`
@@ -51,7 +51,7 @@ func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error
updated_at = ?,
updated_by = ?
WHERE id = ?
AND group_id = ?`, account.Name, account.CurrentBalance, account.LastTransaction, account.OinkBalance, account.UpdatedAt, account.UpdatedBy, account.Id, groupId)
AND user_id = ?`, account.Name, account.CurrentBalance, account.LastTransaction, account.OinkBalance, account.UpdatedAt, account.UpdatedBy, account.Id, userId)
if err != nil {
log.Error("Error updating account: %v", err)
return types.ErrInternal
@@ -70,17 +70,17 @@ func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error
return nil
}
func (db AccountSqlite) GetAll(groupId uuid.UUID) ([]*types.Account, error) {
func (db AccountSqlite) GetAll(userId uuid.UUID) ([]*types.Account, error) {
accounts := make([]*types.Account, 0)
err := db.db.Select(&accounts, `
SELECT
id, group_id, name,
id, user_id, name,
current_balance, last_transaction, oink_balance,
created_at, created_by, updated_at, updated_by
FROM account
WHERE group_id = ?
ORDER BY name`, groupId)
WHERE user_id = ?
ORDER BY name`, userId)
if err != nil {
log.Error("Could not getAll accounts: %v", err)
return nil, types.ErrInternal
@@ -89,17 +89,17 @@ func (db AccountSqlite) GetAll(groupId uuid.UUID) ([]*types.Account, error) {
return accounts, nil
}
func (db AccountSqlite) Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, error) {
func (db AccountSqlite) Get(userId uuid.UUID, id uuid.UUID) (*types.Account, error) {
account := &types.Account{}
err := db.db.Get(account, `
SELECT
id, group_id, name,
id, user_id, name,
current_balance, last_transaction, oink_balance,
created_at, created_by, updated_at, updated_by
FROM account
WHERE group_id = ?
AND id = ?`, groupId, id)
WHERE user_id = ?
AND id = ?`, userId, id)
if err != nil {
log.Error("Could not get accounts: %v", err)
return nil, types.ErrInternal
@@ -108,9 +108,9 @@ func (db AccountSqlite) Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, er
return account, nil
}
func (db AccountSqlite) Delete(groupId uuid.UUID, id uuid.UUID) error {
func (db AccountSqlite) Delete(userId uuid.UUID, id uuid.UUID) error {
res, err := db.db.Exec("DELETE FROM account WHERE id = ? and group_id = ?", id, groupId)
res, err := db.db.Exec("DELETE FROM account WHERE id = ? and user_id = ?", id, userId)
if err != nil {
log.Error("Error deleting account: %v", err)
return types.ErrInternal

View File

@@ -135,7 +135,7 @@ func (db AuthSqlite) DeleteUser(userId uuid.UUID) error {
return types.ErrInternal
}
_, err = tx.Exec("DELETE FROM account WHERE group_id = ?", userId)
_, err = tx.Exec("DELETE FROM account WHERE user_id = ?", userId)
if err != nil {
_ = tx.Rollback()
log.Error("Could not delete accounts: %v", err)

View File

@@ -334,7 +334,7 @@ func TestIntegrationAuth(t *testing.T) {
resp, err = httpClient.Do(req)
timeEnd := time.Now()
assert.Nil(t, err)
if timeEnd.Sub(timeStart) > 260*time.Millisecond || timeEnd.Sub(timeStart) <= 250*time.Millisecond {
if timeEnd.Sub(timeStart) > 260*time.Millisecond || timeEnd.Sub(timeStart) < 250*time.Millisecond {
t.Fail()
t.Logf("Time did not match: %v", timeEnd.Sub(timeStart))
}
@@ -929,7 +929,7 @@ func TestIntegrationAuth(t *testing.T) {
err = db.QueryRow("SELECT COUNT(*) FROM user WHERE user_id = ?", userId).Scan(&rows)
assert.Nil(t, err)
assert.Equal(t, 0, rows)
err = db.QueryRow("SELECT COUNT(*) FROM account WHERE group_id = ?", userId).Scan(&rows)
err = db.QueryRow("SELECT COUNT(*) FROM account WHERE user_id = ?", userId).Scan(&rows)
assert.Nil(t, err)
assert.Equal(t, 0, rows)
})

View File

@@ -1,7 +1,7 @@
CREATE TABLE account (
id TEXT NOT NULL UNIQUE PRIMARY KEY,
group_id TEXT NOT NULL,
user_id TEXT NOT NULL,
name TEXT NOT NULL,

View File

@@ -56,7 +56,7 @@ func (service AccountImpl) Add(user *types.User, name string) (*types.Account, e
account := &types.Account{
Id: newId,
GroupId: user.Id,
UserId: user.Id,
Name: name,
@@ -150,7 +150,7 @@ func (service AccountImpl) Delete(user *types.User, id uuid.UUID) error {
return err
}
if account.GroupId != user.Id {
if account.UserId != user.Id {
return types.ErrUnauthorized
}

View File

@@ -14,11 +14,11 @@ func TestMoneyCalculation(t *testing.T) {
// // GIVEN
// timestamp := time.Date(2020, 01, 01, 0, 0, 0, 0, time.UTC)
//
// groupId := uuid.New()
// userId := uuid.New()
//
// account := types.Account{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
//
// Type: "Bank",
// Name: "Bank",
@@ -31,7 +31,7 @@ func TestMoneyCalculation(t *testing.T) {
// // The PiggyBank is a fictional account. The money it "holds" is actually in the Account
// piggyBank := types.PiggyBank{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
//
// AccountId: account.Id,
// Name: "Car",
@@ -41,7 +41,7 @@ func TestMoneyCalculation(t *testing.T) {
//
// savingsPlan := types.SavingsPlan{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
// PiggyBankId: piggyBank.Id,
//
// MonthlySaving: 10,
@@ -51,7 +51,7 @@ func TestMoneyCalculation(t *testing.T) {
//
// transaction1 := types.Transaction{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
//
// AccountId: account.Id,
//
@@ -61,7 +61,7 @@ func TestMoneyCalculation(t *testing.T) {
//
// transaction2 := types.Transaction{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
//
// AccountId: account.Id,
// PiggyBankId: &piggyBank.Id,

View File

@@ -8,7 +8,6 @@ import (
type User struct {
Id uuid.UUID
GroupId uuid.UUID
Email string
EmailVerified bool
EmailVerifiedAt *time.Time

View File

@@ -13,7 +13,7 @@ import (
// If it becomes necessary to precalculate snapshots for performance reasons, this can be done in the future. But the transaction should always be the source of truth.
type Transaction struct {
Id uuid.UUID
GroupId uuid.UUID
UserId uuid.UUID
AccountId uuid.UUID
// nil indicates that the transaction is not yet associated with a piggy bank
@@ -38,7 +38,7 @@ type Transaction struct {
// The Account holds money
type Account struct {
Id uuid.UUID
GroupId uuid.UUID `db:"group_id"`
UserId uuid.UUID `db:"user_id"`
// Custom Name of the account, e.g. "Bank", "Cash", "Credit Card"
Name string
@@ -58,7 +58,7 @@ type Account struct {
// The PiggyBank is a fictional account. The money it "holds" is actually in the Account
type PiggyBank struct {
Id uuid.UUID
GroupId uuid.UUID
UserId uuid.UUID
AccountId uuid.UUID
Name string
@@ -74,7 +74,7 @@ type PiggyBank struct {
// The SavingsPlan is applied every interval to the PiggyBank/Account as a transaction
type SavingsPlan struct {
Id uuid.UUID
GroupId uuid.UUID
UserId uuid.UUID
PiggyBankId uuid.UUID