diff --git a/backend/docs/docs.go b/backend/docs/docs.go index c147337..5633619 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -1587,7 +1587,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/auth.authRequest" + "$ref": "#/definitions/auth.loginRequest" } } ], @@ -1700,7 +1700,7 @@ const docTemplate = `{ }, "/auth/register": { "post": { - "description": "Register a new user (defaults to 'profissional' role) with email and password", + "description": "Register a new user (defaults to 'profissional' role) with email, password, name and phone", "consumes": [ "application/json" ], @@ -1718,7 +1718,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/auth.authRequest" + "$ref": "#/definitions/auth.registerRequest" } } ], @@ -1778,7 +1778,7 @@ const docTemplate = `{ } } }, - "auth.authRequest": { + "auth.loginRequest": { "type": "object", "required": [ "email", @@ -1809,9 +1809,35 @@ const docTemplate = `{ } } }, + "auth.registerRequest": { + "type": "object", + "required": [ + "email", + "nome", + "senha" + ], + "properties": { + "email": { + "type": "string" + }, + "nome": { + "type": "string" + }, + "senha": { + "type": "string", + "minLength": 6 + }, + "telefone": { + "type": "string" + } + } + }, "auth.userResponse": { "type": "object", "properties": { + "ativo": { + "type": "boolean" + }, "email": { "type": "string" }, diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index a8b1202..49bd2ba 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -1581,7 +1581,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/auth.authRequest" + "$ref": "#/definitions/auth.loginRequest" } } ], @@ -1694,7 +1694,7 @@ }, "/auth/register": { "post": { - "description": "Register a new user (defaults to 'profissional' role) with email and password", + "description": "Register a new user (defaults to 'profissional' role) with email, password, name and phone", "consumes": [ "application/json" ], @@ -1712,7 +1712,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/auth.authRequest" + "$ref": "#/definitions/auth.registerRequest" } } ], @@ -1772,7 +1772,7 @@ } } }, - "auth.authRequest": { + "auth.loginRequest": { "type": "object", "required": [ "email", @@ -1803,9 +1803,35 @@ } } }, + "auth.registerRequest": { + "type": "object", + "required": [ + "email", + "nome", + "senha" + ], + "properties": { + "email": { + "type": "string" + }, + "nome": { + "type": "string" + }, + "senha": { + "type": "string", + "minLength": 6 + }, + "telefone": { + "type": "string" + } + } + }, "auth.userResponse": { "type": "object", "properties": { + "ativo": { + "type": "boolean" + }, "email": { "type": "string" }, diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index b7564d5..5fdafb0 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -15,7 +15,7 @@ definitions: required: - ano_semestre type: object - auth.authRequest: + auth.loginRequest: properties: email: type: string @@ -36,8 +36,26 @@ definitions: user: $ref: '#/definitions/auth.userResponse' type: object + auth.registerRequest: + properties: + email: + type: string + nome: + type: string + senha: + minLength: 6 + type: string + telefone: + type: string + required: + - email + - nome + - senha + type: object auth.userResponse: properties: + ativo: + type: boolean email: type: string id: @@ -1338,7 +1356,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/auth.authRequest' + $ref: '#/definitions/auth.loginRequest' produces: - application/json responses: @@ -1416,15 +1434,15 @@ paths: post: consumes: - application/json - description: Register a new user (defaults to 'profissional' role) with email - and password + description: Register a new user (defaults to 'profissional' role) with email, + password, name and phone parameters: - description: Register Request in: body name: request required: true schema: - $ref: '#/definitions/auth.authRequest' + $ref: '#/definitions/auth.registerRequest' produces: - application/json responses: diff --git a/backend/internal/auth/handler.go b/backend/internal/auth/handler.go index c30057f..74d204a 100644 --- a/backend/internal/auth/handler.go +++ b/backend/internal/auth/handler.go @@ -18,32 +18,40 @@ func NewHandler(service *Service) *Handler { return &Handler{service: service} } -type authRequest struct { - Email string `json:"email" binding:"required,email"` - Senha string `json:"senha" binding:"required,min=6"` +type registerRequest struct { + Email string `json:"email" binding:"required,email"` + Senha string `json:"senha" binding:"required,min=6"` + Nome string `json:"nome" binding:"required"` + Telefone string `json:"telefone"` } // Register godoc // @Summary Register a new user -// @Description Register a new user (defaults to 'profissional' role) with email and password +// @Description Register a new user (defaults to 'profissional' role) with email, password, name and phone // @Tags auth // @Accept json // @Produce json -// @Param request body authRequest true "Register Request" +// @Param request body registerRequest true "Register Request" // @Success 201 {object} map[string]string // @Failure 400 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /auth/register [post] func (h *Handler) Register(c *gin.Context) { - var req authRequest + var req registerRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - // Default simplified registration: Role="profissional", No professional data yet + // Default simplified registration: Role="profissional" role := "profissional" - var profData *profissionais.CreateProfissionalInput = nil + + // Create professional data from input + profData := &profissionais.CreateProfissionalInput{ + Nome: req.Nome, + Whatsapp: &req.Telefone, // Map Telefone to Whatsapp + // FuncaoProfissionalID is left empty intentionally + } _, err := h.service.Register(c.Request.Context(), req.Email, req.Senha, role, profData) if err != nil { @@ -58,6 +66,11 @@ func (h *Handler) Register(c *gin.Context) { c.JSON(http.StatusCreated, gin.H{"message": "user created"}) } +type loginRequest struct { + Email string `json:"email" binding:"required,email"` + Senha string `json:"senha" binding:"required,min=6"` +} + type loginResponse struct { AccessToken string `json:"access_token"` ExpiresAt string `json:"expires_at"` @@ -69,6 +82,7 @@ type userResponse struct { ID string `json:"id"` Email string `json:"email"` Role string `json:"role"` + Ativo bool `json:"ativo"` } // Login godoc @@ -77,13 +91,13 @@ type userResponse struct { // @Tags auth // @Accept json // @Produce json -// @Param request body authRequest true "Login Request" +// @Param request body loginRequest true "Login Request" // @Success 200 {object} loginResponse // @Failure 401 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /auth/login [post] func (h *Handler) Login(c *gin.Context) { - var req authRequest + var req loginRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return @@ -112,6 +126,7 @@ func (h *Handler) Login(c *gin.Context) { ID: uuid.UUID(user.ID.Bytes).String(), Email: user.Email, Role: user.Role, + Ativo: user.Ativo, }, } diff --git a/backend/internal/db/generated/usuarios.sql.go b/backend/internal/db/generated/usuarios.sql.go index 21f3252..049ce2e 100644 --- a/backend/internal/db/generated/usuarios.sql.go +++ b/backend/internal/db/generated/usuarios.sql.go @@ -12,8 +12,8 @@ import ( ) const createUsuario = `-- name: CreateUsuario :one -INSERT INTO usuarios (email, senha_hash, role) -VALUES ($1, $2, $3) +INSERT INTO usuarios (email, senha_hash, role, ativo) +VALUES ($1, $2, $3, false) RETURNING id, email, senha_hash, role, ativo, criado_em, atualizado_em ` diff --git a/backend/internal/db/queries/usuarios.sql b/backend/internal/db/queries/usuarios.sql index bb8e1f2..fec0628 100644 --- a/backend/internal/db/queries/usuarios.sql +++ b/backend/internal/db/queries/usuarios.sql @@ -1,6 +1,6 @@ -- name: CreateUsuario :one -INSERT INTO usuarios (email, senha_hash, role) -VALUES ($1, $2, $3) +INSERT INTO usuarios (email, senha_hash, role, ativo) +VALUES ($1, $2, $3, false) RETURNING *; -- name: GetUsuarioByEmail :one diff --git a/backend/internal/db/schema.sql b/backend/internal/db/schema.sql index 01e743d..cba3a31 100644 --- a/backend/internal/db/schema.sql +++ b/backend/internal/db/schema.sql @@ -5,7 +5,7 @@ CREATE TABLE IF NOT EXISTS usuarios ( email VARCHAR(255) UNIQUE NOT NULL, senha_hash VARCHAR(255) NOT NULL, role VARCHAR(50) NOT NULL DEFAULT 'profissional', - ativo BOOLEAN NOT NULL DEFAULT TRUE, + ativo BOOLEAN NOT NULL DEFAULT FALSE, criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW(), atualizado_em TIMESTAMPTZ NOT NULL DEFAULT NOW() ); diff --git a/backend/internal/profissionais/service.go b/backend/internal/profissionais/service.go index 5ca31ee..5d4f2d9 100644 --- a/backend/internal/profissionais/service.go +++ b/backend/internal/profissionais/service.go @@ -50,15 +50,23 @@ func (s *Service) Create(ctx context.Context, userID string, input CreateProfiss return nil, errors.New("invalid usuario_id from context") } - funcaoUUID, err := uuid.Parse(input.FuncaoProfissionalID) - if err != nil { - return nil, errors.New("invalid funcao_profissional_id") + var funcaoUUID uuid.UUID + var funcaoValid bool + if input.FuncaoProfissionalID != "" { + parsed, err := uuid.Parse(input.FuncaoProfissionalID) + if err != nil { + return nil, errors.New("invalid funcao_profissional_id") + } + funcaoUUID = parsed + funcaoValid = true + } else { + funcaoValid = false } params := generated.CreateProfissionalParams{ UsuarioID: pgtype.UUID{Bytes: usuarioUUID, Valid: true}, Nome: input.Nome, - FuncaoProfissionalID: pgtype.UUID{Bytes: funcaoUUID, Valid: true}, + FuncaoProfissionalID: pgtype.UUID{Bytes: funcaoUUID, Valid: funcaoValid}, Endereco: toPgText(input.Endereco), Cidade: toPgText(input.Cidade), Uf: toPgText(input.Uf),