200 lines
5.9 KiB
Go
200 lines
5.9 KiB
Go
package accounts
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"ruben/inventory2/internal/consts"
|
|
"ruben/inventory2/internal/domains/accounts"
|
|
"ruben/inventory2/internal/logging"
|
|
"ruben/inventory2/internal/server/middleware"
|
|
"ruben/inventory2/internal/server/response"
|
|
"ruben/inventory2/internal/server/sse"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type accountSubrouter struct {
|
|
log *logging.Logger
|
|
accts *accounts.Store
|
|
}
|
|
|
|
func Routes(
|
|
r *gin.RouterGroup,
|
|
logger *logging.Logger,
|
|
accts *accounts.Store,
|
|
pub *sse.UpdateNotificationPublisher,
|
|
) {
|
|
as := &accountSubrouter{
|
|
log: logger,
|
|
accts: accts,
|
|
}
|
|
|
|
syncGroups := r.Group("/:acctID/inventory/sync-groups")
|
|
syncGroups.POST("", response.Handler(as.saveNewSyncGroup))
|
|
|
|
draftListings := syncGroups.Group("/draft/listings", pub.Publish("/:acctID/inventory/sync-groups/draft/listings"))
|
|
draftListings.POST("", response.Handler(as.createSyncGroupListingDraft))
|
|
draftListings.PUT("/:orderIndex/shop", response.Handler(as.setShopInSyncGroupListingDraft))
|
|
draftListings.PUT("/:orderIndex/listing", response.Handler(as.setListingInSyncGroupListingDraft))
|
|
draftListings.DELETE("/:orderIndex", response.Handler(as.deleteSyncGroupListingDraft))
|
|
}
|
|
|
|
// POST /api/accounts
|
|
func (s *accountSubrouter) createAccount(c *gin.Context) (response.Response, error) {
|
|
r := c.Request
|
|
ctx := r.Context()
|
|
email := r.FormValue("email")
|
|
if email == "" {
|
|
return nil, response.BadRequest().Msg("no email provided")
|
|
}
|
|
|
|
userID := middleware.GetIdentity(ctx).User.UserID
|
|
|
|
acct, err := s.accts.CreateAccount(ctx, userID, email)
|
|
if err != nil {
|
|
if errors.Is(err, consts.ErrConflict) {
|
|
return nil, response.Conflict().
|
|
Msg("user already has an account")
|
|
}
|
|
return nil, response.Errorf("failed to create account: %w", err)
|
|
}
|
|
|
|
return response.SeeOther(fmt.Sprintf("/api/accounts/%d", acct.AccountID)), nil
|
|
}
|
|
|
|
// POST /api/accounts/{acctID}/inventory/sync-groups/draft/listings
|
|
func (s *accountSubrouter) createSyncGroupListingDraft(c *gin.Context) (response.Response, error) {
|
|
r := c.Request
|
|
ctx := r.Context()
|
|
acctID := middleware.GetIdentity(ctx).Account.AccountID
|
|
|
|
if _, err := s.accts.CreateSyncGroupListingDraft(ctx, acctID); err != nil {
|
|
return nil, response.Errorf("failed to create new listing draft: %w", err)
|
|
}
|
|
|
|
return response.Redirect(
|
|
http.StatusSeeOther,
|
|
fmt.Sprintf("/ui/accounts/%d/inventory/sync-groups/draft/table", acctID),
|
|
), nil
|
|
}
|
|
|
|
// PUT /api/accounts/{acctID}/inventory/sync-groups/draft/listings/{orderIndex}/shop
|
|
// @platform string
|
|
// @shopID string
|
|
func (s *accountSubrouter) setShopInSyncGroupListingDraft(c *gin.Context) (response.Response, error) {
|
|
r := c.Request
|
|
ctx := r.Context()
|
|
acctID := middleware.GetIdentity(ctx).Account.AccountID
|
|
|
|
orderIndex, err := getOrderIndexForSyncGroupListingDraftFromPath(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
platformStr := r.FormValue("platform")
|
|
platform, err := accounts.NewPlatform(platformStr)
|
|
if err != nil {
|
|
return nil, response.BadRequest().
|
|
Msgf("unrecognized platform: %s", platformStr)
|
|
}
|
|
|
|
shopID := r.FormValue("shop-id")
|
|
if shopID == "" {
|
|
return nil, response.BadRequest().
|
|
Msg("no shop-id provided")
|
|
}
|
|
|
|
if err := s.accts.SetShopInSyncGroupListingDraft(ctx, acctID, orderIndex, platform, shopID); err != nil {
|
|
return nil, response.Errorf("failed to set shop: %w", response.ErrorFromConstant(err))
|
|
}
|
|
|
|
return response.Redirect(
|
|
http.StatusSeeOther,
|
|
fmt.Sprintf("/ui/accounts/%d/inventory/sync-groups/draft/table", acctID),
|
|
), nil
|
|
}
|
|
|
|
// PUT /api/accounts/{acctID}/inventory/sync-groups/draft/listings/{orderIndex}/listing
|
|
func (s *accountSubrouter) setListingInSyncGroupListingDraft(c *gin.Context) (response.Response, error) {
|
|
r := c.Request
|
|
ctx := r.Context()
|
|
acctID := middleware.GetIdentity(ctx).Account.AccountID
|
|
|
|
orderIndex, err := getOrderIndexForSyncGroupListingDraftFromPath(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
listingID := r.FormValue("listing-id")
|
|
if listingID == "" {
|
|
return nil, response.BadRequest().
|
|
Msg("no listing-id provided")
|
|
}
|
|
|
|
if err := s.accts.SetListingInSyncGroupListingDraft(ctx, acctID, orderIndex, listingID); err != nil {
|
|
return nil, response.Errorf("failed to set listing: %w", response.ErrorFromConstant(err))
|
|
}
|
|
|
|
return response.Redirect(
|
|
http.StatusSeeOther,
|
|
fmt.Sprintf("/ui/accounts/%d/inventory/sync-groups/draft/table", acctID),
|
|
), nil
|
|
}
|
|
|
|
// DELETE /api/accounts/{acctID}/inventory/sync-groups/draft/listings/{orderIndex}
|
|
func (s *accountSubrouter) deleteSyncGroupListingDraft(c *gin.Context) (response.Response, error) {
|
|
r := c.Request
|
|
ctx := r.Context()
|
|
acctID := middleware.GetIdentity(ctx).Account.AccountID
|
|
|
|
orderIndex, err := getOrderIndexForSyncGroupListingDraftFromPath(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if _, err := s.accts.DeleteSyncGroupListingDraft(ctx, acctID, orderIndex); err != nil {
|
|
return nil, response.Errorf("failed to delete listing: %w", response.ErrorFromConstant(err))
|
|
}
|
|
|
|
return response.Redirect(
|
|
http.StatusSeeOther,
|
|
fmt.Sprintf("/ui/accounts/%d/inventory/sync-groups/draft/table", acctID),
|
|
), nil
|
|
}
|
|
|
|
// POST /api/accounts/{acctID}/inventory/sync-groups
|
|
func (s *accountSubrouter) saveNewSyncGroup(c *gin.Context) (response.Response, error) {
|
|
r := c.Request
|
|
ctx := r.Context()
|
|
acctID := middleware.GetIdentity(ctx).Account.AccountID
|
|
|
|
grp, err := s.accts.SaveNewSyncGroup(ctx, acctID)
|
|
if err != nil {
|
|
return nil, response.Errorf("failed to save new sync group: %w", response.ErrorFromConstant(err))
|
|
}
|
|
|
|
return response.Redirect(
|
|
http.StatusSeeOther,
|
|
// TODO: template not implemented
|
|
fmt.Sprintf("/ui/accounts/%d/inventory/sync-groups/%d", acctID, grp.SyncGroupID),
|
|
), nil
|
|
}
|
|
|
|
func getOrderIndexForSyncGroupListingDraftFromPath(c *gin.Context) (int, error) {
|
|
orderIndexStr := c.Param("orderIndex")
|
|
if orderIndexStr == "" {
|
|
return 0, response.NotFound().
|
|
Msg("no orderIndex found")
|
|
}
|
|
|
|
orderIndex, err := strconv.Atoi(orderIndexStr)
|
|
if err != nil {
|
|
return 0, response.NotFound().
|
|
Msgf("invalid order index: %s", orderIndexStr)
|
|
}
|
|
|
|
return orderIndex, nil
|
|
}
|