feat(backend): implementa módulo Agenda com lógica automática de status
- Cria tabela 'agenda' com FKs normalizadas e colunas específicas de evento - Gera operações CRUD via SQLC para Agenda - Implementa Service e Handler da Agenda - Adiciona cálculo automático de 'status_profissionais' (OK/FALTA/ERRO) baseado na contagem de faltantes - Registra rotas da Agenda em /api/agenda - Atualiza documentação Swagger - Corrige caminhos de importação e tipagem UUID no novo serviço
This commit is contained in:
parent
d84d6ff022
commit
a1a4d0a5d1
11 changed files with 1764 additions and 0 deletions
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"photum-backend/docs"
|
"photum-backend/docs"
|
||||||
|
"photum-backend/internal/agenda"
|
||||||
"photum-backend/internal/anos_formaturas"
|
"photum-backend/internal/anos_formaturas"
|
||||||
"photum-backend/internal/auth"
|
"photum-backend/internal/auth"
|
||||||
"photum-backend/internal/cadastro_fot"
|
"photum-backend/internal/cadastro_fot"
|
||||||
|
|
@ -68,6 +69,7 @@ func main() {
|
||||||
tiposServicosService := tipos_servicos.NewService(queries)
|
tiposServicosService := tipos_servicos.NewService(queries)
|
||||||
tiposEventosService := tipos_eventos.NewService(queries)
|
tiposEventosService := tipos_eventos.NewService(queries)
|
||||||
cadastroFotService := cadastro_fot.NewService(queries)
|
cadastroFotService := cadastro_fot.NewService(queries)
|
||||||
|
agendaService := agenda.NewService(queries)
|
||||||
|
|
||||||
// Seed Demo Users
|
// Seed Demo Users
|
||||||
if err := authService.EnsureDemoUsers(context.Background()); err != nil {
|
if err := authService.EnsureDemoUsers(context.Background()); err != nil {
|
||||||
|
|
@ -84,6 +86,7 @@ func main() {
|
||||||
tiposServicosHandler := tipos_servicos.NewHandler(tiposServicosService)
|
tiposServicosHandler := tipos_servicos.NewHandler(tiposServicosService)
|
||||||
tiposEventosHandler := tipos_eventos.NewHandler(tiposEventosService)
|
tiposEventosHandler := tipos_eventos.NewHandler(tiposEventosService)
|
||||||
cadastroFotHandler := cadastro_fot.NewHandler(cadastroFotService)
|
cadastroFotHandler := cadastro_fot.NewHandler(cadastroFotService)
|
||||||
|
agendaHandler := agenda.NewHandler(agendaService)
|
||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
|
|
@ -182,6 +185,12 @@ func main() {
|
||||||
api.PUT("/cadastro-fot/:id", cadastroFotHandler.Update)
|
api.PUT("/cadastro-fot/:id", cadastroFotHandler.Update)
|
||||||
api.DELETE("/cadastro-fot/:id", cadastroFotHandler.Delete)
|
api.DELETE("/cadastro-fot/:id", cadastroFotHandler.Delete)
|
||||||
|
|
||||||
|
api.GET("/agenda", agendaHandler.List)
|
||||||
|
api.POST("/agenda", agendaHandler.Create)
|
||||||
|
api.GET("/agenda/:id", agendaHandler.Get)
|
||||||
|
api.PUT("/agenda/:id", agendaHandler.Update)
|
||||||
|
api.DELETE("/agenda/:id", agendaHandler.Delete)
|
||||||
|
|
||||||
admin := api.Group("/admin")
|
admin := api.Group("/admin")
|
||||||
{
|
{
|
||||||
admin.GET("/users", authHandler.ListUsers)
|
admin.GET("/users", authHandler.ListUsers)
|
||||||
|
|
|
||||||
|
|
@ -410,6 +410,247 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/agenda": {
|
||||||
|
"get": {
|
||||||
|
"description": "List all agenda events with details",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "List all agenda events",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"description": "Create a new agenda event",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "Create a new agenda event",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Create Agenda Request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/agenda.CreateAgendaRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Created",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/agenda/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Get agenda event details by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "Get agenda event by ID",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Agenda ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"description": "Update agenda event by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "Update agenda event",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Agenda ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Update Agenda Request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/agenda.CreateAgendaRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"description": "Delete agenda event by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "Delete agenda event",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Agenda ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/anos-formaturas": {
|
"/api/anos-formaturas": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
|
|
@ -2164,6 +2405,80 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
"agenda.CreateAgendaRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cine_faltante": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"data_evento": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"endereco": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fot_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"foto_faltante": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"horario": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"local_evento": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"logistica_observacoes": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"observacoes_evento": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"pre_venda": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"qtd_cinegrafistas": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_estudios": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_formandos": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_fotografos": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_plataforma_360": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_ponto_decorado": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_ponto_foto": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_ponto_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_pontos_led": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_recepcionistas": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"recep_faltante": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"status_profissionais": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"tipo_evento_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"anos_formaturas.AnoFormaturaResponse": {
|
"anos_formaturas.AnoFormaturaResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -404,6 +404,247 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/agenda": {
|
||||||
|
"get": {
|
||||||
|
"description": "List all agenda events with details",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "List all agenda events",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"description": "Create a new agenda event",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "Create a new agenda event",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Create Agenda Request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/agenda.CreateAgendaRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Created",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/agenda/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Get agenda event details by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "Get agenda event by ID",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Agenda ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"description": "Update agenda event by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "Update agenda event",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Agenda ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Update Agenda Request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/agenda.CreateAgendaRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"description": "Delete agenda event by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"agenda"
|
||||||
|
],
|
||||||
|
"summary": "Delete agenda event",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Agenda ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/anos-formaturas": {
|
"/api/anos-formaturas": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
|
|
@ -2158,6 +2399,80 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
"agenda.CreateAgendaRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cine_faltante": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"data_evento": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"endereco": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fot_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"foto_faltante": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"horario": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"local_evento": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"logistica_observacoes": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"observacoes_evento": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"pre_venda": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"qtd_cinegrafistas": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_estudios": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_formandos": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_fotografos": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_plataforma_360": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_ponto_decorado": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_ponto_foto": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_ponto_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_pontos_led": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"qtd_recepcionistas": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"recep_faltante": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"status_profissionais": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"tipo_evento_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"anos_formaturas.AnoFormaturaResponse": {
|
"anos_formaturas.AnoFormaturaResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,54 @@
|
||||||
basePath: /
|
basePath: /
|
||||||
definitions:
|
definitions:
|
||||||
|
agenda.CreateAgendaRequest:
|
||||||
|
properties:
|
||||||
|
cine_faltante:
|
||||||
|
type: integer
|
||||||
|
data_evento:
|
||||||
|
type: string
|
||||||
|
endereco:
|
||||||
|
type: string
|
||||||
|
fot_id:
|
||||||
|
type: string
|
||||||
|
foto_faltante:
|
||||||
|
type: integer
|
||||||
|
horario:
|
||||||
|
type: string
|
||||||
|
local_evento:
|
||||||
|
type: string
|
||||||
|
logistica_observacoes:
|
||||||
|
type: string
|
||||||
|
observacoes_evento:
|
||||||
|
type: string
|
||||||
|
pre_venda:
|
||||||
|
type: boolean
|
||||||
|
qtd_cinegrafistas:
|
||||||
|
type: integer
|
||||||
|
qtd_estudios:
|
||||||
|
type: integer
|
||||||
|
qtd_formandos:
|
||||||
|
type: integer
|
||||||
|
qtd_fotografos:
|
||||||
|
type: integer
|
||||||
|
qtd_plataforma_360:
|
||||||
|
type: integer
|
||||||
|
qtd_ponto_decorado:
|
||||||
|
type: integer
|
||||||
|
qtd_ponto_foto:
|
||||||
|
type: integer
|
||||||
|
qtd_ponto_id:
|
||||||
|
type: integer
|
||||||
|
qtd_pontos_led:
|
||||||
|
type: integer
|
||||||
|
qtd_recepcionistas:
|
||||||
|
type: integer
|
||||||
|
recep_faltante:
|
||||||
|
type: integer
|
||||||
|
status_profissionais:
|
||||||
|
type: string
|
||||||
|
tipo_evento_id:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
anos_formaturas.AnoFormaturaResponse:
|
anos_formaturas.AnoFormaturaResponse:
|
||||||
properties:
|
properties:
|
||||||
ano_semestre:
|
ano_semestre:
|
||||||
|
|
@ -650,6 +699,167 @@ paths:
|
||||||
summary: List pending users
|
summary: List pending users
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
/api/agenda:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: List all agenda events with details
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
summary: List all agenda events
|
||||||
|
tags:
|
||||||
|
- agenda
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Create a new agenda event
|
||||||
|
parameters:
|
||||||
|
- description: Create Agenda Request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/agenda.CreateAgendaRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Created
|
||||||
|
schema:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
summary: Create a new agenda event
|
||||||
|
tags:
|
||||||
|
- agenda
|
||||||
|
/api/agenda/{id}:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Delete agenda event by ID
|
||||||
|
parameters:
|
||||||
|
- description: Agenda ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: No Content
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
summary: Delete agenda event
|
||||||
|
tags:
|
||||||
|
- agenda
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Get agenda event details by ID
|
||||||
|
parameters:
|
||||||
|
- description: Agenda ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
summary: Get agenda event by ID
|
||||||
|
tags:
|
||||||
|
- agenda
|
||||||
|
put:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Update agenda event by ID
|
||||||
|
parameters:
|
||||||
|
- description: Agenda ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: Update Agenda Request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/agenda.CreateAgendaRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
summary: Update agenda event
|
||||||
|
tags:
|
||||||
|
- agenda
|
||||||
/api/anos-formaturas:
|
/api/anos-formaturas:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
|
||||||
152
backend/internal/agenda/handler.go
Normal file
152
backend/internal/agenda/handler.go
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
package agenda
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Handler struct {
|
||||||
|
service *Service
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHandler(service *Service) *Handler {
|
||||||
|
return &Handler{service: service}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create godoc
|
||||||
|
// @Summary Create a new agenda event
|
||||||
|
// @Description Create a new agenda event
|
||||||
|
// @Tags agenda
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param request body CreateAgendaRequest true "Create Agenda Request"
|
||||||
|
// @Success 201 {object} map[string]interface{}
|
||||||
|
// @Failure 400 {object} map[string]string
|
||||||
|
// @Failure 500 {object} map[string]string
|
||||||
|
// @Router /api/agenda [post]
|
||||||
|
func (h *Handler) Create(c *gin.Context) {
|
||||||
|
var req CreateAgendaRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Dados inválidos: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
agenda, err := h.service.Create(c.Request.Context(), req)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erro ao criar agenda: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusCreated, agenda)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List godoc
|
||||||
|
// @Summary List all agenda events
|
||||||
|
// @Description List all agenda events with details
|
||||||
|
// @Tags agenda
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} map[string]interface{}
|
||||||
|
// @Failure 500 {object} map[string]string
|
||||||
|
// @Router /api/agenda [get]
|
||||||
|
func (h *Handler) List(c *gin.Context) {
|
||||||
|
agendas, err := h.service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erro ao listar agendas: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, agendas)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get godoc
|
||||||
|
// @Summary Get agenda event by ID
|
||||||
|
// @Description Get agenda event details by ID
|
||||||
|
// @Tags agenda
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "Agenda ID"
|
||||||
|
// @Success 200 {object} map[string]interface{}
|
||||||
|
// @Failure 400 {object} map[string]string
|
||||||
|
// @Failure 500 {object} map[string]string
|
||||||
|
// @Router /api/agenda/{id} [get]
|
||||||
|
func (h *Handler) Get(c *gin.Context) {
|
||||||
|
idParam := c.Param("id")
|
||||||
|
id, err := uuid.Parse(idParam)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "ID inválido: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
agenda, err := h.service.Get(c.Request.Context(), id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erro ao buscar agenda: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, agenda)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update godoc
|
||||||
|
// @Summary Update agenda event
|
||||||
|
// @Description Update agenda event by ID
|
||||||
|
// @Tags agenda
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "Agenda ID"
|
||||||
|
// @Param request body CreateAgendaRequest true "Update Agenda Request"
|
||||||
|
// @Success 200 {object} map[string]interface{}
|
||||||
|
// @Failure 400 {object} map[string]string
|
||||||
|
// @Failure 500 {object} map[string]string
|
||||||
|
// @Router /api/agenda/{id} [put]
|
||||||
|
func (h *Handler) Update(c *gin.Context) {
|
||||||
|
idParam := c.Param("id")
|
||||||
|
id, err := uuid.Parse(idParam)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "ID inválido: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var req CreateAgendaRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Dados inválidos: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
agenda, err := h.service.Update(c.Request.Context(), id, req)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erro ao atualizar agenda: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, agenda)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete godoc
|
||||||
|
// @Summary Delete agenda event
|
||||||
|
// @Description Delete agenda event by ID
|
||||||
|
// @Tags agenda
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "Agenda ID"
|
||||||
|
// @Success 204 {object} nil
|
||||||
|
// @Failure 400 {object} map[string]string
|
||||||
|
// @Failure 500 {object} map[string]string
|
||||||
|
// @Router /api/agenda/{id} [delete]
|
||||||
|
func (h *Handler) Delete(c *gin.Context) {
|
||||||
|
idParam := c.Param("id")
|
||||||
|
id, err := uuid.Parse(idParam)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "ID inválido: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.service.Delete(c.Request.Context(), id); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erro ao deletar agenda: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Status(http.StatusNoContent)
|
||||||
|
}
|
||||||
136
backend/internal/agenda/service.go
Normal file
136
backend/internal/agenda/service.go
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
package agenda
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"photum-backend/internal/db/generated"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
queries *generated.Queries
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(db *generated.Queries) *Service {
|
||||||
|
return &Service{queries: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateAgendaRequest struct {
|
||||||
|
FotID uuid.UUID `json:"fot_id"`
|
||||||
|
DataEvento time.Time `json:"data_evento"`
|
||||||
|
TipoEventoID uuid.UUID `json:"tipo_evento_id"`
|
||||||
|
ObservacoesEvento string `json:"observacoes_evento"`
|
||||||
|
LocalEvento string `json:"local_evento"`
|
||||||
|
Endereco string `json:"endereco"`
|
||||||
|
Horario string `json:"horario"`
|
||||||
|
QtdFormandos int32 `json:"qtd_formandos"`
|
||||||
|
QtdFotografos int32 `json:"qtd_fotografos"`
|
||||||
|
QtdRecepcionistas int32 `json:"qtd_recepcionistas"`
|
||||||
|
QtdCinegrafistas int32 `json:"qtd_cinegrafistas"`
|
||||||
|
QtdEstudios int32 `json:"qtd_estudios"`
|
||||||
|
QtdPontoFoto int32 `json:"qtd_ponto_foto"`
|
||||||
|
QtdPontoID int32 `json:"qtd_ponto_id"`
|
||||||
|
QtdPontoDecorado int32 `json:"qtd_ponto_decorado"`
|
||||||
|
QtdPontosLed int32 `json:"qtd_pontos_led"`
|
||||||
|
QtdPlataforma360 int32 `json:"qtd_plataforma_360"`
|
||||||
|
StatusProfissionais string `json:"status_profissionais"`
|
||||||
|
FotoFaltante int32 `json:"foto_faltante"`
|
||||||
|
RecepFaltante int32 `json:"recep_faltante"`
|
||||||
|
CineFaltante int32 `json:"cine_faltante"`
|
||||||
|
LogisticaObservacoes string `json:"logistica_observacoes"`
|
||||||
|
PreVenda bool `json:"pre_venda"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) CalculateStatus(fotoFaltante, recepFaltante, cineFaltante int32) string {
|
||||||
|
if fotoFaltante < 0 || recepFaltante < 0 || cineFaltante < 0 {
|
||||||
|
return "ERRO"
|
||||||
|
}
|
||||||
|
|
||||||
|
sum := fotoFaltante + recepFaltante + cineFaltante
|
||||||
|
if sum == 0 {
|
||||||
|
return "OK"
|
||||||
|
} else if sum > 0 {
|
||||||
|
return "FALTA"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "ERRO"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Create(ctx context.Context, req CreateAgendaRequest) (generated.Agenda, error) {
|
||||||
|
status := s.CalculateStatus(req.FotoFaltante, req.RecepFaltante, req.CineFaltante)
|
||||||
|
|
||||||
|
params := generated.CreateAgendaParams{
|
||||||
|
FotID: pgtype.UUID{Bytes: req.FotID, Valid: true},
|
||||||
|
DataEvento: pgtype.Date{Time: req.DataEvento, Valid: true},
|
||||||
|
TipoEventoID: pgtype.UUID{Bytes: req.TipoEventoID, Valid: true},
|
||||||
|
ObservacoesEvento: pgtype.Text{String: req.ObservacoesEvento, Valid: req.ObservacoesEvento != ""},
|
||||||
|
LocalEvento: pgtype.Text{String: req.LocalEvento, Valid: req.LocalEvento != ""},
|
||||||
|
Endereco: pgtype.Text{String: req.Endereco, Valid: req.Endereco != ""},
|
||||||
|
Horario: pgtype.Text{String: req.Horario, Valid: req.Horario != ""},
|
||||||
|
QtdFormandos: pgtype.Int4{Int32: req.QtdFormandos, Valid: true},
|
||||||
|
QtdFotografos: pgtype.Int4{Int32: req.QtdFotografos, Valid: true},
|
||||||
|
QtdRecepcionistas: pgtype.Int4{Int32: req.QtdRecepcionistas, Valid: true},
|
||||||
|
QtdCinegrafistas: pgtype.Int4{Int32: req.QtdCinegrafistas, Valid: true},
|
||||||
|
QtdEstudios: pgtype.Int4{Int32: req.QtdEstudios, Valid: true},
|
||||||
|
QtdPontoFoto: pgtype.Int4{Int32: req.QtdPontoFoto, Valid: true},
|
||||||
|
QtdPontoID: pgtype.Int4{Int32: req.QtdPontoID, Valid: true},
|
||||||
|
QtdPontoDecorado: pgtype.Int4{Int32: req.QtdPontoDecorado, Valid: true},
|
||||||
|
QtdPontosLed: pgtype.Int4{Int32: req.QtdPontosLed, Valid: true},
|
||||||
|
QtdPlataforma360: pgtype.Int4{Int32: req.QtdPlataforma360, Valid: true},
|
||||||
|
StatusProfissionais: pgtype.Text{String: status, Valid: true},
|
||||||
|
FotoFaltante: pgtype.Int4{Int32: req.FotoFaltante, Valid: true},
|
||||||
|
RecepFaltante: pgtype.Int4{Int32: req.RecepFaltante, Valid: true},
|
||||||
|
CineFaltante: pgtype.Int4{Int32: req.CineFaltante, Valid: true},
|
||||||
|
LogisticaObservacoes: pgtype.Text{String: req.LogisticaObservacoes, Valid: req.LogisticaObservacoes != ""},
|
||||||
|
PreVenda: pgtype.Bool{Bool: req.PreVenda, Valid: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.queries.CreateAgenda(ctx, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) List(ctx context.Context) ([]generated.ListAgendasRow, error) {
|
||||||
|
return s.queries.ListAgendas(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Get(ctx context.Context, id uuid.UUID) (generated.Agenda, error) {
|
||||||
|
return s.queries.GetAgenda(ctx, pgtype.UUID{Bytes: id, Valid: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Update(ctx context.Context, id uuid.UUID, req CreateAgendaRequest) (generated.Agenda, error) {
|
||||||
|
status := s.CalculateStatus(req.FotoFaltante, req.RecepFaltante, req.CineFaltante)
|
||||||
|
|
||||||
|
params := generated.UpdateAgendaParams{
|
||||||
|
ID: pgtype.UUID{Bytes: id, Valid: true},
|
||||||
|
FotID: pgtype.UUID{Bytes: req.FotID, Valid: true},
|
||||||
|
DataEvento: pgtype.Date{Time: req.DataEvento, Valid: true},
|
||||||
|
TipoEventoID: pgtype.UUID{Bytes: req.TipoEventoID, Valid: true},
|
||||||
|
ObservacoesEvento: pgtype.Text{String: req.ObservacoesEvento, Valid: req.ObservacoesEvento != ""},
|
||||||
|
LocalEvento: pgtype.Text{String: req.LocalEvento, Valid: req.LocalEvento != ""},
|
||||||
|
Endereco: pgtype.Text{String: req.Endereco, Valid: req.Endereco != ""},
|
||||||
|
Horario: pgtype.Text{String: req.Horario, Valid: req.Horario != ""},
|
||||||
|
QtdFormandos: pgtype.Int4{Int32: req.QtdFormandos, Valid: true},
|
||||||
|
QtdFotografos: pgtype.Int4{Int32: req.QtdFotografos, Valid: true},
|
||||||
|
QtdRecepcionistas: pgtype.Int4{Int32: req.QtdRecepcionistas, Valid: true},
|
||||||
|
QtdCinegrafistas: pgtype.Int4{Int32: req.QtdCinegrafistas, Valid: true},
|
||||||
|
QtdEstudios: pgtype.Int4{Int32: req.QtdEstudios, Valid: true},
|
||||||
|
QtdPontoFoto: pgtype.Int4{Int32: req.QtdPontoFoto, Valid: true},
|
||||||
|
QtdPontoID: pgtype.Int4{Int32: req.QtdPontoID, Valid: true},
|
||||||
|
QtdPontoDecorado: pgtype.Int4{Int32: req.QtdPontoDecorado, Valid: true},
|
||||||
|
QtdPontosLed: pgtype.Int4{Int32: req.QtdPontosLed, Valid: true},
|
||||||
|
QtdPlataforma360: pgtype.Int4{Int32: req.QtdPlataforma360, Valid: true},
|
||||||
|
StatusProfissionais: pgtype.Text{String: status, Valid: true},
|
||||||
|
FotoFaltante: pgtype.Int4{Int32: req.FotoFaltante, Valid: true},
|
||||||
|
RecepFaltante: pgtype.Int4{Int32: req.RecepFaltante, Valid: true},
|
||||||
|
CineFaltante: pgtype.Int4{Int32: req.CineFaltante, Valid: true},
|
||||||
|
LogisticaObservacoes: pgtype.Text{String: req.LogisticaObservacoes, Valid: req.LogisticaObservacoes != ""},
|
||||||
|
PreVenda: pgtype.Bool{Bool: req.PreVenda, Valid: true},
|
||||||
|
}
|
||||||
|
return s.queries.UpdateAgenda(ctx, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Delete(ctx context.Context, id uuid.UUID) error {
|
||||||
|
return s.queries.DeleteAgenda(ctx, pgtype.UUID{Bytes: id, Valid: true})
|
||||||
|
}
|
||||||
401
backend/internal/db/generated/agenda.sql.go
Normal file
401
backend/internal/db/generated/agenda.sql.go
Normal file
|
|
@ -0,0 +1,401 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: agenda.sql
|
||||||
|
|
||||||
|
package generated
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
const createAgenda = `-- name: CreateAgenda :one
|
||||||
|
INSERT INTO agenda (
|
||||||
|
fot_id,
|
||||||
|
data_evento,
|
||||||
|
tipo_evento_id,
|
||||||
|
observacoes_evento,
|
||||||
|
local_evento,
|
||||||
|
endereco,
|
||||||
|
horario,
|
||||||
|
qtd_formandos,
|
||||||
|
qtd_fotografos,
|
||||||
|
qtd_recepcionistas,
|
||||||
|
qtd_cinegrafistas,
|
||||||
|
qtd_estudios,
|
||||||
|
qtd_ponto_foto,
|
||||||
|
qtd_ponto_id,
|
||||||
|
qtd_ponto_decorado,
|
||||||
|
qtd_pontos_led,
|
||||||
|
qtd_plataforma_360,
|
||||||
|
status_profissionais,
|
||||||
|
foto_faltante,
|
||||||
|
recep_faltante,
|
||||||
|
cine_faltante,
|
||||||
|
logistica_observacoes,
|
||||||
|
pre_venda
|
||||||
|
) VALUES (
|
||||||
|
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23
|
||||||
|
) RETURNING id, fot_id, data_evento, tipo_evento_id, observacoes_evento, local_evento, endereco, horario, qtd_formandos, qtd_fotografos, qtd_recepcionistas, qtd_cinegrafistas, qtd_estudios, qtd_ponto_foto, qtd_ponto_id, qtd_ponto_decorado, qtd_pontos_led, qtd_plataforma_360, status_profissionais, foto_faltante, recep_faltante, cine_faltante, logistica_observacoes, pre_venda, criado_em, atualizado_em
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateAgendaParams struct {
|
||||||
|
FotID pgtype.UUID `json:"fot_id"`
|
||||||
|
DataEvento pgtype.Date `json:"data_evento"`
|
||||||
|
TipoEventoID pgtype.UUID `json:"tipo_evento_id"`
|
||||||
|
ObservacoesEvento pgtype.Text `json:"observacoes_evento"`
|
||||||
|
LocalEvento pgtype.Text `json:"local_evento"`
|
||||||
|
Endereco pgtype.Text `json:"endereco"`
|
||||||
|
Horario pgtype.Text `json:"horario"`
|
||||||
|
QtdFormandos pgtype.Int4 `json:"qtd_formandos"`
|
||||||
|
QtdFotografos pgtype.Int4 `json:"qtd_fotografos"`
|
||||||
|
QtdRecepcionistas pgtype.Int4 `json:"qtd_recepcionistas"`
|
||||||
|
QtdCinegrafistas pgtype.Int4 `json:"qtd_cinegrafistas"`
|
||||||
|
QtdEstudios pgtype.Int4 `json:"qtd_estudios"`
|
||||||
|
QtdPontoFoto pgtype.Int4 `json:"qtd_ponto_foto"`
|
||||||
|
QtdPontoID pgtype.Int4 `json:"qtd_ponto_id"`
|
||||||
|
QtdPontoDecorado pgtype.Int4 `json:"qtd_ponto_decorado"`
|
||||||
|
QtdPontosLed pgtype.Int4 `json:"qtd_pontos_led"`
|
||||||
|
QtdPlataforma360 pgtype.Int4 `json:"qtd_plataforma_360"`
|
||||||
|
StatusProfissionais pgtype.Text `json:"status_profissionais"`
|
||||||
|
FotoFaltante pgtype.Int4 `json:"foto_faltante"`
|
||||||
|
RecepFaltante pgtype.Int4 `json:"recep_faltante"`
|
||||||
|
CineFaltante pgtype.Int4 `json:"cine_faltante"`
|
||||||
|
LogisticaObservacoes pgtype.Text `json:"logistica_observacoes"`
|
||||||
|
PreVenda pgtype.Bool `json:"pre_venda"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateAgenda(ctx context.Context, arg CreateAgendaParams) (Agenda, error) {
|
||||||
|
row := q.db.QueryRow(ctx, createAgenda,
|
||||||
|
arg.FotID,
|
||||||
|
arg.DataEvento,
|
||||||
|
arg.TipoEventoID,
|
||||||
|
arg.ObservacoesEvento,
|
||||||
|
arg.LocalEvento,
|
||||||
|
arg.Endereco,
|
||||||
|
arg.Horario,
|
||||||
|
arg.QtdFormandos,
|
||||||
|
arg.QtdFotografos,
|
||||||
|
arg.QtdRecepcionistas,
|
||||||
|
arg.QtdCinegrafistas,
|
||||||
|
arg.QtdEstudios,
|
||||||
|
arg.QtdPontoFoto,
|
||||||
|
arg.QtdPontoID,
|
||||||
|
arg.QtdPontoDecorado,
|
||||||
|
arg.QtdPontosLed,
|
||||||
|
arg.QtdPlataforma360,
|
||||||
|
arg.StatusProfissionais,
|
||||||
|
arg.FotoFaltante,
|
||||||
|
arg.RecepFaltante,
|
||||||
|
arg.CineFaltante,
|
||||||
|
arg.LogisticaObservacoes,
|
||||||
|
arg.PreVenda,
|
||||||
|
)
|
||||||
|
var i Agenda
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.FotID,
|
||||||
|
&i.DataEvento,
|
||||||
|
&i.TipoEventoID,
|
||||||
|
&i.ObservacoesEvento,
|
||||||
|
&i.LocalEvento,
|
||||||
|
&i.Endereco,
|
||||||
|
&i.Horario,
|
||||||
|
&i.QtdFormandos,
|
||||||
|
&i.QtdFotografos,
|
||||||
|
&i.QtdRecepcionistas,
|
||||||
|
&i.QtdCinegrafistas,
|
||||||
|
&i.QtdEstudios,
|
||||||
|
&i.QtdPontoFoto,
|
||||||
|
&i.QtdPontoID,
|
||||||
|
&i.QtdPontoDecorado,
|
||||||
|
&i.QtdPontosLed,
|
||||||
|
&i.QtdPlataforma360,
|
||||||
|
&i.StatusProfissionais,
|
||||||
|
&i.FotoFaltante,
|
||||||
|
&i.RecepFaltante,
|
||||||
|
&i.CineFaltante,
|
||||||
|
&i.LogisticaObservacoes,
|
||||||
|
&i.PreVenda,
|
||||||
|
&i.CriadoEm,
|
||||||
|
&i.AtualizadoEm,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteAgenda = `-- name: DeleteAgenda :exec
|
||||||
|
DELETE FROM agenda
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) DeleteAgenda(ctx context.Context, id pgtype.UUID) error {
|
||||||
|
_, err := q.db.Exec(ctx, deleteAgenda, id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAgenda = `-- name: GetAgenda :one
|
||||||
|
SELECT id, fot_id, data_evento, tipo_evento_id, observacoes_evento, local_evento, endereco, horario, qtd_formandos, qtd_fotografos, qtd_recepcionistas, qtd_cinegrafistas, qtd_estudios, qtd_ponto_foto, qtd_ponto_id, qtd_ponto_decorado, qtd_pontos_led, qtd_plataforma_360, status_profissionais, foto_faltante, recep_faltante, cine_faltante, logistica_observacoes, pre_venda, criado_em, atualizado_em FROM agenda
|
||||||
|
WHERE id = $1 LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetAgenda(ctx context.Context, id pgtype.UUID) (Agenda, error) {
|
||||||
|
row := q.db.QueryRow(ctx, getAgenda, id)
|
||||||
|
var i Agenda
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.FotID,
|
||||||
|
&i.DataEvento,
|
||||||
|
&i.TipoEventoID,
|
||||||
|
&i.ObservacoesEvento,
|
||||||
|
&i.LocalEvento,
|
||||||
|
&i.Endereco,
|
||||||
|
&i.Horario,
|
||||||
|
&i.QtdFormandos,
|
||||||
|
&i.QtdFotografos,
|
||||||
|
&i.QtdRecepcionistas,
|
||||||
|
&i.QtdCinegrafistas,
|
||||||
|
&i.QtdEstudios,
|
||||||
|
&i.QtdPontoFoto,
|
||||||
|
&i.QtdPontoID,
|
||||||
|
&i.QtdPontoDecorado,
|
||||||
|
&i.QtdPontosLed,
|
||||||
|
&i.QtdPlataforma360,
|
||||||
|
&i.StatusProfissionais,
|
||||||
|
&i.FotoFaltante,
|
||||||
|
&i.RecepFaltante,
|
||||||
|
&i.CineFaltante,
|
||||||
|
&i.LogisticaObservacoes,
|
||||||
|
&i.PreVenda,
|
||||||
|
&i.CriadoEm,
|
||||||
|
&i.AtualizadoEm,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const listAgendas = `-- name: ListAgendas :many
|
||||||
|
SELECT
|
||||||
|
a.id, a.fot_id, a.data_evento, a.tipo_evento_id, a.observacoes_evento, a.local_evento, a.endereco, a.horario, a.qtd_formandos, a.qtd_fotografos, a.qtd_recepcionistas, a.qtd_cinegrafistas, a.qtd_estudios, a.qtd_ponto_foto, a.qtd_ponto_id, a.qtd_ponto_decorado, a.qtd_pontos_led, a.qtd_plataforma_360, a.status_profissionais, a.foto_faltante, a.recep_faltante, a.cine_faltante, a.logistica_observacoes, a.pre_venda, a.criado_em, a.atualizado_em,
|
||||||
|
cf.fot as fot_numero,
|
||||||
|
cf.instituicao,
|
||||||
|
c.nome as curso_nome,
|
||||||
|
e.nome as empresa_nome,
|
||||||
|
af.ano_semestre,
|
||||||
|
cf.observacoes as observacoes_fot,
|
||||||
|
te.nome as tipo_evento_nome
|
||||||
|
FROM agenda a
|
||||||
|
JOIN cadastro_fot cf ON a.fot_id = cf.id
|
||||||
|
JOIN cursos c ON cf.curso_id = c.id
|
||||||
|
JOIN empresas e ON cf.empresa_id = e.id
|
||||||
|
JOIN anos_formaturas af ON cf.ano_formatura_id = af.id
|
||||||
|
JOIN tipos_eventos te ON a.tipo_evento_id = te.id
|
||||||
|
ORDER BY a.data_evento
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListAgendasRow struct {
|
||||||
|
ID pgtype.UUID `json:"id"`
|
||||||
|
FotID pgtype.UUID `json:"fot_id"`
|
||||||
|
DataEvento pgtype.Date `json:"data_evento"`
|
||||||
|
TipoEventoID pgtype.UUID `json:"tipo_evento_id"`
|
||||||
|
ObservacoesEvento pgtype.Text `json:"observacoes_evento"`
|
||||||
|
LocalEvento pgtype.Text `json:"local_evento"`
|
||||||
|
Endereco pgtype.Text `json:"endereco"`
|
||||||
|
Horario pgtype.Text `json:"horario"`
|
||||||
|
QtdFormandos pgtype.Int4 `json:"qtd_formandos"`
|
||||||
|
QtdFotografos pgtype.Int4 `json:"qtd_fotografos"`
|
||||||
|
QtdRecepcionistas pgtype.Int4 `json:"qtd_recepcionistas"`
|
||||||
|
QtdCinegrafistas pgtype.Int4 `json:"qtd_cinegrafistas"`
|
||||||
|
QtdEstudios pgtype.Int4 `json:"qtd_estudios"`
|
||||||
|
QtdPontoFoto pgtype.Int4 `json:"qtd_ponto_foto"`
|
||||||
|
QtdPontoID pgtype.Int4 `json:"qtd_ponto_id"`
|
||||||
|
QtdPontoDecorado pgtype.Int4 `json:"qtd_ponto_decorado"`
|
||||||
|
QtdPontosLed pgtype.Int4 `json:"qtd_pontos_led"`
|
||||||
|
QtdPlataforma360 pgtype.Int4 `json:"qtd_plataforma_360"`
|
||||||
|
StatusProfissionais pgtype.Text `json:"status_profissionais"`
|
||||||
|
FotoFaltante pgtype.Int4 `json:"foto_faltante"`
|
||||||
|
RecepFaltante pgtype.Int4 `json:"recep_faltante"`
|
||||||
|
CineFaltante pgtype.Int4 `json:"cine_faltante"`
|
||||||
|
LogisticaObservacoes pgtype.Text `json:"logistica_observacoes"`
|
||||||
|
PreVenda pgtype.Bool `json:"pre_venda"`
|
||||||
|
CriadoEm pgtype.Timestamptz `json:"criado_em"`
|
||||||
|
AtualizadoEm pgtype.Timestamptz `json:"atualizado_em"`
|
||||||
|
FotNumero int32 `json:"fot_numero"`
|
||||||
|
Instituicao pgtype.Text `json:"instituicao"`
|
||||||
|
CursoNome string `json:"curso_nome"`
|
||||||
|
EmpresaNome string `json:"empresa_nome"`
|
||||||
|
AnoSemestre string `json:"ano_semestre"`
|
||||||
|
ObservacoesFot pgtype.Text `json:"observacoes_fot"`
|
||||||
|
TipoEventoNome string `json:"tipo_evento_nome"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) ListAgendas(ctx context.Context) ([]ListAgendasRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, listAgendas)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []ListAgendasRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i ListAgendasRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.FotID,
|
||||||
|
&i.DataEvento,
|
||||||
|
&i.TipoEventoID,
|
||||||
|
&i.ObservacoesEvento,
|
||||||
|
&i.LocalEvento,
|
||||||
|
&i.Endereco,
|
||||||
|
&i.Horario,
|
||||||
|
&i.QtdFormandos,
|
||||||
|
&i.QtdFotografos,
|
||||||
|
&i.QtdRecepcionistas,
|
||||||
|
&i.QtdCinegrafistas,
|
||||||
|
&i.QtdEstudios,
|
||||||
|
&i.QtdPontoFoto,
|
||||||
|
&i.QtdPontoID,
|
||||||
|
&i.QtdPontoDecorado,
|
||||||
|
&i.QtdPontosLed,
|
||||||
|
&i.QtdPlataforma360,
|
||||||
|
&i.StatusProfissionais,
|
||||||
|
&i.FotoFaltante,
|
||||||
|
&i.RecepFaltante,
|
||||||
|
&i.CineFaltante,
|
||||||
|
&i.LogisticaObservacoes,
|
||||||
|
&i.PreVenda,
|
||||||
|
&i.CriadoEm,
|
||||||
|
&i.AtualizadoEm,
|
||||||
|
&i.FotNumero,
|
||||||
|
&i.Instituicao,
|
||||||
|
&i.CursoNome,
|
||||||
|
&i.EmpresaNome,
|
||||||
|
&i.AnoSemestre,
|
||||||
|
&i.ObservacoesFot,
|
||||||
|
&i.TipoEventoNome,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateAgenda = `-- name: UpdateAgenda :one
|
||||||
|
UPDATE agenda
|
||||||
|
SET
|
||||||
|
fot_id = $2,
|
||||||
|
data_evento = $3,
|
||||||
|
tipo_evento_id = $4,
|
||||||
|
observacoes_evento = $5,
|
||||||
|
local_evento = $6,
|
||||||
|
endereco = $7,
|
||||||
|
horario = $8,
|
||||||
|
qtd_formandos = $9,
|
||||||
|
qtd_fotografos = $10,
|
||||||
|
qtd_recepcionistas = $11,
|
||||||
|
qtd_cinegrafistas = $12,
|
||||||
|
qtd_estudios = $13,
|
||||||
|
qtd_ponto_foto = $14,
|
||||||
|
qtd_ponto_id = $15,
|
||||||
|
qtd_ponto_decorado = $16,
|
||||||
|
qtd_pontos_led = $17,
|
||||||
|
qtd_plataforma_360 = $18,
|
||||||
|
status_profissionais = $19,
|
||||||
|
foto_faltante = $20,
|
||||||
|
recep_faltante = $21,
|
||||||
|
cine_faltante = $22,
|
||||||
|
logistica_observacoes = $23,
|
||||||
|
pre_venda = $24,
|
||||||
|
atualizado_em = NOW()
|
||||||
|
WHERE id = $1
|
||||||
|
RETURNING id, fot_id, data_evento, tipo_evento_id, observacoes_evento, local_evento, endereco, horario, qtd_formandos, qtd_fotografos, qtd_recepcionistas, qtd_cinegrafistas, qtd_estudios, qtd_ponto_foto, qtd_ponto_id, qtd_ponto_decorado, qtd_pontos_led, qtd_plataforma_360, status_profissionais, foto_faltante, recep_faltante, cine_faltante, logistica_observacoes, pre_venda, criado_em, atualizado_em
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateAgendaParams struct {
|
||||||
|
ID pgtype.UUID `json:"id"`
|
||||||
|
FotID pgtype.UUID `json:"fot_id"`
|
||||||
|
DataEvento pgtype.Date `json:"data_evento"`
|
||||||
|
TipoEventoID pgtype.UUID `json:"tipo_evento_id"`
|
||||||
|
ObservacoesEvento pgtype.Text `json:"observacoes_evento"`
|
||||||
|
LocalEvento pgtype.Text `json:"local_evento"`
|
||||||
|
Endereco pgtype.Text `json:"endereco"`
|
||||||
|
Horario pgtype.Text `json:"horario"`
|
||||||
|
QtdFormandos pgtype.Int4 `json:"qtd_formandos"`
|
||||||
|
QtdFotografos pgtype.Int4 `json:"qtd_fotografos"`
|
||||||
|
QtdRecepcionistas pgtype.Int4 `json:"qtd_recepcionistas"`
|
||||||
|
QtdCinegrafistas pgtype.Int4 `json:"qtd_cinegrafistas"`
|
||||||
|
QtdEstudios pgtype.Int4 `json:"qtd_estudios"`
|
||||||
|
QtdPontoFoto pgtype.Int4 `json:"qtd_ponto_foto"`
|
||||||
|
QtdPontoID pgtype.Int4 `json:"qtd_ponto_id"`
|
||||||
|
QtdPontoDecorado pgtype.Int4 `json:"qtd_ponto_decorado"`
|
||||||
|
QtdPontosLed pgtype.Int4 `json:"qtd_pontos_led"`
|
||||||
|
QtdPlataforma360 pgtype.Int4 `json:"qtd_plataforma_360"`
|
||||||
|
StatusProfissionais pgtype.Text `json:"status_profissionais"`
|
||||||
|
FotoFaltante pgtype.Int4 `json:"foto_faltante"`
|
||||||
|
RecepFaltante pgtype.Int4 `json:"recep_faltante"`
|
||||||
|
CineFaltante pgtype.Int4 `json:"cine_faltante"`
|
||||||
|
LogisticaObservacoes pgtype.Text `json:"logistica_observacoes"`
|
||||||
|
PreVenda pgtype.Bool `json:"pre_venda"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateAgenda(ctx context.Context, arg UpdateAgendaParams) (Agenda, error) {
|
||||||
|
row := q.db.QueryRow(ctx, updateAgenda,
|
||||||
|
arg.ID,
|
||||||
|
arg.FotID,
|
||||||
|
arg.DataEvento,
|
||||||
|
arg.TipoEventoID,
|
||||||
|
arg.ObservacoesEvento,
|
||||||
|
arg.LocalEvento,
|
||||||
|
arg.Endereco,
|
||||||
|
arg.Horario,
|
||||||
|
arg.QtdFormandos,
|
||||||
|
arg.QtdFotografos,
|
||||||
|
arg.QtdRecepcionistas,
|
||||||
|
arg.QtdCinegrafistas,
|
||||||
|
arg.QtdEstudios,
|
||||||
|
arg.QtdPontoFoto,
|
||||||
|
arg.QtdPontoID,
|
||||||
|
arg.QtdPontoDecorado,
|
||||||
|
arg.QtdPontosLed,
|
||||||
|
arg.QtdPlataforma360,
|
||||||
|
arg.StatusProfissionais,
|
||||||
|
arg.FotoFaltante,
|
||||||
|
arg.RecepFaltante,
|
||||||
|
arg.CineFaltante,
|
||||||
|
arg.LogisticaObservacoes,
|
||||||
|
arg.PreVenda,
|
||||||
|
)
|
||||||
|
var i Agenda
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.FotID,
|
||||||
|
&i.DataEvento,
|
||||||
|
&i.TipoEventoID,
|
||||||
|
&i.ObservacoesEvento,
|
||||||
|
&i.LocalEvento,
|
||||||
|
&i.Endereco,
|
||||||
|
&i.Horario,
|
||||||
|
&i.QtdFormandos,
|
||||||
|
&i.QtdFotografos,
|
||||||
|
&i.QtdRecepcionistas,
|
||||||
|
&i.QtdCinegrafistas,
|
||||||
|
&i.QtdEstudios,
|
||||||
|
&i.QtdPontoFoto,
|
||||||
|
&i.QtdPontoID,
|
||||||
|
&i.QtdPontoDecorado,
|
||||||
|
&i.QtdPontosLed,
|
||||||
|
&i.QtdPlataforma360,
|
||||||
|
&i.StatusProfissionais,
|
||||||
|
&i.FotoFaltante,
|
||||||
|
&i.RecepFaltante,
|
||||||
|
&i.CineFaltante,
|
||||||
|
&i.LogisticaObservacoes,
|
||||||
|
&i.PreVenda,
|
||||||
|
&i.CriadoEm,
|
||||||
|
&i.AtualizadoEm,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,35 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Agenda struct {
|
||||||
|
ID pgtype.UUID `json:"id"`
|
||||||
|
FotID pgtype.UUID `json:"fot_id"`
|
||||||
|
DataEvento pgtype.Date `json:"data_evento"`
|
||||||
|
TipoEventoID pgtype.UUID `json:"tipo_evento_id"`
|
||||||
|
ObservacoesEvento pgtype.Text `json:"observacoes_evento"`
|
||||||
|
LocalEvento pgtype.Text `json:"local_evento"`
|
||||||
|
Endereco pgtype.Text `json:"endereco"`
|
||||||
|
Horario pgtype.Text `json:"horario"`
|
||||||
|
QtdFormandos pgtype.Int4 `json:"qtd_formandos"`
|
||||||
|
QtdFotografos pgtype.Int4 `json:"qtd_fotografos"`
|
||||||
|
QtdRecepcionistas pgtype.Int4 `json:"qtd_recepcionistas"`
|
||||||
|
QtdCinegrafistas pgtype.Int4 `json:"qtd_cinegrafistas"`
|
||||||
|
QtdEstudios pgtype.Int4 `json:"qtd_estudios"`
|
||||||
|
QtdPontoFoto pgtype.Int4 `json:"qtd_ponto_foto"`
|
||||||
|
QtdPontoID pgtype.Int4 `json:"qtd_ponto_id"`
|
||||||
|
QtdPontoDecorado pgtype.Int4 `json:"qtd_ponto_decorado"`
|
||||||
|
QtdPontosLed pgtype.Int4 `json:"qtd_pontos_led"`
|
||||||
|
QtdPlataforma360 pgtype.Int4 `json:"qtd_plataforma_360"`
|
||||||
|
StatusProfissionais pgtype.Text `json:"status_profissionais"`
|
||||||
|
FotoFaltante pgtype.Int4 `json:"foto_faltante"`
|
||||||
|
RecepFaltante pgtype.Int4 `json:"recep_faltante"`
|
||||||
|
CineFaltante pgtype.Int4 `json:"cine_faltante"`
|
||||||
|
LogisticaObservacoes pgtype.Text `json:"logistica_observacoes"`
|
||||||
|
PreVenda pgtype.Bool `json:"pre_venda"`
|
||||||
|
CriadoEm pgtype.Timestamptz `json:"criado_em"`
|
||||||
|
AtualizadoEm pgtype.Timestamptz `json:"atualizado_em"`
|
||||||
|
}
|
||||||
|
|
||||||
type AnosFormatura struct {
|
type AnosFormatura struct {
|
||||||
ID pgtype.UUID `json:"id"`
|
ID pgtype.UUID `json:"id"`
|
||||||
AnoSemestre string `json:"ano_semestre"`
|
AnoSemestre string `json:"ano_semestre"`
|
||||||
|
|
|
||||||
84
backend/internal/db/queries/agenda.sql
Normal file
84
backend/internal/db/queries/agenda.sql
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
-- name: CreateAgenda :one
|
||||||
|
INSERT INTO agenda (
|
||||||
|
fot_id,
|
||||||
|
data_evento,
|
||||||
|
tipo_evento_id,
|
||||||
|
observacoes_evento,
|
||||||
|
local_evento,
|
||||||
|
endereco,
|
||||||
|
horario,
|
||||||
|
qtd_formandos,
|
||||||
|
qtd_fotografos,
|
||||||
|
qtd_recepcionistas,
|
||||||
|
qtd_cinegrafistas,
|
||||||
|
qtd_estudios,
|
||||||
|
qtd_ponto_foto,
|
||||||
|
qtd_ponto_id,
|
||||||
|
qtd_ponto_decorado,
|
||||||
|
qtd_pontos_led,
|
||||||
|
qtd_plataforma_360,
|
||||||
|
status_profissionais,
|
||||||
|
foto_faltante,
|
||||||
|
recep_faltante,
|
||||||
|
cine_faltante,
|
||||||
|
logistica_observacoes,
|
||||||
|
pre_venda
|
||||||
|
) VALUES (
|
||||||
|
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23
|
||||||
|
) RETURNING *;
|
||||||
|
|
||||||
|
-- name: GetAgenda :one
|
||||||
|
SELECT * FROM agenda
|
||||||
|
WHERE id = $1 LIMIT 1;
|
||||||
|
|
||||||
|
-- name: ListAgendas :many
|
||||||
|
SELECT
|
||||||
|
a.*,
|
||||||
|
cf.fot as fot_numero,
|
||||||
|
cf.instituicao,
|
||||||
|
c.nome as curso_nome,
|
||||||
|
e.nome as empresa_nome,
|
||||||
|
af.ano_semestre,
|
||||||
|
cf.observacoes as observacoes_fot,
|
||||||
|
te.nome as tipo_evento_nome
|
||||||
|
FROM agenda a
|
||||||
|
JOIN cadastro_fot cf ON a.fot_id = cf.id
|
||||||
|
JOIN cursos c ON cf.curso_id = c.id
|
||||||
|
JOIN empresas e ON cf.empresa_id = e.id
|
||||||
|
JOIN anos_formaturas af ON cf.ano_formatura_id = af.id
|
||||||
|
JOIN tipos_eventos te ON a.tipo_evento_id = te.id
|
||||||
|
ORDER BY a.data_evento;
|
||||||
|
|
||||||
|
-- name: UpdateAgenda :one
|
||||||
|
UPDATE agenda
|
||||||
|
SET
|
||||||
|
fot_id = $2,
|
||||||
|
data_evento = $3,
|
||||||
|
tipo_evento_id = $4,
|
||||||
|
observacoes_evento = $5,
|
||||||
|
local_evento = $6,
|
||||||
|
endereco = $7,
|
||||||
|
horario = $8,
|
||||||
|
qtd_formandos = $9,
|
||||||
|
qtd_fotografos = $10,
|
||||||
|
qtd_recepcionistas = $11,
|
||||||
|
qtd_cinegrafistas = $12,
|
||||||
|
qtd_estudios = $13,
|
||||||
|
qtd_ponto_foto = $14,
|
||||||
|
qtd_ponto_id = $15,
|
||||||
|
qtd_ponto_decorado = $16,
|
||||||
|
qtd_pontos_led = $17,
|
||||||
|
qtd_plataforma_360 = $18,
|
||||||
|
status_profissionais = $19,
|
||||||
|
foto_faltante = $20,
|
||||||
|
recep_faltante = $21,
|
||||||
|
cine_faltante = $22,
|
||||||
|
logistica_observacoes = $23,
|
||||||
|
pre_venda = $24,
|
||||||
|
atualizado_em = NOW()
|
||||||
|
WHERE id = $1
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: DeleteAgenda :exec
|
||||||
|
DELETE FROM agenda
|
||||||
|
WHERE id = $1;
|
||||||
|
|
@ -313,3 +313,32 @@ CREATE TABLE IF NOT EXISTS cadastro_clientes (
|
||||||
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
UNIQUE(usuario_id)
|
UNIQUE(usuario_id)
|
||||||
);
|
);
|
||||||
|
-- Agenda Table
|
||||||
|
CREATE TABLE IF NOT EXISTS agenda (
|
||||||
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
fot_id UUID NOT NULL REFERENCES cadastro_fot(id) ON DELETE CASCADE,
|
||||||
|
data_evento DATE NOT NULL,
|
||||||
|
tipo_evento_id UUID NOT NULL REFERENCES tipos_eventos(id),
|
||||||
|
observacoes_evento TEXT,
|
||||||
|
local_evento VARCHAR(255),
|
||||||
|
endereco VARCHAR(255),
|
||||||
|
horario VARCHAR(20),
|
||||||
|
qtd_formandos INTEGER DEFAULT 0,
|
||||||
|
qtd_fotografos INTEGER DEFAULT 0,
|
||||||
|
qtd_recepcionistas INTEGER DEFAULT 0,
|
||||||
|
qtd_cinegrafistas INTEGER DEFAULT 0,
|
||||||
|
qtd_estudios INTEGER DEFAULT 0,
|
||||||
|
qtd_ponto_foto INTEGER DEFAULT 0,
|
||||||
|
qtd_ponto_id INTEGER DEFAULT 0,
|
||||||
|
qtd_ponto_decorado INTEGER DEFAULT 0,
|
||||||
|
qtd_pontos_led INTEGER DEFAULT 0,
|
||||||
|
qtd_plataforma_360 INTEGER DEFAULT 0,
|
||||||
|
status_profissionais VARCHAR(20) DEFAULT 'OK', -- OK, FALTA, ERRO
|
||||||
|
foto_faltante INTEGER DEFAULT 0,
|
||||||
|
recep_faltante INTEGER DEFAULT 0,
|
||||||
|
cine_faltante INTEGER DEFAULT 0,
|
||||||
|
logistica_observacoes TEXT,
|
||||||
|
pre_venda BOOLEAN DEFAULT FALSE,
|
||||||
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
|
||||||
84
project_documentation.md
Normal file
84
project_documentation.md
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
# Documentação do Projeto Photum - Sessão de Desenvolvimento
|
||||||
|
|
||||||
|
Esta documentação resume todo o trabalho realizado durante a sessão atual de desenvolvimento, focada na implementação do Backend e ajustes no Frontend para o sistema Photum.
|
||||||
|
|
||||||
|
## 1. Visão Geral
|
||||||
|
O objetivo principal foi fortalecer o backend em Go, implementar autenticação segura, e criar as estruturas para gerenciamento de FOT (Formandos, Organização, Turma) e Agenda de Eventos.
|
||||||
|
|
||||||
|
## 2. Implementações no Backend (Go + PostgreSQL)
|
||||||
|
|
||||||
|
### 2.1. Sistema de Autenticação e Usuários
|
||||||
|
- **JWT & Refresh Tokens**: Implementação de autenticação baseada em tokens JWT curta duração e Refresh Tokens seguros.
|
||||||
|
- **Hierarquia de Permissões (RBAC)**: Definição de roles padronizadas: ROLES Backend (Strings no Banco de Dados):
|
||||||
|
|
||||||
|
admin ⮕ Mapeado para SUPERADMIN
|
||||||
|
empresa ⮕ Mapeado para BUSINESS_OWNER
|
||||||
|
cliente ⮕ Mapeado para EVENT_OWNER
|
||||||
|
profissional ⮕ Mapeado para PHOTOGRAPHER
|
||||||
|
|
||||||
|
admin@photum.com -> SUPERADMIN
|
||||||
|
empresa@photum.com -> BUSINESS_OWNER
|
||||||
|
foto@photum.com -> PHOTOGRAPHER
|
||||||
|
- **Fluxo de Aprovação**:
|
||||||
|
- Usuários se registram com status `ativo=false`.
|
||||||
|
- Admin lista usuários pendentes (`/admin/users/pending`).
|
||||||
|
- Admin aprova e define a Role (`/admin/users/:id/approve` e `/admin/users/:id/role`).
|
||||||
|
- Bloqueio de login para usuários inativos.
|
||||||
|
- **Dados do Usuário**: Adição de campos `Nome`, `Telefone` e `Empresa` no registro e listagens.
|
||||||
|
|
||||||
|
### 2.2. Tabelas Auxiliares (CRUDs)
|
||||||
|
Criadas tabelas, Services e Handlers para as entidades básicas do sistema:
|
||||||
|
- `cursos`
|
||||||
|
- `empresas`
|
||||||
|
- `anos_formaturas`
|
||||||
|
- `tipos_eventos` (incluindo tabela de preços por função)
|
||||||
|
- `tipos_servicos`
|
||||||
|
- `funcoes_profissionais`
|
||||||
|
|
||||||
|
### 2.3. Módulo Cadastro FOT
|
||||||
|
Responsável por vincular Turmas a Empresas e Instituições.
|
||||||
|
- **Tabela**: `cadastro_fot` (Campos: `fot`, `empresa_id`, `curso_id`, `ano_formatura_id`, `instituicao`, `observacoes`, etc.).
|
||||||
|
- **Backend**:
|
||||||
|
- Endpoint `POST /api/cadastro-fot`: Criação com verificação de FOT duplicado.
|
||||||
|
- Endpoint `GET /api/cadastro-fot`: Listagem com _joins_ para trazer nomes de Empresa, Curso, etc.
|
||||||
|
- **Integração**: Conectado ao `CourseManagement.tsx` no frontend.
|
||||||
|
|
||||||
|
### 2.4. Módulo Agenda
|
||||||
|
Responsável pelo agendamento de eventos vinculados a um FOT.
|
||||||
|
- **Tabela**: `agenda` criada com uma estrutura normalizada, mas com campos específicos de evento.
|
||||||
|
- Vinculada a `cadastro_fot` via `fot_id`.
|
||||||
|
- Campos de dados do evento: `data_evento`, `local_evento`, `horario`, etc.
|
||||||
|
- Campos de quantitativos: `qtd_formandos`, `qtd_fotografos`, `qtd_recepcionistas`, etc.
|
||||||
|
- Campos de controle: `status_profissionais`, `foto_faltante`, `pre_venda`, etc.
|
||||||
|
- **Backend**:
|
||||||
|
- Arquivos gerados via SQLC (`internal/db/generated/agenda.sql.go`).
|
||||||
|
- Service (`internal/agenda/service.go`) e Handler (`internal/agenda/handler.go`) implementados.
|
||||||
|
- Rotas registradas em `cmd/api/main.go` sob `/api/agenda`.
|
||||||
|
|
||||||
|
### 2.5. Decisões Técnicas Backend
|
||||||
|
- **Framework**: Gin Gonic.
|
||||||
|
- **Database**: PostgreSQL com driver `pgx/v5`.
|
||||||
|
- **Geração de Código**: Utilização do `sqlc` para gerar código Go type-safe a partir de queries SQL puras.
|
||||||
|
- **Estrutura**: Padrão `internal/domain` (Service/Handler/Repository isolados).
|
||||||
|
|
||||||
|
## 3. Implementações no Frontend (React/Next.js)
|
||||||
|
|
||||||
|
### 3.1. Autenticação e Sessão
|
||||||
|
- **AuthContext**: Melhoria na persistência de sessão. O frontend valida o token ao carregar e mantêm o usuário logado.
|
||||||
|
- **Logout**: Implementada função de logout que chama o backend e limpa o estado local.
|
||||||
|
- **UserApproval**: Interface para aprovação de usuários pendentes, exibindo Nome, E-mail e Empresa.
|
||||||
|
|
||||||
|
### 3.2. Gerenciamento de FOT (`CourseManagement.tsx`)
|
||||||
|
- **Listagem**: Atualizada para consumir `/api/cadastro-fot` em vez de dados mockados.
|
||||||
|
- **Formulário de Criação (`FotForm.tsx`)**:
|
||||||
|
- Modal para criar novo FOT.
|
||||||
|
- Dropdowns (Selects) conectados dinamicamente às APIs `/api/empresas`, `/api/cursos`, `/api/anos-formaturas`.
|
||||||
|
- Validação e envio dos dados para o backend.
|
||||||
|
|
||||||
|
### 3.3. API Service
|
||||||
|
- **`apiService.ts`**: Centralização das chamadas HTTP. Adicionadas funções para buscar cursos, anos de formatura, criar FOT, etc.
|
||||||
|
|
||||||
|
## 4. Próximos Passos Sugeridos
|
||||||
|
1. **Frontend Agenda**: Criar a interface para visualizar e editar a Agenda (`Calendar` ou `List View`), consumindo os endpoints `/api/agenda` já criados.
|
||||||
|
2. **Validações Avançadas**: Implementar regras de negócio mais complexas no backend (ex: conflito de horários).
|
||||||
|
3. **Relatórios**: Gerar PDFs ou Excels baseados nos dados de FOT e Agenda.
|
||||||
Loading…
Reference in a new issue