commit 213c9480e727a26b0f373500baf850fe73178597 Author: Pedro Pérez Date: Wed Oct 22 00:45:18 2025 +0200 kickstart diff --git a/.docker.env b/.docker.env new file mode 100644 index 0000000..b18b0f7 --- /dev/null +++ b/.docker.env @@ -0,0 +1,2 @@ +POSTGRES_USER=developer +POSTGRES_PW=secret diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..49d1813 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.sqlfluff diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4fda387 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +SERVICE_A := ./service_a +SERVICE_B := ./service_b +PG_VERSION := 17.6-alpine3.22 +DB_NAME := meteologica + +.PHONY: dockerize-db +# Remove and create a development database. +dockerize-db: + docker rm -f $(DB_NAME) + docker run --name $(DB_NAME) -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=developer -e POSTGRES_DB=$(DB_NAME) -p 5432:5432 -d postgres:$(PG_VERSION) + sleep 10 + make migrateup + +.PHONY: migrateup +# Migrate all schemas, triggers and data located in database/migrations. +migrateup: + go run -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest -path $(SERVICE_A)/server/database/migrations -database "postgresql://developer:secret@localhost:5432/$(DB_NAME)?sslmode=disable" -verbose up + +.PHONY: run +# Run all services +run: + go run ./service_a/server/main.go & go run ./service_b/server/main.go diff --git a/Meteologica_vacante_ProgramadorBackend_202510_datos.csv b/Meteologica_vacante_ProgramadorBackend_202510_datos.csv new file mode 100644 index 0000000..b4fd9ca --- /dev/null +++ b/Meteologica_vacante_ProgramadorBackend_202510_datos.csv @@ -0,0 +1,125 @@ +Fecha;Ciudad;Temperatura Máxima (C);Temperatura Mínima (C);Precipitación (mm);Nubosidad (%) +2025/10/12;Madrid;11,55;6,25;0;10 +2025/10/13;Madrid;12,35;5,25;0,2;60 +2025/10/14;Madrid;12,65;7,15;0;30 +2025/10/15;Madrid;15,75;5,85;1,4;80 +2025/10/16;Madrid;16,65;8,15;2,6;100 +2025/10/17;Madrid;16,35;8,05;0,3;50 +2025/10/18;Madrid;20,25;7,15;0,1;20 +2025/10/19;Madrid;22,35;8,65;0,1;10 +2025/10/20;Madrid;21,35;10,85;0;0 +2025/10/21;Madrid;20,25;10,45;0;10 +2025/10/22;Madrid;20,85;10,55;0;0 +2025/10/23;Madrid;21,95;11,25;0;0 +2025/10/24;Madrid;21,45;11,65;0;0 +2025/10/25;Madrid;22,65;12,45;0;0 +2025/10/26;Madrid;23,35;11,75;0;10 +2025/10/27;Madrid;22,45;11,85;0;30 +2025/10/28;Madrid;21,45;12,95;0,6;60 +2025/10/29;Madrid;17,45;11,25;1,2;90 +2025/10/30;Madrid;14,35;8,85;0;50 +2025/10/31;Madrid;13,65;6,05;0;10 +2025/11/01;Madrid;13,65;6,05;0;10 +2025/11/02;Madrid;14,65;6,15;0;0 +2025/11/03;Madrid;16,65;5,65;0;0 +2025/11/04;Madrid;18,65;9,45;0;0 +2025/11/05;Madrid;19,05;9,05;0;10 +2025/11/06;Madrid;22,25;9,85;0;30 +2025/11/07;Madrid;22,45;11,95;0,2;50 +2025/11/08;Madrid;21,75;12,85;0;0 +2025/11/09;Madrid;22,45;12,65;0;0 +2025/11/10;Madrid;22,45;12,55;0;10 +2025/11/11;Madrid;20,95;13,25;0;0 +2025/10/12;Sevilla;13.86;7,5;0;20 +2025/10/13;Sevilla;14.82;6,3;0,1;70 +2025/10/14;Sevilla;15.18;8,58;0;30 +2025/10/15;Sevilla;18.9;7,02;0,6;70 +2025/10/16;Sevilla;19.98;9,78;1,6;90 +2025/10/17;Sevilla;19.62;9,66;0,1;20 +2025/10/18;Sevilla;24.3;8,58;0;10 +2025/10/19;Sevilla;26.82;10,38;0;0 +2025/10/20;Sevilla;25.62;13,02;0;0 +2025/10/21;Sevilla;24.3;12,54;0,1;20 +2025/10/22;Sevilla;25.02;12,66;0;0 +2025/10/23;Sevilla;26.34;13,5;0;0 +2025/10/24;Sevilla;25.74;13,98;0;0 +2025/10/25;Sevilla;27.18;14,94;0;0 +2025/10/26;Sevilla;28.02;14,1;0;20 +2025/10/27;Sevilla;26.94;14,22;0,1;30 +2025/10/28;Sevilla;25.74;15,54;0,3;70 +2025/10/29;Sevilla;20.94;13,5;1;80 +2025/10/30;Sevilla;17.22;10,62;0,1;40 +2025/10/31;Sevilla;16.38;7,26;0;10 +2025/11/01;Sevilla;16.38;7,26;0;0 +2025/11/02;Sevilla;17.58;7,38;0;0 +2025/11/03;Sevilla;19.98;6,78;0;0 +2025/11/04;Sevilla;22.38;11,34;0;10 +2025/11/05;Sevilla;22.86;10,86;0;20 +2025/11/06;Sevilla;26.7;11,82;0;30 +2025/11/07;Sevilla;26.94;14,34;0;20 +2025/11/08;Sevilla;26.1;15,42;0;0 +2025/11/09;Sevilla;26.94;15,18;0;0 +2025/11/10;Sevilla;26.94;15,06;0;10 +2025/11/11;Sevilla;25.14;15,9;0;0 +2025/10/12;Gijón;9,24;5;0;20 +2025/10/13;Gijón;9,88;4,2;1,2;80 +2025/10/14;Gijón;10,12;5,72;0;30 +2025/10/15;Gijón;12,6;4,68;2,3;100 +2025/10/16;Gijón;13,32;6,52;3,2;100 +2025/10/17;Gijón;13,08;6,44;0,6;80 +2025/10/18;Gijón;16,2;5,72;0,4;40 +2025/10/19;Gijón;17,88;6,92;0,2;30 +2025/10/20;Gijón;17,08;8,68;0;20 +2025/10/21;Gijón;16,2;8,36;0,5;70 +2025/10/22;Gijón;16,68;8,44;0;20 +2025/10/23;Gijón;17,56;9;0;30 +2025/10/24;Gijón;17,16;9,32;0;20 +2025/10/25;Gijón;18,12;9,96;0;10 +2025/10/26; Gijón;18,68;9,4;0;10 +2025/10/27; Gijón;17,96;9,48;0,3;40 +2025/10/28; Gijón;17,16;10,36;0,9;70 +2025/10/29; Gijón;13,96;9;1,8;100 +2025/10/30; Gijón;11,48;7,08;0,6;90 +2025/10/31; Gijón;10,92;4,84;0;40 +2025/11/01; Gijón;10,92;4,84;0;30 +2025/11/02; Gijón;11,72;4,92;0;10 +2025/11/03; Gijón;13,32;4,52;0;10 +2025/11/04; Gijón;14,92;7,56;0;0 +2025/11/05; Gijón;15,24;7,24;0,1;20 +2025/11/06; Gijón;17,8;7,88;0,1;40 +2025/11/07; Gijón;17,96;9,56;0,6;70 +2025/11/08; Gijón;17,4;10,28;0,1;10 +2025/11/09; Gijón;17,96;10,12;0;0 +2025/11/10; Gijón;17,96;10,04;0,1;30 +2025/11/11; Gijón;16,76;10,6;0;0 +2025/10/12;Valencia;12,705;6,875;0,3;20 +2025/10/13;Valencia;13,585;5,775;0;20 +2025/10/14;Valencia;13,915;7,865;1,6;60 +2025/10/15;Valencia;17,325;6,435;3;100 +2025/10/16;Valencia;18,315;8,965;0,5;20 +2025/10/17;Valencia;17,985;8,855;0;10 +2025/10/18;Valencia;22,275;7,865;0;0 +2025/10/19;Valencia;24,585;9,515;0;0 +2025/10/20;Valencia;23,485;11,935;0;0 +2025/10/21;Valencia;22,275;11,495;0;0 +2025/10/22;Valencia;22,935;11,605;0;0 +2025/10/23;Valencia;24,145;12,375;0;0 +2025/10/24;Valencia;23,595;12,815;0;10 +2025/10/25;Valencia;24,915;13,695;0;10 +2025/10/26;Valencia;25,685;12,925;0;20 +2025/10/27;Valencia;24,695;13,035;0,8;40 +2025/10/28;Valencia;23,595;14,245;1,6;70 +2025/10/29;Valencia;19,195;12,375;0,8;90 +2025/10/30;Valencia;15,785;9,735;0,4;20 +2025/10/31;Valencia;15,015;6,655;;10 +2025/11/01;Valencia;15,015;6,655;;0 +2025/11/02;Valencia;16,115;6,765;;0 +2025/11/03;Valencia;18,315;6,215;;0 +2025/11/04;Valencia;20,515;10,395;;0 +2025/11/05;Valencia;20,955;9,955;;0 +2025/11/06;Valencia;24,475;10,835;0,5;30 +2025/11/07;Valencia;24,695;13,145;0;20 +2025/11/08;Valencia;23,925;14,135;0;0 +2025/11/09;Valencia;24,695;13,915;0;0 +2025/11/10;Valencia;24,695;13,805;0;0 +2025/11/11;Valencia;23,045;14,575;0;0 diff --git a/README.md b/README.md new file mode 100644 index 0000000..13f31d3 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# meteologica + +Prueba técnica para el puesto de desarrollador Go/C++ + +## Comandos útiles + +Compilar todos los servicios e iniciar los contenedores Docker. + +`docker compose --env-file up --build` + +## Entorno desarrollo + +Linux Fedora 41 6.16.11-200.fc42.x86_64 +Go 1.25.2 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..df67a5d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,29 @@ +services: + database: + container_name: database + image: postgres:17.6-alpine3.22 + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PW} + - POSTGRES_DB=meteologica + ports: + - "5432:5432" + restart: always + + service_a: + build: + context: ./service_a + dockerfile: Dockerfile + container_name: service_a + ports: + - "8080:8080" + restart: unless-stopped + + service_b: + build: + context: ./service_b + dockerfile: Dockerfile + container_name: service_b + ports: + - "8090:8090" + restart: unless-stopped diff --git a/service_a/Dockerfile b/service_a/Dockerfile new file mode 100644 index 0000000..11a17ff --- /dev/null +++ b/service_a/Dockerfile @@ -0,0 +1,19 @@ +FROM golang:1.25.2-alpine3.22 AS builder + +WORKDIR /app + +COPY go.mod ./ +COPY server/ ./server/ + +RUN go mod download +RUN go build -o /app/service_a ./server/main.go + +FROM alpine:latest + +WORKDIR /app + +COPY --from=builder /app/service_a /app/service_a + +EXPOSE 8080 + +CMD ["/app/service_a"] diff --git a/service_a/go.mod b/service_a/go.mod new file mode 100644 index 0000000..ade2ac6 --- /dev/null +++ b/service_a/go.mod @@ -0,0 +1,3 @@ +module servicea + +go 1.25.2 diff --git a/service_a/server/database/migrations/001_data.up.sql b/service_a/server/database/migrations/001_data.up.sql new file mode 100644 index 0000000..1b85500 --- /dev/null +++ b/service_a/server/database/migrations/001_data.up.sql @@ -0,0 +1,19 @@ +create table public.locations +( + id serial primary key, + location_name varchar(255) not null +); + + +create table public.temp_data +( + id serial primary key, + + location_id int not null references public.locations (id), + max_temp float not null, + min_temp float not null, + rainfall float not null, + cloudiness float not null, + + created_at timestamp not null default now() +); diff --git a/service_a/server/database/queries/queries.sql b/service_a/server/database/queries/queries.sql new file mode 100644 index 0000000..e036280 --- /dev/null +++ b/service_a/server/database/queries/queries.sql @@ -0,0 +1,2 @@ +-- name: DummyQuery :exec +select 1; diff --git a/service_a/server/main.go b/service_a/server/main.go new file mode 100644 index 0000000..7883799 --- /dev/null +++ b/service_a/server/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "log" + "net/http" +) + +func main() { + mux := http.NewServeMux() + + mux.HandleFunc("GET /hello", func(w http.ResponseWriter, r *http.Request) { + log.Println("Received request on /hello endpoint") + fmt.Fprintf(w, "Hello world from service A") + }) + + http.ListenAndServe(":8080", mux) +} diff --git a/service_b/Dockerfile b/service_b/Dockerfile new file mode 100644 index 0000000..39ecb91 --- /dev/null +++ b/service_b/Dockerfile @@ -0,0 +1,19 @@ +FROM golang:1.25.2-alpine3.22 AS builder + +WORKDIR /app + +COPY go.mod ./ +COPY server/ ./server/ + +RUN go mod download +RUN go build -o /app/service_b ./server/main.go + +FROM alpine:latest + +WORKDIR /app + +COPY --from=builder /app/service_b /app/service_b + +EXPOSE 8090 + +CMD ["/app/service_b"] diff --git a/service_b/go.mod b/service_b/go.mod new file mode 100644 index 0000000..34d6ee3 --- /dev/null +++ b/service_b/go.mod @@ -0,0 +1,3 @@ +module serviceb + +go 1.25.2 diff --git a/service_b/server/main.go b/service_b/server/main.go new file mode 100644 index 0000000..64c6a35 --- /dev/null +++ b/service_b/server/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "log" + "net/http" +) + +func main() { + mux := http.NewServeMux() + + mux.HandleFunc("GET /hello", func(w http.ResponseWriter, r *http.Request) { + log.Println("Received request on /hello endpoint") + fmt.Fprintf(w, "Hello world from service B") + }) + + http.ListenAndServe(":8090", mux) +}