diff --git a/api/account.go b/api/account.go index bdd68fb..817bd98 100644 --- a/api/account.go +++ b/api/account.go @@ -120,20 +120,41 @@ func (server *Server) listAccounts(ctx *gin.Context) { ctx.JSON(http.StatusOK, accounts) } +type updateAccountPrivacyRequest struct { + ID int64 `binding:"required" json:"ID"` + Changer string `binding:"required" json:"changer"` + PrivacyAccepted bool `json:"privacy_accepted"` +} + +func (server *Server) updateAccountPrivacy(ctx *gin.Context) { + var req updateAccountPrivacyRequest + if err := ctx.ShouldBindJSON(&req); err != nil { + ctx.JSON(http.StatusBadRequest, errorResponse(err)) + return + } + + account, err := server.store.UpdateAccountPrivacyTx(ctx, db.UpdateAccountPrivacyTxParams(req)) + if err != nil { + ctx.JSON(http.StatusInternalServerError, errorResponse(err)) + return + } + + ctx.JSON(http.StatusOK, account) +} + type updateAccountRequest struct { - ID int64 `binding:"required" json:"ID"` - Changer string `binding:"required" json:"changer"` - PrivacyAccepted bool `json:"privacy_accepted"` - Passwordhash string `json:"passwordhash"` - Firstname string `json:"firstname"` - Lastname string `json:"lastname"` - Birthday time.Time `json:"birthday"` - Email string `json:"email"` - Phone string `json:"phone"` - City string `json:"city"` - Zip string `json:"zip"` - Street string `json:"street"` - Country string `json:"country"` + ID int64 `binding:"required" json:"ID"` + Changer string `binding:"required" json:"changer"` + Passwordhash string `json:"passwordhash"` + Firstname string `json:"firstname"` + Lastname string `json:"lastname"` + Birthday time.Time `json:"birthday"` + Email string `json:"email"` + Phone string `json:"phone"` + City string `json:"city"` + Zip string `json:"zip"` + Street string `json:"street"` + Country string `json:"country"` } func (server *Server) updateAccount(ctx *gin.Context) { @@ -143,12 +164,6 @@ func (server *Server) updateAccount(ctx *gin.Context) { return } - account, err := server.store.GetAccount(ctx, req.ID) - if err != nil { - ctx.JSON(http.StatusNotFound, errorResponse(err)) - return - } - arg := db.UpdateAccountTxParams{ ID: req.ID, Changer: req.Changer, @@ -192,13 +207,9 @@ func (server *Server) updateAccount(ctx *gin.Context) { String: req.Phone, Valid: req.Phone != "", }, - PrivacyAccepted: sql.NullBool{ - Valid: account.PrivacyAccepted.Bool != req.PrivacyAccepted, - Bool: req.PrivacyAccepted, - }, } - account, err = server.store.UpdateAccountTx(ctx, arg) + account, err := server.store.UpdateAccountTx(ctx, arg) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return diff --git a/api/account_test.go b/api/account_test.go index d19ba45..5f82317 100644 --- a/api/account_test.go +++ b/api/account_test.go @@ -303,10 +303,6 @@ func TestUpdateAccountTxAPI(t *testing.T) { Changer: changer, } - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1) - store.EXPECT(). UpdateAccountTx(gomock.Any(), gomock.Eq(arg)). Times(1). @@ -339,10 +335,6 @@ func TestUpdateAccountTxAPI(t *testing.T) { Changer: changer, } - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1) - store.EXPECT(). UpdateAccountTx(gomock.Any(), gomock.Eq(arg)). Times(1). @@ -573,6 +565,139 @@ func TestListAccountsAPI(t *testing.T) { } } +func TestUpdateAccountPrivacyTxAPI(t *testing.T) { + account := randomAccount() + changer := util.RandomName() + + testCases := []struct { + name string + body gin.H + buildStubs func(store *mockdb.MockStore) + checkResponse func(recoder *httptest.ResponseRecorder) + }{ + { + name: "OK", + body: gin.H{ + "id": account.ID, + "changer": changer, + "privacy_accepted": true, + }, + buildStubs: func(store *mockdb.MockStore) { + arg := db.UpdateAccountPrivacyTxParams{ + ID: account.ID, + PrivacyAccepted: true, + Changer: changer, + } + + account2 := account + account2.PrivacyAccepted.Valid = true + account2.PrivacyAccepted.Bool = true + account2.Changer = changer + + store.EXPECT(). + UpdateAccountPrivacyTx(gomock.Any(), gomock.Eq(arg)). + Times(1). + Return(account2, nil) + }, + checkResponse: func(recoder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusOK, recoder.Code) + data, err := io.ReadAll(recoder.Body) + require.NoError(t, err) + + var getAccount db.Account + err = json.Unmarshal(data, &getAccount) + require.NoError(t, err) + + require.Equal(t, account.ID, getAccount.ID) + require.Equal(t, true, getAccount.PrivacyAccepted.Bool) + require.Equal(t, true, getAccount.PrivacyAccepted.Valid) + require.WithinDuration(t, timestamp, getAccount.PrivacyAcceptedDate.Time, time.Second) + }, + }, + { + name: "Revoked", + body: gin.H{ + "id": account.ID, + "changer": changer, + "privacy_accepted": false, + }, + buildStubs: func(store *mockdb.MockStore) { + arg := db.UpdateAccountPrivacyTxParams{ + ID: account.ID, + PrivacyAccepted: false, + Changer: changer, + } + + account2 := account + account2.PrivacyAccepted.Valid = true + account2.PrivacyAccepted.Bool = false + account2.PrivacyAcceptedDate.Valid = true + account2.PrivacyAcceptedDate.Time = time.Time{} + account2.Changer = changer + + store.EXPECT(). + UpdateAccountPrivacyTx(gomock.Any(), gomock.Eq(arg)). + Times(1). + Return(account2, nil) + }, + checkResponse: func(recoder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusOK, recoder.Code) + data, err := io.ReadAll(recoder.Body) + require.NoError(t, err) + + var getAccount db.Account + err = json.Unmarshal(data, &getAccount) + require.NoError(t, err) + + require.Equal(t, account.ID, getAccount.ID) + require.Equal(t, false, getAccount.PrivacyAccepted.Bool) + require.Equal(t, true, getAccount.PrivacyAccepted.Valid) + require.Equal(t, time.Time{}, getAccount.PrivacyAcceptedDate.Time) + + }, + }, { + name: "OK", + body: gin.H{ + "id": account.ID, + }, + buildStubs: func(store *mockdb.MockStore) { + store.EXPECT(). + UpdateAccountPrivacyTx(gomock.Any(), gomock.Any()). + Times(0) + }, + checkResponse: func(recoder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusBadRequest, recoder.Code) + }, + }, + } + + for i := range testCases { + tc := testCases[i] + + t.Run(tc.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + store := mockdb.NewMockStore(ctrl) + tc.buildStubs(store) + + server := NewServer(config, store) + recorder := httptest.NewRecorder() + + // Marshal body data to JSON + data, err := json.Marshal(tc.body) + require.NoError(t, err) + + url := "/accounts/privacy" + request, err := http.NewRequest(http.MethodPut, url, bytes.NewReader(data)) + require.NoError(t, err) + + server.router.ServeHTTP(recorder, request) + tc.checkResponse(recorder) + }) + } +} + func randomAccount() db.Account { acc := db.Account{ ID: util.RandomInt(1, 1000), diff --git a/api/server.go b/api/server.go index 8fb94ec..083bbd0 100644 --- a/api/server.go +++ b/api/server.go @@ -47,6 +47,7 @@ func NewServer(config util.Config, store db.Store) *Server { router.POST("/accounts", server.createAccount) router.PUT("/accounts", server.updateAccount) + router.PUT("/accounts/privacy", server.updateAccountPrivacy) router.GET("/accounts/:id", server.getAccount) router.GET("/accounts", server.listAccounts) diff --git a/db/mock/store.go b/db/mock/store.go index 8cca983..25a06d5 100644 --- a/db/mock/store.go +++ b/db/mock/store.go @@ -586,6 +586,36 @@ func (mr *MockStoreMockRecorder) UpdateAccount(arg0, arg1 any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAccount", reflect.TypeOf((*MockStore)(nil).UpdateAccount), arg0, arg1) } +// UpdateAccountPrivacy mocks base method. +func (m *MockStore) UpdateAccountPrivacy(arg0 context.Context, arg1 db.UpdateAccountPrivacyParams) (db.Account, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateAccountPrivacy", arg0, arg1) + ret0, _ := ret[0].(db.Account) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateAccountPrivacy indicates an expected call of UpdateAccountPrivacy. +func (mr *MockStoreMockRecorder) UpdateAccountPrivacy(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAccountPrivacy", reflect.TypeOf((*MockStore)(nil).UpdateAccountPrivacy), arg0, arg1) +} + +// UpdateAccountPrivacyTx mocks base method. +func (m *MockStore) UpdateAccountPrivacyTx(arg0 context.Context, arg1 db.UpdateAccountPrivacyTxParams) (db.Account, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateAccountPrivacyTx", arg0, arg1) + ret0, _ := ret[0].(db.Account) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateAccountPrivacyTx indicates an expected call of UpdateAccountPrivacyTx. +func (mr *MockStoreMockRecorder) UpdateAccountPrivacyTx(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAccountPrivacyTx", reflect.TypeOf((*MockStore)(nil).UpdateAccountPrivacyTx), arg0, arg1) +} + // UpdateAccountTx mocks base method. func (m *MockStore) UpdateAccountTx(arg0 context.Context, arg1 db.UpdateAccountTxParams) (db.Account, error) { m.ctrl.T.Helper() diff --git a/db/query/account.sql b/db/query/account.sql index d36e778..49094e8 100644 --- a/db/query/account.sql +++ b/db/query/account.sql @@ -50,8 +50,6 @@ OFFSET $2; UPDATE accounts SET "passwordhash" = COALESCE(sqlc.narg(passwordhash), "passwordhash"), - "privacy_accepted" = COALESCE(sqlc.narg(privacy_accepted), "privacy_accepted"), - "privacy_accepted_date" = COALESCE(sqlc.narg(privacy_accepted_date), "privacy_accepted_date"), "firstname" = COALESCE(sqlc.narg(firstname), "firstname"), "lastname" = COALESCE(sqlc.narg(lastname), "lastname"), "birthday" = COALESCE(sqlc.narg(birthday), "birthday"), @@ -66,6 +64,16 @@ SET WHERE "id" = $1 RETURNING *; +-- name: UpdateAccountPrivacy :one +UPDATE accounts +SET + "privacy_accepted" = sqlc.arg(privacy_accepted), + "privacy_accepted_date" = sqlc.arg(privacy_accepted_date), + "changer" = sqlc.arg(changer), + "changed" = now() +WHERE "id" = sqlc.arg(id) +RETURNING *; + -- name: DeleteAccount :exec DELETE FROM accounts WHERE "id" = $1; \ No newline at end of file diff --git a/db/sqlc/account.sql.go b/db/sqlc/account.sql.go index bd38a52..76c9b51 100644 --- a/db/sqlc/account.sql.go +++ b/db/sqlc/account.sql.go @@ -240,17 +240,15 @@ const updateAccount = `-- name: UpdateAccount :one UPDATE accounts SET "passwordhash" = COALESCE($3, "passwordhash"), - "privacy_accepted" = COALESCE($4, "privacy_accepted"), - "privacy_accepted_date" = COALESCE($5, "privacy_accepted_date"), - "firstname" = COALESCE($6, "firstname"), - "lastname" = COALESCE($7, "lastname"), - "birthday" = COALESCE($8, "birthday"), - "email" = COALESCE($9, "email"), - "phone" = COALESCE($10, "phone"), - "city" = COALESCE($11, "city"), - "zip" = COALESCE($12, "zip"), - "street" = COALESCE($13, "street"), - "country" = COALESCE($14, "country"), + "firstname" = COALESCE($4, "firstname"), + "lastname" = COALESCE($5, "lastname"), + "birthday" = COALESCE($6, "birthday"), + "email" = COALESCE($7, "email"), + "phone" = COALESCE($8, "phone"), + "city" = COALESCE($9, "city"), + "zip" = COALESCE($10, "zip"), + "street" = COALESCE($11, "street"), + "country" = COALESCE($12, "country"), "changer" = $2, "changed" = now() WHERE "id" = $1 @@ -258,20 +256,18 @@ RETURNING id, passwordhash, firstname, lastname, birthday, privacy_accepted, pri ` type UpdateAccountParams struct { - ID int64 `json:"id"` - Changer string `json:"changer"` - Passwordhash sql.NullString `json:"passwordhash"` - PrivacyAccepted sql.NullBool `json:"privacy_accepted"` - PrivacyAcceptedDate sql.NullTime `json:"privacy_accepted_date"` - Firstname sql.NullString `json:"firstname"` - Lastname sql.NullString `json:"lastname"` - Birthday sql.NullTime `json:"birthday"` - Email sql.NullString `json:"email"` - Phone sql.NullString `json:"phone"` - City sql.NullString `json:"city"` - Zip sql.NullString `json:"zip"` - Street sql.NullString `json:"street"` - Country sql.NullString `json:"country"` + ID int64 `json:"id"` + Changer string `json:"changer"` + Passwordhash sql.NullString `json:"passwordhash"` + Firstname sql.NullString `json:"firstname"` + Lastname sql.NullString `json:"lastname"` + Birthday sql.NullTime `json:"birthday"` + Email sql.NullString `json:"email"` + Phone sql.NullString `json:"phone"` + City sql.NullString `json:"city"` + Zip sql.NullString `json:"zip"` + Street sql.NullString `json:"street"` + Country sql.NullString `json:"country"` } func (q *Queries) UpdateAccount(ctx context.Context, arg UpdateAccountParams) (Account, error) { @@ -279,8 +275,6 @@ func (q *Queries) UpdateAccount(ctx context.Context, arg UpdateAccountParams) (A arg.ID, arg.Changer, arg.Passwordhash, - arg.PrivacyAccepted, - arg.PrivacyAcceptedDate, arg.Firstname, arg.Lastname, arg.Birthday, @@ -316,3 +310,54 @@ func (q *Queries) UpdateAccount(ctx context.Context, arg UpdateAccountParams) (A ) return i, err } + +const updateAccountPrivacy = `-- name: UpdateAccountPrivacy :one +UPDATE accounts +SET + "privacy_accepted" = $1, + "privacy_accepted_date" = $2, + "changer" = $3, + "changed" = now() +WHERE "id" = $4 +RETURNING id, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, phone, city, zip, street, country, token, token_valid, token_expiration, creator, created, changer, changed +` + +type UpdateAccountPrivacyParams struct { + PrivacyAccepted sql.NullBool `json:"privacy_accepted"` + PrivacyAcceptedDate sql.NullTime `json:"privacy_accepted_date"` + Changer string `json:"changer"` + ID int64 `json:"id"` +} + +func (q *Queries) UpdateAccountPrivacy(ctx context.Context, arg UpdateAccountPrivacyParams) (Account, error) { + row := q.db.QueryRowContext(ctx, updateAccountPrivacy, + arg.PrivacyAccepted, + arg.PrivacyAcceptedDate, + arg.Changer, + arg.ID, + ) + var i Account + err := row.Scan( + &i.ID, + &i.Passwordhash, + &i.Firstname, + &i.Lastname, + &i.Birthday, + &i.PrivacyAccepted, + &i.PrivacyAcceptedDate, + &i.Email, + &i.Phone, + &i.City, + &i.Zip, + &i.Street, + &i.Country, + &i.Token, + &i.TokenValid, + &i.TokenExpiration, + &i.Creator, + &i.Created, + &i.Changer, + &i.Changed, + ) + return i, err +} diff --git a/db/sqlc/account_test.go b/db/sqlc/account_test.go index e675952..4c88937 100644 --- a/db/sqlc/account_test.go +++ b/db/sqlc/account_test.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/require" ) +var timestamp = time.Now() + func createRandomAccount(t *testing.T) Account { creator := util.RandomName() @@ -28,6 +30,10 @@ func createRandomAccount(t *testing.T) Account { Valid: true, Bool: true, }, + PrivacyAcceptedDate: sql.NullTime{ + Valid: true, + Time: timestamp, + }, City: util.RandomString(15), Zip: util.RandomString(5), Street: util.RandomString(20), @@ -119,6 +125,56 @@ func TestUpdateAccount(t *testing.T) { require.NotEqual(t, account1.Changer, account2.Changer) } +func TestUpdateAccountPrivacy(t *testing.T) { + account1 := createRandomAccount(t) + require.NotEmpty(t, account1) + + changer1 := util.RandomName() + + arg := UpdateAccountPrivacyParams{ + ID: account1.ID, + PrivacyAccepted: sql.NullBool{ + Valid: true, + Bool: false, + }, + PrivacyAcceptedDate: sql.NullTime{ + Valid: true, + Time: time.Time{}, + }, + Changer: changer1, + } + + account2, err := testQueries.UpdateAccountPrivacy(context.Background(), arg) + require.NoError(t, err) + require.NotEmpty(t, account2) + + require.Equal(t, account1.ID, account2.ID) + require.Equal(t, account1.Lastname, account2.Lastname) + require.WithinDuration(t, time.Time{}, account2.PrivacyAcceptedDate.Time, time.Second) + require.NotEqual(t, account1.PrivacyAccepted.Bool, account2.PrivacyAccepted.Bool) + require.NotEqual(t, account1.PrivacyAcceptedDate.Time, account2.PrivacyAcceptedDate.Time) + + arg.PrivacyAccepted = sql.NullBool{ + Valid: true, + Bool: true, + } + + arg.PrivacyAcceptedDate = sql.NullTime{ + Valid: true, + Time: timestamp.UTC(), + } + + account1, err = testQueries.UpdateAccountPrivacy(context.Background(), arg) + require.NoError(t, err) + require.NotEmpty(t, account2) + + require.Equal(t, account1.ID, account2.ID) + require.Equal(t, account1.Lastname, account2.Lastname) + require.WithinDuration(t, timestamp.UTC(), account1.PrivacyAcceptedDate.Time, time.Second) + require.NotEqual(t, account1.PrivacyAccepted.Bool, account2.PrivacyAccepted.Bool) + require.NotEqual(t, account1.PrivacyAcceptedDate.Time, account2.PrivacyAcceptedDate.Time) +} + func TestListAccounts(t *testing.T) { for i := 0; i < 10; i++ { createRandomAccount(t) diff --git a/db/sqlc/querier.go b/db/sqlc/querier.go index 1f4fea1..2dee7af 100644 --- a/db/sqlc/querier.go +++ b/db/sqlc/querier.go @@ -58,6 +58,7 @@ type Querier interface { ListReturns(ctx context.Context, arg ListReturnsParams) ([]Return, error) ListReturnsLogs(ctx context.Context, arg ListReturnsLogsParams) ([]ReturnsLog, error) UpdateAccount(ctx context.Context, arg UpdateAccountParams) (Account, error) + UpdateAccountPrivacy(ctx context.Context, arg UpdateAccountPrivacyParams) (Account, error) UpdateDocument(ctx context.Context, arg UpdateDocumentParams) (Document, error) UpdatePayment(ctx context.Context, arg UpdatePaymentParams) (Payment, error) UpdatePerson(ctx context.Context, arg UpdatePersonParams) (Person, error) diff --git a/db/sqlc/store.go b/db/sqlc/store.go index b4e4eea..36d47dd 100644 --- a/db/sqlc/store.go +++ b/db/sqlc/store.go @@ -10,6 +10,7 @@ type Store interface { Querier CreateAccountTx(ctx context.Context, arg CreateAccountTxParams) (Account, error) UpdateAccountTx(ctx context.Context, arg UpdateAccountTxParams) (Account, error) + UpdateAccountPrivacyTx(ctx context.Context, arg UpdateAccountPrivacyTxParams) (Account, error) } // Store provides all functions to execute db queries and transactions diff --git a/db/sqlc/tx_update_account.go b/db/sqlc/tx_update_account.go index 3799fb7..48dbff9 100644 --- a/db/sqlc/tx_update_account.go +++ b/db/sqlc/tx_update_account.go @@ -3,24 +3,21 @@ package db import ( "context" "database/sql" - "time" ) type UpdateAccountTxParams struct { - ID int64 `json:"ID"` - Changer string `json:"changer"` - Passwordhash sql.NullString `json:"passwordhash"` - PrivacyAccepted sql.NullBool `json:"privacy_accepted"` - PrivacyAcceptedDate sql.NullTime `json:"privacy_accepted_date"` - Firstname sql.NullString `json:"firstname"` - Lastname sql.NullString `json:"lastname"` - Birthday sql.NullTime `json:"birthday"` - Email sql.NullString `json:"email"` - Phone sql.NullString `json:"phone"` - City sql.NullString `json:"city"` - Zip sql.NullString `json:"zip"` - Street sql.NullString `json:"street"` - Country sql.NullString `json:"country"` + ID int64 `json:"ID"` + Changer string `json:"changer"` + Passwordhash sql.NullString `json:"passwordhash"` + Firstname sql.NullString `json:"firstname"` + Lastname sql.NullString `json:"lastname"` + Birthday sql.NullTime `json:"birthday"` + Email sql.NullString `json:"email"` + Phone sql.NullString `json:"phone"` + City sql.NullString `json:"city"` + Zip sql.NullString `json:"zip"` + Street sql.NullString `json:"street"` + Country sql.NullString `json:"country"` } type UpdateAccountTxResult struct { @@ -30,26 +27,7 @@ type UpdateAccountTxResult struct { func (store *SQLStore) UpdateAccountTx(ctx context.Context, arg UpdateAccountTxParams) (Account, error) { var result UpdateAccountTxResult - account, err := store.GetAccount(ctx, arg.ID) - if err != nil { - return Account{}, err - } - - if arg.PrivacyAccepted.Bool && arg.PrivacyAccepted.Bool != account.PrivacyAccepted.Bool { - arg.PrivacyAcceptedDate = sql.NullTime{ - Valid: true, - Time: time.Now(), - } - } - - if !account.PrivacyAccepted.Bool && !arg.PrivacyAccepted.Bool { - arg.PrivacyAcceptedDate = sql.NullTime{ - Valid: true, - Time: time.Time{}, - } - } - - err = store.execTx(ctx, func(q *Queries) error { + err := store.execTx(ctx, func(q *Queries) error { var err error result.Account, err = q.UpdateAccount(ctx, UpdateAccountParams(arg)) return err diff --git a/db/sqlc/tx_update_account_privacy.go b/db/sqlc/tx_update_account_privacy.go new file mode 100644 index 0000000..a394789 --- /dev/null +++ b/db/sqlc/tx_update_account_privacy.go @@ -0,0 +1,46 @@ +package db + +import ( + "context" + "database/sql" + "time" +) + +type UpdateAccountPrivacyTxParams struct { + ID int64 `json:"ID"` + Changer string `json:"changer"` + PrivacyAccepted bool `json:"privacy_accepted"` +} + +type UpdateAccountPrivacyTxResult struct { + Account Account `json:"account"` +} + +func (store *SQLStore) UpdateAccountPrivacyTx(ctx context.Context, arg UpdateAccountPrivacyTxParams) (Account, error) { + var result UpdateAccountPrivacyTxResult + param := UpdateAccountPrivacyParams{ + ID: arg.ID, + Changer: arg.Changer, + } + + if arg.PrivacyAccepted { + param.PrivacyAcceptedDate = sql.NullTime{ + Valid: true, + Time: time.Now(), + } + } else { + param.PrivacyAcceptedDate = sql.NullTime{ + Valid: true, + Time: time.Time{}, + } + + } + + err := store.execTx(ctx, func(q *Queries) error { + var err error + result.Account, err = q.UpdateAccountPrivacy(ctx, param) + return err + }) + + return result.Account, err +}