Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 143 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,147 @@

[![codecov](https://codecov.io/gh/ClassConnect-org/courses-microservice/graph/badge.svg?token=35RXOMF06U)](https://codecov.io/gh/ClassConnect-org/courses-microservice)

### Test Coverage Grid
Este repositorio es parte del backend de la aplicacion class-connect, para conocer informacion mas general sobre
el proyecto visita el siguiente link [Organization Homepage](https://github.com/ClassConnect-org).

![coverage grid](https://codecov.io/gh/ClassConnect-org/courses-microservice/graphs/tree.svg?token=35RXOMF06U)
## Descripcion

Este microservicio es el nucleo de la aplicacion y se ocupa de todas las operaciones relacionadas con cursos, incluyendo
el manejo de inscripciones, examenes, tareas, modulos organizables por los profesores, estadisticas por curso, entre otras.

## Endpoints

Los endpoints de este microservicio se pueden encontrar en el [swagger](http://172.233.5.227/courses/swagger/index.html) del mismo (o alternativamente en la carpeta `docs/`),
los mismos son:

#### Swagger

* `GET` /swagger/index.html (Documentacion de la API)

#### Cursos

* `GET` **/** (Listar cursos con filtros aplicables)
* `POST` **/** (Agregar curso)

* `GET` **/aux/logs/{id}** (Obtener registros del profesor auxiliar)
* `PUT` **/aux/{id}/{professor_id}** (Agregar o eliminar profesor auxiliar)

* `PUT` **/picture/{id}** (Agregar imagen al curso)
* `DELETE` **/picture/{id}** (Eliminar imagen del curso)

* `GET` **/session** (Listar cursos de la sesión)

* `PATCH` **/status/{id}** (Cambiar estado del curso)

* `GET` **/students/{id}** (Obtener información del estudiante)

* `GET` **/{id}** (Obtener curso por ID)
* `DELETE` **/{id}** (Eliminar curso)
* `PATCH` **/{id}** (Actualizar curso)

#### Inscripciones

* `GET` **/enrollments/{id}** (Inscribir estudiante)
* `DELETE` **/enrollments/{id}/{student_id}** (Desinscribir estudiante)

#### Módulos

* `PUT` **/modules/attachment/{id}** (Agregar archivo adjunto a un módulo)
* `DELETE` **/modules/attachment/{id}/{attachment_pos}** (Eliminar archivo adjunto de un módulo)

* `GET` **/modules/{id}** (Obtener módulos por curso)

* `PUT` **/modules/{id}** (Organizar posiciones de módulos)
* `POST` **/modules/{id}** (Crear un módulo nuevo)
* `DELETE` **/modules/{id}** (Eliminar un módulo)
* `PATCH` **/modules/{id}** (Modificar un módulo existente)

#### Tareas

* `GET` **/assignments** (Listar tareas de la sesión actual)

* `PUT` **/assignments/attachment/{id}** (Agregar archivo adjunto a la tarea)
* `DELETE` **/assignments/attachment/{id}/{attachment_pos}** (Eliminar archivo adjunto de la tarea)

* `GET` **/assignments/course/{id}** (Listar tareas por curso)

* `GET` **/assignments/{id}** (Obtener tarea por ID)
* `POST` **/assignments/{id}** (Crear tarea)
* `DELETE` **/assignments/{id}** (Eliminar tarea)
* `PATCH` **/assignments/{id}** (Actualizar tarea)

#### Entregas de tareas

* `POST` **/assignments/submission/review/{id}** (Revisar entrega de tarea)

* `GET` **/assignments/submission/states/{id}** (Obtener estados de la tarea por ID)

* `GET` **/assignments/submission/{id}** (Obtener entrega de tarea por ID)
* `POST` **/assignments/submission/{id}** (Enviar entrega de tarea)

#### Exámenes

* `GET` **/exams** (Obtener exámenes de la sesión)
* `GET` **/exams/course/{id}** (Obtener exámenes por curso)

* `GET` **/exams/{id}** (Obtener examen por ID)
* `POST` **/exams/{id}** (Crear examen)
* `DELETE` **/exams/{id}** (Eliminar examen)
* `PATCH` **/exams/{id}** (Modificar examen)

#### Entregas de exámenes

* `POST` **/exams/submission/review/{id}** (Revisar entrega de examen)

* `GET` **/exams/submission/states/{id}** (Obtener estados del examen por ID)

* `GET` **/exams/submission/{id}** (Obtener entrega de examen por ID)
* `POST` **/exams/submission/{id}** (Enviar entrega de examen)

#### Estadísticas

* `GET` **/stats/{id}** (Obtener estadísticas del curso)
* `GET` **/stats/{id}/{student_id}** (Obtener estadísticas de un estudiante)

## Estructura

Se utiliza la arquitectura package by layer, donde los controladores se pueden encontrar en la
carpeta *handlers*, los servicios en *services* y los repositorios en *repository*.

Para cada grupo de rutas hay una interfaz para el Handler y otra para el Service.

En la carpeta *models* se encuentran las representaciones en estructura de datos de cada tabla en la base de datos.
A su vez en la carpeta *dto* se encuentran las representaciones de datos que se envian al cliente y se reciven del mismo.

Todos los cambios a la base de datos estan registrados en la carpeta *migrations*, donde cada
migracion tiene su `up.sql` (accion creativa) y `down.sql` (accion desctructiva).

## Desarrollo

### Docker-compose de uso local

Para correr el microservicio en un entorno de desarrollo local (con base de datos local incluida),
se puede utilizar el siguiente comando:

```bash
docker compose -f local-dev-compose.yml up --build
```

### Migraciones

Para crear una migracion para cambiar tablas/entradas de la base de datos, se utiliza el comando go-migrate de la siguiente manera:

```bash
# Instalar go-migrate si no se tiene instalado
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest

# Crear una migracion nueva (alternativamente, crear archivos manualmente con el nombre deseado)
migrate create -ext sql -dir ./migrations -seq migration_name
```

## Despliegue

1. Se hace feature branching desde la rama **dev**.
2. Una vez listo para integrar se realiza PR a **dev**, donde corre el pipeline de testing y coverage.
3. Una vez esta listo para desplegar se realiza PR a **main**, se vuelven a correr pipelines de calidad de codigo.
4. Cuando se hace el push a **main** se ejecuta el pipeline de continous delivery, construye la imagen y la desplega a k8s.
9 changes: 4 additions & 5 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ package main

import (
"courses-microservice/config"
"courses-microservice/internal/router"
"courses-microservice/internal/server"
"log"
)

Expand All @@ -22,9 +22,8 @@ func main() {
if err != nil {
log.Fatalf("Failed to connect to the database: %v", err)
}
r := router.Create_router(db, conf)
err = r.Run()
if err != nil {
log.Fatalf("Failed to connect to the database: %v", err)
sv := server.NewServer(conf, db)
if err := sv.Run(); err != nil {
log.Fatalf("Failed to run the server: %v", err)
}
}
12 changes: 12 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const (
type Config struct {
// Server config
ENVIRONMENT Environment
SV_ADDR string
SV_PORT string

NOTIFICATIONS_SERVICE string

Expand All @@ -36,11 +38,18 @@ type Config struct {

// Authentication config
JWT_SECRET string

// Datadog
DD_SERVICE_NAME string
DD_AGENT_HOST string
DD_AGENT_PORT string
}

func LoadConfig() *Config {
return &Config{
ENVIRONMENT: getServerEnvironment(),
SV_ADDR: getEnvOrDefault("ADDR", "0.0.0.0"),
SV_PORT: getEnvOrDefault("PORT", "8080"),
NOTIFICATIONS_SERVICE: "http://" + getEnvOrDefault("NOTIFICATIONS_SERVICE", "") + ":8000",
DB_URL: getEnvOrDefault("DB_URL", ""),
STORAGE_URL: getEnvOrDefault("STORAGE_URL", ""),
Expand All @@ -50,6 +59,9 @@ func LoadConfig() *Config {
PICTURES_BUCKET_NAME: getEnvOrDefault("PICTURES_BUCKET_NAME", "course-pictures"),
MAX_FILE_SIZE: getEnvOrDefaultInt64("MAX_FILE_SIZE", 10*1024*1024), // Default to 10MB
JWT_SECRET: getEnvOrDefault("JWT_SECRET", "default_secret"),
DD_SERVICE_NAME: getEnvOrDefault("DD_SERVICE_NAME", "users-microservice"),
DD_AGENT_HOST: getEnvOrDefault("DD_AGENT_HOST", "localhost"),
DD_AGENT_PORT: getEnvOrDefault("DD_AGENT_PORT", "8126"),
}
}

Expand Down
87 changes: 71 additions & 16 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,53 @@ require (
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.4
gopkg.in/DataDog/dd-trace-go.v1 v1.74.0
)

require (
github.com/DataDog/appsec-internal-go v1.11.2 // indirect
github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.64.2 // indirect
github.com/DataDog/datadog-agent/pkg/obfuscate v0.64.2 // indirect
github.com/DataDog/datadog-agent/pkg/proto v0.64.2 // indirect
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.64.2 // indirect
github.com/DataDog/datadog-agent/pkg/trace v0.64.2 // indirect
github.com/DataDog/datadog-agent/pkg/util/log v0.64.2 // indirect
github.com/DataDog/datadog-agent/pkg/util/scrubber v0.64.2 // indirect
github.com/DataDog/datadog-agent/pkg/version v0.64.2 // indirect
github.com/DataDog/datadog-go/v5 v5.6.0 // indirect
github.com/DataDog/dd-trace-go/v2 v2.0.0 // indirect
github.com/DataDog/go-libddwaf/v3 v3.5.4 // indirect
github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250319104955-81009b9bad14 // indirect
github.com/DataDog/go-sqllexer v0.1.3 // indirect
github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect
github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.26.0 // indirect
github.com/DataDog/sketches-go v1.4.7 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/Masterminds/semver/v3 v3.3.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/bytedance/sonic v1.13.2 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect
github.com/ebitengine/purego v0.8.3 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/gin-contrib/sse v1.0.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/spec v0.20.4 // indirect
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.26.0 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
Expand All @@ -48,23 +75,51 @@ require (
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect
github.com/shirou/gopsutil/v4 v4.25.3 // indirect
github.com/tinylib/msgp v1.2.5 // indirect
github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
go.uber.org/atomic v1.7.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opentelemetry.io/collector/component v1.27.0 // indirect
go.opentelemetry.io/collector/pdata v1.27.0 // indirect
go.opentelemetry.io/collector/pdata/pprofile v0.121.0 // indirect
go.opentelemetry.io/collector/semconv v0.123.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/arch v0.15.0 // indirect
golang.org/x/crypto v0.36.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/sync v0.13.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/text v0.24.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.32.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect
google.golang.org/grpc v1.70.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading