diff --git a/cmd/staffapp/main.go b/cmd/staffapp/main.go index 0d684245..6a3e15d1 100644 --- a/cmd/staffapp/main.go +++ b/cmd/staffapp/main.go @@ -1,15 +1,143 @@ package main import ( + "encoding/json" "fmt" "log" "net/http" + "strconv" + + "git.gocasts.ir/ebhomengo/niki/staffapp/repository/database" + "git.gocasts.ir/ebhomengo/niki/staffapp/service" ) func main() { - fmt.Println(" Staffapp Server Starting...") + + staffDb := database.New() + staffService := service.NewStaffService(staffDb) + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Staffapp OK!") }) + + http.HandleFunc("/staff", func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + var newStaff service.Staff + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(&newStaff) + if err != nil { + http.Error(w, "Invalid request payload: "+err.Error(), http.StatusBadRequest) + return + } + defer r.Body.Close() + + createdStaff, err := staffService.RegisterStaff(newStaff.Name, newStaff.LastName, newStaff.PhoneNumber) + if err != nil { + http.Error(w, "Failed to register staff: "+err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + json.NewEncoder(w).Encode(createdStaff) + }) + + http.HandleFunc("/staff/", func(w http.ResponseWriter, r *http.Request) { + + idStr := r.URL.Path[len("/staff/"):] + if idStr == "" { + http.Error(w, "Missing staff ID", http.StatusBadRequest) + return + } + + id, err := strconv.Atoi(idStr) + if err != nil { + http.Error(w, "Invalid staff ID format", http.StatusBadRequest) + return + } + + switch r.Method { + case http.MethodGet: + + st, err := staffService.Get(id) + if err != nil { + + if err.Error() == "staff not found" { + http.Error(w, "Staff not found", http.StatusNotFound) + } else { + http.Error(w, "Failed to fetch staff: "+err.Error(), http.StatusInternalServerError) + } + return + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(st) + + case http.MethodPut: + + var staffData struct { + Name string `json:"Name"` + LastName string `json:"LastName"` + PhoneNumber string `json:"PhoneNumber"` + } + decoder := json.NewDecoder(r.Body) + if err := decoder.Decode(&staffData); err != nil { + http.Error(w, "Invalid request payload: "+err.Error(), http.StatusBadRequest) + return + } + defer r.Body.Close() + + updatedStaff, err := staffService.Update(id, staffData.Name, staffData.LastName, staffData.PhoneNumber) + if err != nil { + + if err.Error() == "staff not found" { + http.Error(w, "Staff not found", http.StatusNotFound) + } else { + http.Error(w, "Failed to update staff: "+err.Error(), http.StatusInternalServerError) + } + return + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(updatedStaff) + + case http.MethodDelete: + + err = staffService.Remove(id) + if err != nil { + if err.Error() == "staff not found" { + http.Error(w, "Staff not found", http.StatusNotFound) + } else { + http.Error(w, "Failed to remove staff: "+err.Error(), http.StatusInternalServerError) + } + return + } + w.WriteHeader(http.StatusNoContent) + + default: + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + } + }) + + http.HandleFunc("/staffs", func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + list, err := staffService.List() + if err != nil { + http.Error(w, "Failed to fetch staff list: "+err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(list) + }) + log.Fatal(http.ListenAndServe(":8080", nil)) } diff --git a/staffapp/repository/database/db.go b/staffapp/repository/database/db.go index 5d07c611..c1d2a621 100644 --- a/staffapp/repository/database/db.go +++ b/staffapp/repository/database/db.go @@ -1,13 +1,64 @@ package database -import "git.gocasts.ir/ebhomengo/niki/repository/mysql" +import ( + "fmt" + + "git.gocasts.ir/ebhomengo/niki/staffapp/service" +) type DB struct { - conn *mysql.DB + staffs []service.Staff + nextID int } -func New(conn *mysql.DB) *DB { +func New() service.StaffRepository { return &DB{ - conn: conn, + staffs: []service.Staff{}, + nextID: 1, } } + +func (d *DB) Create(staff service.Staff) (service.Staff, error) { + staff.ID = d.nextID + d.staffs = append(d.staffs, staff) + d.nextID++ + return staff, nil +} + +func (d *DB) Get(id int) (*service.Staff, error) { + for _, v := range d.staffs { + if id == v.ID { + return &v, nil + } + + } + + return nil, fmt.Errorf("The user not found with id = %d", id) +} + +func (d *DB) List() ([]service.Staff, error) { + return d.staffs, nil +} +func (d *DB) Remove(id int) error { + for _, v := range d.staffs { + if id == v.ID { + d.staffs = append(d.staffs[:id], d.staffs[id+1:]...) + return nil + } + + } + return fmt.Errorf("User with ID: %d notfound", id) +} +func (d *DB) Update(id int, name, lastName, phoneNumber string) (*service.Staff, error) { + for _, v := range d.staffs { + if id == v.ID { + v.Name = name + v.LastName = lastName + v.PhoneNumber = phoneNumber + + return &v, nil + } + + } + return nil, fmt.Errorf("User with this Id(%d)couldn't found for updating", id) +} diff --git a/staffapp/service/entity.go b/staffapp/service/entity.go deleted file mode 100644 index f728dd56..00000000 --- a/staffapp/service/entity.go +++ /dev/null @@ -1,13 +0,0 @@ -package service - -type Staff struct { - ID int - Name string - LastName string - PhoneNumber string -} - -type StaffService struct { - Staffs []Staff - NextID int -} diff --git a/staffapp/service/repository.go b/staffapp/service/repository.go new file mode 100644 index 00000000..5781858b --- /dev/null +++ b/staffapp/service/repository.go @@ -0,0 +1,15 @@ +package service + +type Staff struct { + ID int + Name string + LastName string + PhoneNumber string +} +type StaffRepository interface { + Create(staff Staff) (Staff, error) + Get(id int) (*Staff, error) + List() ([]Staff, error) + Remove(id int) error + Update(id int, name, lastName, phoneNumber string) (*Staff, error) +} diff --git a/staffapp/service/service.go b/staffapp/service/service.go index 20b75894..d78e7b06 100644 --- a/staffapp/service/service.go +++ b/staffapp/service/service.go @@ -1,49 +1,44 @@ package service import ( - "errors" "fmt" ) -func (s *StaffService) RegisterStaff(id int, name string, lastname string, phonenumber string) (Staff, error) { +type StaffService struct { + repo StaffRepository +} - for _, staff := range s.Staffs { - if staff.PhoneNumber == phonenumber { - return Staff{}, errors.New("This number is already in use") - } +func NewStaffService(repo StaffRepository) *StaffService { + return &StaffService{ + repo: repo, } +} - newID := s.NextID - s.NextID++ - +func (s *StaffService) RegisterStaff(name, lastname, phone string) (Staff, error) { newStaff := Staff{ - ID: newID, Name: name, LastName: lastname, - PhoneNumber: phonenumber, + PhoneNumber: phone, } - s.Staffs = append(s.Staffs, newStaff) - return newStaff, nil + createdStaff, err := s.repo.Create(newStaff) + if err != nil { + return Staff{}, fmt.Errorf("Error in registring staff%w", err) + } + return createdStaff, nil } -func (s *StaffService) DeleteStaff(phoneNumber string) { - for i, n := range s.Staffs { - if phoneNumber == n.PhoneNumber { - s.Staffs = append(s.Staffs[:i], s.Staffs[i+1:]...) - } - } +func (s *StaffService) Get(id int) (*Staff, error) { + return s.repo.Get(id) } -func (s *StaffService) ListStaff() []Staff { - return s.Staffs +func (s *StaffService) List() ([]Staff, error) { + return s.repo.List() } -func (s *StaffService) PrintStaffs() { - if len(s.Staffs) == 0 { - fmt.Println("There is no staff yet") - } - for _, staff := range s.Staffs { - fmt.Printf("ID: %d, Name:%s %s,Phone number:%s", staff.ID, staff.Name, staff.LastName, staff.PhoneNumber) - } - +func (s *StaffService) Remove(id int) error { + return s.repo.Remove(id) +} + +func (s *StaffService) Update(id int, name, lastName, phoneNumber string) (*Staff, error) { + return s.repo.Update(id, name, lastName, phoneNumber) }