Skip to content

Feature/11 api postgres - #43

Open
Lightsul wants to merge 5 commits into
developfrom
feature/11-api-postgres
Open

Lightsul wants to merge 5 commits into
developfrom
feature/11-api-postgres

Conversation

@Lightsul

@Lightsul Lightsul commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #11

Overview

Base de l'API centrale et connexion à PostgreSQL.

  • Retrait du template WeatherForecast
  • MoissonDbContext (vide pour l'instant, le schéma viendra avec son issue)
  • Chaîne de connexion lue depuis la configuration : user-secrets en local, variable d'environnement ConnectionStrings__Moisson` sinon. L'API refuse de démarrer si elle est absente.
  • Endpoint /health qui vérifie la connexion à la base (Healthy 200 / Unhealthy 503)
  • Correction d'un conflit de versions d'EF Core entre Api et Tests
  • Tests d'intégration de /health (WebApplicationFactory + Testcontainers)

Tests automatisés

dotnet test` : 3/3 réussis (Docker requis pour Testcontainers)
tests/MoissonMontreal.Tests/Api/HealthEndpointTests.cs

Checklist

| Critère | Test | Résultat |
| The API runs locally | dotnet run --project src/MoissonMontreal.Api | ✅ Now listening on: http://localhost:5297 |
| Health endpoint reports DB reachability | curl -i localhost:5297/health avec la base allumée | ✅ 200 OK + Healthy |
| | docker compose stop db puis curl -i localhost:5297/health | ✅ 503 Service Unavailable + Unhealthy |
| No credentials committed | git grep -n "Password=" -- ':!compose.yaml' | ✅ aucun résultat |

- Retire le template WeatherForecast (contrôleur, modèle, requête .http)
- Ajoute MoissonDbContext dans Data/ et l'enregistre avec Npgsql
- Lit ConnectionStrings:Moisson depuis la configuration (user-secrets en local, variables d'environnement sinon) ; l'API refuse de démarrer si la chaîne est absente
- Fixe Microsoft.EntityFrameworkCore.Relational en 10.0.13 pour régler le conflit de versions d'EF Core dans Tests
- Ajoute le package HealthChecks.EntityFrameworkCore 10.0.13
- Expose /health : Healthy (200) si PostgreSQL répond, Unhealthy (503) sinon
- Rend le message d'erreur de connexion autonome (commande user-secrets incluse)
- WebApplicationFactory pour démarrer l'API en mémoire
- Testcontainers pour une base PostgreSQL 17 jetable
- Vérifie Healthy (200) quand la base répond et Unhealthy (503) quand elle est injoignable
@Lightsul Lightsul self-assigned this Oct 28, 2026
@Lightsul Lightsul added this to the Sprint - 1 milestone Oct 28, 2026
@Lightsul Lightsul linked an issue Oct 28, 2026 that may be closed by this pull request
4 of 7 tasks
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.13" />

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Microsoft.EntityFrameworkCore.Relational 10.0.13 is already provided by Npgsql

Suggested change
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.13" />

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bien vu, merci ! Je l'avais ajouté pour régler un conflit de versions EF Core (10.0.4 vs 10.0.13) dans le projet Tests, mais depuis l'ajout de HealthChecks.EntityFrameworkCore 10.0.13 il est redondant.

Comment on lines 14 to +37
@@ -20,4 +34,6 @@

app.MapControllers();

app.MapHealthChecks("/health");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MVC configuration is currently pointless, but we will most likely add controllers soon. We can keep them for now

Comment thread src/MoissonMontreal.Api/Program.cs Outdated
Comment on lines +9 to +10
"La chaîne de connexion 'Moisson' est absente. Définissez ConnectionStrings__Moisson " +
"ou utilisez 'dotnet user-secrets'. ");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove space at the end of error message

Suggested change
"La chaîne de connexion 'Moisson' est absente. Définissez ConnectionStrings__Moisson " +
"ou utilisez 'dotnet user-secrets'. ");
"La chaîne de connexion 'Moisson' est absente. Définissez ConnectionStrings__Moisson " +
"ou utilisez 'dotnet user-secrets'.");

- Déjà fournie en 10.0.13 via HealthChecks.EntityFrameworkCore
- Retire un espace en trop dans le message d'erreur de connexion

@lauriechammah lauriechammah left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall good. For the future, make sure that your PR and commit messages are written in English.

Please fix the issues I have mentioned in my comments. Thank you! :)


var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("Moisson")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cloning the repo causes a crash on dotnet run: ConnectionStrings:Moisson isn't defined anywhere, even though compose.yaml already sets the dev credentials. Could we add the local dev connection string to appsettings.Development.json?

"ConnectionStrings": {
  "Moisson": "Host=localhost;Port=5432;Database=moisson_dev;Username=moisson;Password=moisson"
}

These are local-only Docker credentials, so committing them is fine. User-secrets/env vars can still override them.



// Add services to the container.
builder.Services.AddDbContext<MoissonDbContext>(options => options.UseNpgsql(connectionString));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads-up for the migrations issue: because the connection string is read and validated at startup (line 7), dotnet ef migrations add will throw on any machine/CI without the secret, since EF runs Program to build the DbContext. Fixing the dev config (comment above) mostly solves it. Otherwise, add an IDesignTimeDbContextFactory.


app.MapControllers();

app.MapHealthChecks("/health");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/health sits behind UseHttpsRedirection(), so an HTTP health probe (Docker, Kubernetes, load balancer) gets a 307 instead of the status and may mark the service as down. Not a problem today, but worth keeping in mind when we deploy (e.g. skip the redirect for /health).


public class HealthEndpointTests : IAsyncLifetime
{
private readonly PostgreSqlContainer _postgres = new PostgreSqlBuilder("postgres:17").Build();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xUnit creates a new instance of the class per test, so this starts a new Postgres container for each test (including the "unreachable" one, which doesn't use it). Moving the container into a shared IClassFixture<PostgresFixture> would start it only once and speed up the suite.


namespace MoissonMontreal.Tests.Api;

public class HealthEndpointTests : IAsyncLifetime

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests require Docker to be running, otherwise dotnet test fails with DockerUnavailableException. Could we tag them (e.g. [Trait("Category", "Integration")]) so they can be filtered, and mention the Docker requirement in the README?

public async Task Health_RetourneUnhealthy_QuandLaBaseEstInjoignable()
{
// Rien n'écoute sur le port 1 : la connexion échoue immédiatement.
await using var factory = CreerFactory("Host=localhost;Port=1;Database=inexistante;Username=test;Timeout=2");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: localhost can resolve to both ::1 and 127.0.0.1, and some CI firewalls drop packets instead of refusing them, so this can wait for the timeout twice instead of failing immediately. Using Host=127.0.0.1 makes it more predictable.

@anis022
anis022 requested review from anis022 and removed request for anis022 October 28, 2026 19:46

@anis022 anis022 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lauriechammah requested changes cover pretty much everything that needs to be addressed. Other than that, looks good to me. Great work.

@anis022
anis022 requested review from MarcAntoineGmd and removed request for MarcAntoineGmd October 28, 2026 20:00
@maayjayy maayjayy mentioned this pull request Oct 29, 2026
6 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Issue]: Central ASP.NET Core API with PostgreSQL connection

3 participants