feat: завершён этап 3 - API структура Core Service

- Созданы репозитории для locations, items, operations
- Реализованы сервисы с бизнес-логикой
- Созданы HTTP handlers для всех API endpoints
- Добавлена функция GetClaims в middleware
- Обновлён server.go для интеграции всех компонентов
- Поддержка JSON полей в PostgreSQL
- Organization-scope фильтрация во всех операциях
- Валидация запросов через validator

Готово для этапа 4 - Шаблоны помещений
This commit is contained in:
2025-08-27 15:17:12 +04:00
parent 87595300b7
commit a846a2dce4
13 changed files with 1913 additions and 76 deletions

View File

@@ -0,0 +1,130 @@
package service
import (
"context"
"time"
"erp-mvp/core-service/internal/models"
"erp-mvp/core-service/internal/repository"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
)
type LocationService interface {
CreateLocation(ctx context.Context, orgID uuid.UUID, req *models.CreateLocationRequest) (*models.StorageLocation, error)
GetLocation(ctx context.Context, id uuid.UUID, orgID uuid.UUID) (*models.StorageLocation, error)
GetLocations(ctx context.Context, orgID uuid.UUID) ([]*models.StorageLocation, error)
UpdateLocation(ctx context.Context, id uuid.UUID, orgID uuid.UUID, req *models.CreateLocationRequest) (*models.StorageLocation, error)
DeleteLocation(ctx context.Context, id uuid.UUID, orgID uuid.UUID) error
GetChildren(ctx context.Context, parentID uuid.UUID, orgID uuid.UUID) ([]*models.StorageLocation, error)
}
type locationService struct {
locationRepo repository.LocationRepository
logger *logrus.Logger
}
func NewLocationService(locationRepo repository.LocationRepository) LocationService {
return &locationService{
locationRepo: locationRepo,
logger: logrus.New(),
}
}
func (s *locationService) CreateLocation(ctx context.Context, orgID uuid.UUID, req *models.CreateLocationRequest) (*models.StorageLocation, error) {
s.logger.Info("Creating location for organization: ", orgID)
location := &models.StorageLocation{
ID: uuid.New(),
OrganizationID: orgID,
ParentID: req.ParentID,
Name: req.Name,
Address: req.Address,
Type: req.Type,
Coordinates: req.Coordinates,
CreatedAt: time.Now(),
}
if err := s.locationRepo.Create(ctx, location); err != nil {
s.logger.Error("Failed to create location: ", err)
return nil, err
}
s.logger.Info("Location created successfully: ", location.ID)
return location, nil
}
func (s *locationService) GetLocation(ctx context.Context, id uuid.UUID, orgID uuid.UUID) (*models.StorageLocation, error) {
s.logger.Info("Getting location: ", id, " for organization: ", orgID)
location, err := s.locationRepo.GetByID(ctx, id, orgID)
if err != nil {
s.logger.Error("Failed to get location: ", err)
return nil, err
}
return location, nil
}
func (s *locationService) GetLocations(ctx context.Context, orgID uuid.UUID) ([]*models.StorageLocation, error) {
s.logger.Info("Getting all locations for organization: ", orgID)
locations, err := s.locationRepo.GetByOrganization(ctx, orgID)
if err != nil {
s.logger.Error("Failed to get locations: ", err)
return nil, err
}
return locations, nil
}
func (s *locationService) UpdateLocation(ctx context.Context, id uuid.UUID, orgID uuid.UUID, req *models.CreateLocationRequest) (*models.StorageLocation, error) {
s.logger.Info("Updating location: ", id, " for organization: ", orgID)
// Сначала получаем существующую локацию
location, err := s.locationRepo.GetByID(ctx, id, orgID)
if err != nil {
s.logger.Error("Failed to get location for update: ", err)
return nil, err
}
// Обновляем поля
location.ParentID = req.ParentID
location.Name = req.Name
location.Address = req.Address
location.Type = req.Type
location.Coordinates = req.Coordinates
if err := s.locationRepo.Update(ctx, location); err != nil {
s.logger.Error("Failed to update location: ", err)
return nil, err
}
s.logger.Info("Location updated successfully: ", location.ID)
return location, nil
}
func (s *locationService) DeleteLocation(ctx context.Context, id uuid.UUID, orgID uuid.UUID) error {
s.logger.Info("Deleting location: ", id, " for organization: ", orgID)
if err := s.locationRepo.Delete(ctx, id, orgID); err != nil {
s.logger.Error("Failed to delete location: ", err)
return err
}
s.logger.Info("Location deleted successfully: ", id)
return nil
}
func (s *locationService) GetChildren(ctx context.Context, parentID uuid.UUID, orgID uuid.UUID) ([]*models.StorageLocation, error) {
s.logger.Info("Getting children for location: ", parentID, " in organization: ", orgID)
children, err := s.locationRepo.GetChildren(ctx, parentID, orgID)
if err != nil {
s.logger.Error("Failed to get children: ", err)
return nil, err
}
return children, nil
}