diff --git a/Backend/Backend.csproj b/Backend/Backend.csproj
index 106d073..c5aa143 100644
--- a/Backend/Backend.csproj
+++ b/Backend/Backend.csproj
@@ -10,6 +10,8 @@
+
+
diff --git a/Backend/Database/PostgresDbContext.cs b/Backend/Database/PostgresDbContext.cs
new file mode 100644
index 0000000..eff0cac
--- /dev/null
+++ b/Backend/Database/PostgresDbContext.cs
@@ -0,0 +1,23 @@
+using Backend.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace Backend.Database;
+
+///
+/// Contains all information on the postgresql database, for the object-database mapping.
+/// This allows using C# to run SQL queries on the database.
+///
+public class PostgresDbContext : DbContext
+{
+ /// Reference to the Activities relational table.
+ public DbSet Activities { get; set; }
+ /// Reference to the Enrollments relational table.
+ public DbSet Enrollments { get; set; }
+
+ ///
+ /// Creates information how to set up the object-database mapping, from C# to SQL, on the postgresql database.
+ ///
+ /// All parameters that define the database connection.
+ public PostgresDbContext(DbContextOptions options) : base(options)
+ { }
+}
diff --git a/Backend/Models/Activity.cs b/Backend/Models/Activity.cs
index 2a40159..2f6d774 100644
--- a/Backend/Models/Activity.cs
+++ b/Backend/Models/Activity.cs
@@ -1,6 +1,9 @@
+using Microsoft.EntityFrameworkCore;
+
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
namespace Backend.Models;
+[PrimaryKey(nameof(Id))]
public class Activity
{
///
@@ -10,7 +13,7 @@ public class Activity
///
/// The name of the activity.
///
- public string Name { get; set; }
+ public string Name { get; set; } // TODO: set max string length for performance?
///
/// A description or arbitrary length, explaining everything there is to know about the activity.
///
diff --git a/Backend/Models/Participation.cs b/Backend/Models/Enrollment.cs
similarity index 84%
rename from Backend/Models/Participation.cs
rename to Backend/Models/Enrollment.cs
index 7b9b7fc..143cd9a 100644
--- a/Backend/Models/Participation.cs
+++ b/Backend/Models/Enrollment.cs
@@ -1,14 +1,14 @@
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
namespace Backend.Models;
-public class Participation
+public class Enrollment
{
///
- /// Reference to the unique identifier of the activity which is participated.
+ /// Reference to the unique identifier of the activity which is enrolled for.
///
public uint ActivityId { get; set; }
///
- /// The ID of the user, as determined by the used OAuth application, which participated in the activity.
+ /// The ID of the user, as determined by the used OAuth application, which enrolls for the activity.
///
public string UserId { get; set; }
}
diff --git a/Backend/Program.cs b/Backend/Program.cs
index 61ad702..5c4944b 100644
--- a/Backend/Program.cs
+++ b/Backend/Program.cs
@@ -1,4 +1,6 @@
+using Backend.Database;
using Backend.Models;
+using Microsoft.AspNetCore.Http.HttpResults;
var builder = WebApplication.CreateBuilder(args);
@@ -6,6 +8,7 @@
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
+builder.Services.AddNpgsql(connectionString: builder.Configuration.GetConnectionString("Postgresql"));
var app = builder.Build();
@@ -18,17 +21,41 @@
app.UseHttpsRedirection();
-app.MapGet("/activity", (uint activityId) =>
+app.MapGet("/activity", async (PostgresDbContext db, uint activityId) =>
{
- return new Activity()
- {
- Id = activityId,
- Name = "Some activity",
- Description = "Some activity description",
- DateTimeStart = DateTimeOffset.Now,
- };
+ // Simply fetch and return
+ Activity? activity = await db.Activities.FindAsync(activityId);
+ return activity != null ? Results.Ok(activity) : Results.NotFound();
+ })
+ // .WithName("GetWeatherForecast")
+ .WithOpenApi();
+
+app.MapPost("/activity", async (PostgresDbContext db, Activity activity) =>
+ {
+ // First, ensure activity with same id does not exist yet
+ Activity? currentActivity = await db.Activities.FindAsync(activity.Id);
+ if (currentActivity != null)
+ return Results.BadRequest("Activity already exists with this Id.");
+
+ // Activity does not exist yet, create it
+ db.Activities.Add(activity);
+ await db.SaveChangesAsync();
+ return Results.Ok(activity.Id);
+ })
+ .WithOpenApi();
+
+app.MapDelete("/activity", async (PostgresDbContext db, uint activityId) =>
+ {
+ // First, check if activity exists
+ Activity? activity = await db.Activities.FindAsync(activityId);
+ if (activity == null)
+ return Results.NotFound();
+
+ // Remove activity
+ db.Activities.Remove(activity);
+ await db.SaveChangesAsync();
+ return Results.Ok();
})
- .WithName("GetWeatherForecast")
.WithOpenApi();
app.Run();
diff --git a/Backend/Tavern.http b/Backend/Tavern.http
index 69f67b3..bb68d22 100644
--- a/Backend/Tavern.http
+++ b/Backend/Tavern.http
@@ -1,6 +1,6 @@
-@Tavern_HostAddress = http://localhost:5273
+@Tavern_HostAddress = http://localhost:8080
-GET {{Tavern_HostAddress}}/weatherforecast/
+GET {{Tavern_HostAddress}}/activity?activityId=1
Accept: application/json
###
diff --git a/Backend/appsettings.json b/Backend/appsettings.json
index 10f68b8..9a0ad70 100644
--- a/Backend/appsettings.json
+++ b/Backend/appsettings.json
@@ -1,4 +1,7 @@
{
+ "ConnectionStrings": {
+ "Postgresql": "postgres"
+ },
"Logging": {
"LogLevel": {
"Default": "Information",
diff --git a/compose.yaml b/compose.yaml
index aa75dd2..71b097c 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -1,6 +1,26 @@
services:
- tavern-backend:
- image: backend
+ backend:
+ restart: unless-stopped
+ ports:
+ - "8080:8080"
build:
context: .
dockerfile: Backend/Dockerfile
+ networks:
+ - postgres-network
+
+ postgres:
+ image: postgres:17
+ restart: always
+ environment:
+ POSTGRES_PASSWORD: docker-secret # TODO: use docker secrets to store this password
+ volumes:
+ - postgres-data:$PGDATA
+ networks:
+ - postgres-network
+
+volumes:
+ postgres-data:
+
+networks:
+ postgres-network:
\ No newline at end of file