Skip to content
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

Task/clean up old handlers #311

Merged
merged 7 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions generate-client.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash

# Function to display usage
show_usage() {
echo "Usage: $0 <platform> <output-dir>"
echo ""
echo "Arguments:"
echo " platform Either 'desktop' or 'mobile'"
echo " output-dir Directory path for generated code output"
echo ""
echo "Example:"
echo " $0 desktop /home/user/project/src/open-api"
exit 1
}

# Check if correct number of arguments is provided
if [ $# -ne 2 ]; then
echo "Error: Exactly 2 arguments are required"
show_usage
fi

platform=$1
output_dir=$2

# Validate platform argument
if [ "$platform" != "desktop" ] && [ "$platform" != "mobile" ]; then
echo "Error: Platform must be either 'desktop' or 'mobile'"
show_usage
fi

# Set generator based on platform
if [ "$platform" = "desktop" ]; then
generator="typescript-angular"
else
generator="dart-dio"
fi

# Execute the OpenAPI generator command
npx @openapitools/openapi-generator-cli generate \
-i swagger.yml \
-g "$generator" \
-o "$output_dir"

# Check if command executed successfully
if [ $? -eq 0 ]; then
echo "API code successfully generated in: $output_dir"
else
echo "Error: API code generation failed"
exit 1
fi
1 change: 0 additions & 1 deletion generate-core-swagger.sh

This file was deleted.

53 changes: 53 additions & 0 deletions internal/commands/upsert_group_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package commands

import (
"encoding/json"
"net/http"
"receipt-wrangler/api/internal/models"
"receipt-wrangler/api/internal/structs"
"receipt-wrangler/api/internal/utils"
)

type UpsertGroupCommand struct {
Name string `gorm:"not null" json:"name"`
GroupMembers []UpsertGroupMemberCommand `json:"groupMembers"`
Status models.GroupStatus `gorm:"default:'ACTIVE'; not null" json:"status"`
IsAllGroup bool `json:"isAllGroup" gorm:"default:false"`
IsDefaultGroup bool `json:"isDefault"`
}

func (command *UpsertGroupCommand) LoadDataFromRequest(w http.ResponseWriter, r *http.Request) error {
bytes, err := utils.GetBodyData(w, r)
if err != nil {
return err
}

err = json.Unmarshal(bytes, &command)
if err != nil {
return err
}

return nil
}

func (command *UpsertGroupCommand) Validate(isCreate bool) structs.ValidatorError {
vErr := structs.ValidatorError{}
errorMap := make(map[string]string)

if len(command.Name) == 0 {
errorMap["name"] = "Name is required"
}

if len(command.Status) == 0 {
errorMap["status"] = "Status is required"
}

if !isCreate {
if len(command.GroupMembers) == 0 {
errorMap["groupMembers"] = "Group Members are required"
}
}

vErr.Errors = errorMap
return vErr
}
9 changes: 9 additions & 0 deletions internal/commands/upsert_group_memeber_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package commands

import "receipt-wrangler/api/internal/models"

type UpsertGroupMemberCommand struct {
UserID uint `gorm:"primaryKey;autoIncrement:false" json:"userId"`
GroupID uint `gorm:"primaryKey;autoIncrement:false" json:"groupId"`
GroupRole models.GroupRole `gorm:"not null" json:"groupRole"`
}
32 changes: 27 additions & 5 deletions internal/handlers/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,23 @@ func CreateGroup(w http.ResponseWriter, r *http.Request) {
Request: r,
ResponseType: constants.APPLICATION_JSON,
HandlerFunction: func(w http.ResponseWriter, r *http.Request) (int, error) {
command := commands.UpsertGroupCommand{}
err := command.LoadDataFromRequest(w, r)
if err != nil {
return http.StatusInternalServerError, err
}

vErrs := command.Validate(true)
if len(vErrs.Errors) > 0 {
structs.WriteValidatorErrorResponse(w, vErrs, http.StatusBadRequest)
return 0, nil
}

token := structs.GetJWT(r)
group := r.Context().Value("group").(models.Group)
group.IsAllGroup = false

command.IsAllGroup = false
groupRepository := repositories.NewGroupRepository(nil)
group, err := groupRepository.CreateGroup(group, token.UserId)
group, err := groupRepository.CreateGroup(command, token.UserId)

if err != nil {
return http.StatusInternalServerError, err
Expand Down Expand Up @@ -202,6 +213,7 @@ func CreateGroup(w http.ResponseWriter, r *http.Request) {
HandleRequest(handler)
}

// TODO: move hooks, and update swagger to take command
func UpdateGroup(w http.ResponseWriter, r *http.Request) {
handler := structs.Handler{
ErrorMessage: "Error updating group.",
Expand All @@ -211,7 +223,17 @@ func UpdateGroup(w http.ResponseWriter, r *http.Request) {
GroupRole: models.OWNER,
ResponseType: constants.APPLICATION_JSON,
HandlerFunction: func(w http.ResponseWriter, r *http.Request) (int, error) {
group := r.Context().Value("group").(models.Group)
command := commands.UpsertGroupCommand{}
err := command.LoadDataFromRequest(w, r)
if err != nil {
return http.StatusInternalServerError, err
}

vErrs := command.Validate(true)
if len(vErrs.Errors) > 0 {
structs.WriteValidatorErrorResponse(w, vErrs, http.StatusBadRequest)
return 0, nil
}
groupId := chi.URLParam(r, "groupId")

groupRepository := repositories.NewGroupRepository(nil)
Expand All @@ -228,7 +250,7 @@ func UpdateGroup(w http.ResponseWriter, r *http.Request) {
return http.StatusBadRequest, errors.New("cannot update all group")
}

updatedGroup, err := groupRepository.UpdateGroup(group, groupId)
updatedGroup, err := groupRepository.UpdateGroup(command, groupId)

if err != nil {
return http.StatusInternalServerError, err
Expand Down
52 changes: 42 additions & 10 deletions internal/repositories/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,22 +77,39 @@ func (repository GroupRepository) isValidColumn(orderBy string) bool {
orderBy == "updated_at"
}

func (repository GroupRepository) CreateGroup(group models.Group, userId uint) (models.Group, error) {
func (repository GroupRepository) CreateGroup(command commands.UpsertGroupCommand, userId uint) (models.Group, error) {
// TODO: move hooks on delete to repository func
db := repository.GetDB()
var returnGroup models.Group
var groupToCreate models.Group

groupToCreate.Name = command.Name
groupToCreate.Status = command.Status
groupToCreate.IsAllGroup = command.IsAllGroup
for i := 0; i < len(command.GroupMembers); i++ {
groupMemberCommand := command.GroupMembers[i]
groupMember := models.GroupMember{
UserID: groupMemberCommand.UserID,
GroupID: groupMemberCommand.GroupID,
GroupRole: groupMemberCommand.GroupRole,
}

groupToCreate.GroupMembers = append(groupToCreate.GroupMembers, groupMember)
}

err := db.Transaction(func(tx *gorm.DB) error {
repository.SetTransaction(tx)
groupSettingsRepository := NewGroupSettingsRepository(tx)

txErr := tx.Model(&group).Create(&group).Error
txErr := tx.Model(&groupToCreate).Create(&groupToCreate).Error
if txErr != nil {
repository.ClearTransaction()
return txErr
}

groupMember := models.GroupMember{
UserID: userId,
GroupID: group.ID,
GroupID: groupToCreate.ID,
GroupRole: models.OWNER,
}

Expand All @@ -103,7 +120,7 @@ func (repository GroupRepository) CreateGroup(group models.Group, userId uint) (
}

groupSettings := models.GroupSettings{
GroupId: group.ID,
GroupId: groupToCreate.ID,
}

_, txErr = groupSettingsRepository.CreateGroupSettings(groupSettings)
Expand All @@ -119,31 +136,46 @@ func (repository GroupRepository) CreateGroup(group models.Group, userId uint) (
return models.Group{}, err
}

err = repository.GetDB().Model(models.Group{}).Where("id = ?", group.ID).Preload("GroupMembers").Find(&returnGroup).Error
err = repository.GetDB().Model(models.Group{}).Where("id = ?", groupToCreate.ID).Preload("GroupMembers").Find(&returnGroup).Error
if err != nil {
return models.Group{}, err
}

return returnGroup, nil
}

func (repository GroupRepository) UpdateGroup(group models.Group, groupId string) (models.Group, error) {
func (repository GroupRepository) UpdateGroup(command commands.UpsertGroupCommand, groupId string) (models.Group, error) {
// TODO: move hooks from model to repository func
db := repository.GetDB()

u64Id, err := simpleutils.StringToUint64(groupId)
if err != nil {
return models.Group{}, err
}

group.ID = uint(u64Id)
groupToUpdate := models.Group{
Name: command.Name,
Status: command.Status,
}
groupToUpdate.ID = uint(u64Id)

for i := 0; i < len(command.GroupMembers); i++ {
groupMemberCommand := command.GroupMembers[i]
groupMember := models.GroupMember{
UserID: groupMemberCommand.UserID,
GroupID: groupMemberCommand.GroupID,
GroupRole: groupMemberCommand.GroupRole,
}
groupToUpdate.GroupMembers = append(groupToUpdate.GroupMembers, groupMember)
}

err = db.Transaction(func(tx *gorm.DB) error {
txErr := tx.Session(&gorm.Session{FullSaveAssociations: true}).Model(&group).Omit("ID", "is_all_group").Updates(&group).Error
txErr := tx.Session(&gorm.Session{FullSaveAssociations: true}).Model(&groupToUpdate).Omit("ID", "is_all_group").Updates(&groupToUpdate).Error
if err != nil {
return txErr
}

txErr = tx.Model(&group).Association("GroupMembers").Unscoped().Replace(group.GroupMembers)
txErr = tx.Model(&groupToUpdate).Association("GroupMembers").Unscoped().Replace(groupToUpdate.GroupMembers)
if txErr != nil {
return txErr
}
Expand Down Expand Up @@ -201,7 +233,7 @@ func (repository GroupRepository) GetGroupById(id string, preloadGroupMembers bo
}

func (repository GroupRepository) CreateAllGroup(userId uint) (models.Group, error) {
group := models.Group{
group := commands.UpsertGroupCommand{
Name: "All",
IsAllGroup: true,
}
Expand Down
5 changes: 3 additions & 2 deletions internal/repositories/groups_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package repositories

import (
"receipt-wrangler/api/internal/commands"
"receipt-wrangler/api/internal/models"
"receipt-wrangler/api/internal/utils"
"testing"
Expand All @@ -19,7 +20,7 @@ func teardownGroupTest() {
}

func TestShouldCreateGroupSuccessfully(t *testing.T) {
groupToCreate := models.Group{Name: "test"}
groupToCreate := commands.UpsertGroupCommand{Name: "test"}
setUpGroupTest()
groupRepository := setupGroupRepository()
createdGroup, err := groupRepository.CreateGroup(groupToCreate, 1)
Expand Down Expand Up @@ -98,7 +99,7 @@ func TestShouldReturnErrorIfGroupDoesNotExist(t *testing.T) {
func TestShouldUpdateGroup(t *testing.T) {
defer teardownGroupTest()
CreateTestGroup()
updateGroup := models.Group{Name: "new name", Status: models.GROUP_ARCHIVED}
updateGroup := commands.UpsertGroupCommand{Name: "new name", Status: models.GROUP_ARCHIVED}
groupRepository := setupGroupRepository()
updatedGroup, err := groupRepository.UpdateGroup(updateGroup, "1")

Expand Down
5 changes: 2 additions & 3 deletions internal/repositories/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,12 @@ func (repository UserRepository) CreateUser(userData commands.SignUpCommand) (mo
return err
}

group := models.Group{
groupCommand := commands.UpsertGroupCommand{
Name: "My Receipts",
IsDefaultGroup: true,
GroupSettings: models.GroupSettings{},
}

_, err := groupRepository.CreateGroup(group, user.ID)
_, err := groupRepository.CreateGroup(groupCommand, user.ID)
if err != nil {
repository.ClearTransaction()
return err
Expand Down
10 changes: 4 additions & 6 deletions internal/routers/group.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package routers

import (
"receipt-wrangler/api/internal/handlers"
"receipt-wrangler/api/internal/middleware"
"receipt-wrangler/api/internal/models"

jwtmiddleware "github.com/auth0/go-jwt-middleware/v2"
"github.com/go-chi/chi/v5"
"receipt-wrangler/api/internal/handlers"
"receipt-wrangler/api/internal/middleware"
)

func BuildGroupRouter(tokenValidator *jwtmiddleware.JWTMiddleware) *chi.Mux {
Expand All @@ -15,8 +13,8 @@ func BuildGroupRouter(tokenValidator *jwtmiddleware.JWTMiddleware) *chi.Mux {
groupRouter.Use(middleware.MoveJWTCookieToHeader, tokenValidator.CheckJWT)
groupRouter.Get("/", handlers.GetGroupsForUser)
groupRouter.Get("/{groupId}", handlers.GetGroupById)
groupRouter.With(middleware.SetGeneralBodyData("group", models.Group{})).Post("/", handlers.CreateGroup)
groupRouter.With(middleware.SetGeneralBodyData("group", models.Group{})).Put("/{groupId}", handlers.UpdateGroup)
groupRouter.Post("/", handlers.CreateGroup)
groupRouter.Put("/{groupId}", handlers.UpdateGroup)
groupRouter.Put("/{groupId}/groupSettings", handlers.UpdateGroupSettings)
groupRouter.With(middleware.CanDeleteGroup).Delete("/{groupId}", handlers.DeleteGroup)
groupRouter.Post("/{groupId}/pollGroupEmail", handlers.PollGroupEmail)
Expand Down
17 changes: 14 additions & 3 deletions internal/services/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package services

import (
"errors"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"os"
"receipt-wrangler/api/internal/models"
"receipt-wrangler/api/internal/repositories"
"receipt-wrangler/api/internal/simpleutils"

"gorm.io/gorm"
"gorm.io/gorm/clause"
)

type GroupService struct {
Expand Down Expand Up @@ -116,6 +116,17 @@ func (service GroupService) DeleteGroup(groupId string, allowAllGroupDelete bool
return txErr
}

// Remove group's directory
groupPath, txErr := simpleutils.BuildGroupPathString(simpleutils.UintToString(group.ID), group.Name)
if txErr != nil {
return txErr
}

txErr = os.Remove(groupPath)
if txErr != nil {
return txErr
}

return nil
})
if err != nil {
Expand Down
Loading