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" "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 { type Account interface {
Insert(groupId uuid.UUID, account *types.Account) error Insert(userId uuid.UUID, account *types.Account) error
Update(groupId uuid.UUID, account *types.Account) error Update(userId uuid.UUID, account *types.Account) error
GetAll(groupId uuid.UUID) ([]*types.Account, error) GetAll(userId uuid.UUID) ([]*types.Account, error)
Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, error) Get(userId uuid.UUID, id uuid.UUID) (*types.Account, error)
Delete(groupId uuid.UUID, id uuid.UUID) error Delete(userId uuid.UUID, id uuid.UUID) error
} }
type AccountSqlite struct { type AccountSqlite struct {
@@ -25,11 +25,11 @@ func NewAccountSqlite(db *sqlx.DB) *AccountSqlite {
return &AccountSqlite{db: db} 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(` _, err := db.db.Exec(`
INSERT INTO account (id, group_id, name, current_balance, oink_balance, created_at, created_by) INSERT INTO account (id, user_id, name, current_balance, oink_balance, created_at, created_by)
VALUES (?,?,?,?,?,?,?)`, account.Id, groupId, account.Name, 0, 0, account.CreatedAt, account.CreatedBy) VALUES (?,?,?,?,?,?,?)`, account.Id, userId, account.Name, 0, 0, account.CreatedAt, account.CreatedBy)
if err != nil { if err != nil {
log.Error("Error inserting account: %v", err) log.Error("Error inserting account: %v", err)
return types.ErrInternal return types.ErrInternal
@@ -38,7 +38,7 @@ func (db AccountSqlite) Insert(groupId uuid.UUID, account *types.Account) error
return nil 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) log.Info("Updating account: %v", account)
r, err := db.db.Exec(` r, err := db.db.Exec(`
@@ -51,7 +51,7 @@ func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error
updated_at = ?, updated_at = ?,
updated_by = ? updated_by = ?
WHERE id = ? 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 { if err != nil {
log.Error("Error updating account: %v", err) log.Error("Error updating account: %v", err)
return types.ErrInternal return types.ErrInternal
@@ -70,17 +70,17 @@ func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error
return nil 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) accounts := make([]*types.Account, 0)
err := db.db.Select(&accounts, ` err := db.db.Select(&accounts, `
SELECT SELECT
id, group_id, name, id, user_id, name,
current_balance, last_transaction, oink_balance, current_balance, last_transaction, oink_balance,
created_at, created_by, updated_at, updated_by created_at, created_by, updated_at, updated_by
FROM account FROM account
WHERE group_id = ? WHERE user_id = ?
ORDER BY name`, groupId) ORDER BY name`, userId)
if err != nil { if err != nil {
log.Error("Could not getAll accounts: %v", err) log.Error("Could not getAll accounts: %v", err)
return nil, types.ErrInternal return nil, types.ErrInternal
@@ -89,17 +89,17 @@ func (db AccountSqlite) GetAll(groupId uuid.UUID) ([]*types.Account, error) {
return accounts, nil 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{} account := &types.Account{}
err := db.db.Get(account, ` err := db.db.Get(account, `
SELECT SELECT
id, group_id, name, id, user_id, name,
current_balance, last_transaction, oink_balance, current_balance, last_transaction, oink_balance,
created_at, created_by, updated_at, updated_by created_at, created_by, updated_at, updated_by
FROM account FROM account
WHERE group_id = ? WHERE user_id = ?
AND id = ?`, groupId, id) AND id = ?`, userId, id)
if err != nil { if err != nil {
log.Error("Could not get accounts: %v", err) log.Error("Could not get accounts: %v", err)
return nil, types.ErrInternal return nil, types.ErrInternal
@@ -108,9 +108,9 @@ func (db AccountSqlite) Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, er
return account, nil 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 { if err != nil {
log.Error("Error deleting account: %v", err) log.Error("Error deleting account: %v", err)
return types.ErrInternal return types.ErrInternal

View File

@@ -135,7 +135,7 @@ func (db AuthSqlite) DeleteUser(userId uuid.UUID) error {
return types.ErrInternal 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 { if err != nil {
_ = tx.Rollback() _ = tx.Rollback()
log.Error("Could not delete accounts: %v", err) log.Error("Could not delete accounts: %v", err)

View File

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

View File

@@ -1,7 +1,7 @@
CREATE TABLE account ( CREATE TABLE account (
id TEXT NOT NULL UNIQUE PRIMARY KEY, id TEXT NOT NULL UNIQUE PRIMARY KEY,
group_id TEXT NOT NULL, user_id TEXT NOT NULL,
name 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{ account := &types.Account{
Id: newId, Id: newId,
GroupId: user.Id, UserId: user.Id,
Name: name, Name: name,
@@ -150,7 +150,7 @@ func (service AccountImpl) Delete(user *types.User, id uuid.UUID) error {
return err return err
} }
if account.GroupId != user.Id { if account.UserId != user.Id {
return types.ErrUnauthorized return types.ErrUnauthorized
} }

View File

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

View File

@@ -8,7 +8,6 @@ import (
type User struct { type User struct {
Id uuid.UUID Id uuid.UUID
GroupId uuid.UUID
Email string Email string
EmailVerified bool EmailVerified bool
EmailVerifiedAt *time.Time 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. // 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 { type Transaction struct {
Id uuid.UUID Id uuid.UUID
GroupId uuid.UUID UserId uuid.UUID
AccountId uuid.UUID AccountId uuid.UUID
// nil indicates that the transaction is not yet associated with a piggy bank // nil indicates that the transaction is not yet associated with a piggy bank
@@ -38,7 +38,7 @@ type Transaction struct {
// The Account holds money // The Account holds money
type Account struct { type Account struct {
Id uuid.UUID 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" // Custom Name of the account, e.g. "Bank", "Cash", "Credit Card"
Name string Name string
@@ -58,7 +58,7 @@ type Account struct {
// The PiggyBank is a fictional account. The money it "holds" is actually in the Account // The PiggyBank is a fictional account. The money it "holds" is actually in the Account
type PiggyBank struct { type PiggyBank struct {
Id uuid.UUID Id uuid.UUID
GroupId uuid.UUID UserId uuid.UUID
AccountId uuid.UUID AccountId uuid.UUID
Name string Name string
@@ -74,7 +74,7 @@ type PiggyBank struct {
// The SavingsPlan is applied every interval to the PiggyBank/Account as a transaction // The SavingsPlan is applied every interval to the PiggyBank/Account as a transaction
type SavingsPlan struct { type SavingsPlan struct {
Id uuid.UUID Id uuid.UUID
GroupId uuid.UUID UserId uuid.UUID
PiggyBankId uuid.UUID PiggyBankId uuid.UUID