Compare commits
2 Commits
cce7622ae1
...
feature/co
| Author | SHA1 | Date | |
|---|---|---|---|
| 87595300b7 | |||
| 0f93308c65 |
@@ -182,9 +182,9 @@ type ItemPlacement struct {
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Этап 2: Аутентификация (Неделя 2)
|
||||
## 🔐 Этап 2: Аутентификация (Неделя 2) ✅ ЗАВЕРШЁН
|
||||
|
||||
### Шаг 2.1: JWT аутентификация
|
||||
### Шаг 2.1: JWT аутентификация ✅
|
||||
- [x] Создать `internal/auth/jwt.go`
|
||||
- [x] Реализовать генерацию и валидацию JWT токенов
|
||||
- [x] Добавить organization-scope в токены
|
||||
@@ -201,12 +201,12 @@ type Claims struct {
|
||||
}
|
||||
```
|
||||
|
||||
### Шаг 2.2: Хеширование паролей
|
||||
### Шаг 2.2: Хеширование паролей ✅
|
||||
- [x] Создать `internal/auth/password.go`
|
||||
- [x] Использовать bcrypt для хеширования
|
||||
- [x] Добавить функции проверки паролей
|
||||
|
||||
### Шаг 2.3: API endpoints для аутентификации
|
||||
### Шаг 2.3: API endpoints для аутентификации ✅
|
||||
- [x] `POST /api/auth/register` - регистрация организации и пользователя
|
||||
- [x] `POST /api/auth/login` - вход в систему
|
||||
- [x] `POST /api/auth/refresh` - обновление токена (опционально)
|
||||
@@ -226,6 +226,13 @@ type LoginRequest struct {
|
||||
}
|
||||
```
|
||||
|
||||
**Результаты тестирования:**
|
||||
- ✅ Регистрация: `POST /api/auth/register` - 201 Created
|
||||
- ✅ Вход: `POST /api/auth/login` - 200 OK
|
||||
- ✅ Middleware: JWT токены проходят валидацию
|
||||
- ✅ JSON поля: исправлена конвертация в PostgreSQL
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Этап 3: API структура (Неделя 3)
|
||||
|
||||
@@ -90,9 +90,9 @@ type OrganizationResponse struct {
|
||||
|
||||
// LoginResponse ответ на аутентификацию
|
||||
type LoginResponse struct {
|
||||
Token string `json:"token"`
|
||||
User UserResponse `json:"user"`
|
||||
Organization OrganizationResponse `json:"organization"`
|
||||
Token string `json:"token"`
|
||||
User UserResponse `json:"user"`
|
||||
Organization OrganizationResponse `json:"organization"`
|
||||
}
|
||||
|
||||
// CreateLocationRequest запрос на создание места хранения
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"erp-mvp/core-service/internal/models"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
@@ -29,18 +30,18 @@ func (r *organizationRepository) Create(ctx context.Context, org *models.Organiz
|
||||
INSERT INTO organizations (id, name, type, settings, created_at)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
`
|
||||
|
||||
|
||||
// Конвертируем JSON в строку
|
||||
settingsJSON, err := json.Marshal(org.Settings)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal settings: %w", err)
|
||||
}
|
||||
|
||||
|
||||
_, err = r.db.ExecContext(ctx, query, org.ID, org.Name, org.Type, string(settingsJSON), org.CreatedAt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create organization: %w", err)
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -50,7 +51,7 @@ func (r *organizationRepository) GetByID(ctx context.Context, id uuid.UUID) (*mo
|
||||
FROM organizations
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
|
||||
var settingsJSON []byte
|
||||
org := &models.Organization{}
|
||||
err := r.db.QueryRowContext(ctx, query, id).Scan(
|
||||
@@ -60,14 +61,14 @@ func (r *organizationRepository) GetByID(ctx context.Context, id uuid.UUID) (*mo
|
||||
&settingsJSON,
|
||||
&org.CreatedAt,
|
||||
)
|
||||
|
||||
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, fmt.Errorf("organization not found")
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get organization: %w", err)
|
||||
}
|
||||
|
||||
|
||||
// Конвертируем JSON строку в map
|
||||
if len(settingsJSON) > 0 {
|
||||
err = json.Unmarshal(settingsJSON, &org.Settings)
|
||||
@@ -77,7 +78,7 @@ func (r *organizationRepository) GetByID(ctx context.Context, id uuid.UUID) (*mo
|
||||
} else {
|
||||
org.Settings = make(models.JSON)
|
||||
}
|
||||
|
||||
|
||||
return org, nil
|
||||
}
|
||||
|
||||
@@ -87,26 +88,26 @@ func (r *organizationRepository) Update(ctx context.Context, org *models.Organiz
|
||||
SET name = $2, type = $3, settings = $4
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
|
||||
// Конвертируем JSON в строку
|
||||
settingsJSON, err := json.Marshal(org.Settings)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal settings: %w", err)
|
||||
}
|
||||
|
||||
|
||||
result, err := r.db.ExecContext(ctx, query, org.ID, org.Name, org.Type, string(settingsJSON))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update organization: %w", err)
|
||||
}
|
||||
|
||||
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get rows affected: %w", err)
|
||||
}
|
||||
|
||||
|
||||
if rowsAffected == 0 {
|
||||
return fmt.Errorf("organization not found")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user