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
5 changes: 5 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"enabledPlugins": {
"mongodb@claude-plugins-official": true
}
}
31 changes: 31 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "mongodb-dotnet-example",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspaces/mongodb-dotnet-example",
"customizations": {
"vscode": {
"extensions": [
"ms-dotnettools.csharp",
"mongodb.mongodb-vscode"
]
}
},
"forwardPorts": [5000, 27017],
"portsAttributes": {
"5000": {
"label": "ASP.NET API"
},
"27017": {
"label": "MongoDB Atlas Local"
}
},
"remoteEnv": {
"GamesDatabaseSettings__ConnectionString": "mongodb://localhost:27017",
"GamesDatabaseSettings__DatabaseName": "GamesDB",
"GamesDatabaseSettings__GamesCollectionName": "Games",
"ASPNETCORE_ENVIRONMENT": "Development"
},
"postCreateCommand": "dotnet restore",
"postStartCommand": "echo 'Startup seed runs when the API starts (SEED_ON_STARTUP=true by default).'"
}
27 changes: 27 additions & 0 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
services:
app:
image: mcr.microsoft.com/devcontainers/dotnet:1-10.0-bookworm
volumes:
- ..:/workspaces/mongodb-dotnet-example:cached
command: sleep infinity
network_mode: service:mongodb
depends_on:
- mongodb

mongodb:
image: mongodb/mongodb-atlas-local:8.0.3-20250506T093411Z
restart: unless-stopped
volumes:
- mongodb-data:/data/db
- mongodb-config:/data/configdb
ports:
- "27017:27017"
healthcheck:
test: ["CMD-SHELL", "mongosh --eval \"db.adminCommand({ ping: 1 })\" || exit 1"]
interval: 10s
timeout: 5s
retries: 12

volumes:
mongodb-data:
mongodb-config:
70 changes: 70 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: ci

on:
push:
branches: [ main ]
pull_request:

jobs:
build-and-smoke:
runs-on: ubuntu-latest
strategy:
max-parallel: 1
matrix:
dotnet-version: ["10.0.x"]

services:
mongodb:
image: mongo:latest
ports:
- 27017:27017
options: >-
--health-cmd "mongosh --eval 'db.adminCommand({ ping: 1 })'"
--health-interval 10s
--health-timeout 5s
--health-retries 5

env:
GamesDatabaseSettings__ConnectionString: mongodb://localhost:27017
GamesDatabaseSettings__DatabaseName: GamesDB
GamesDatabaseSettings__GamesCollectionName: Games
ASPNETCORE_ENVIRONMENT: Development
ASPNETCORE_URLS: http://localhost:5050

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet-version }}

- name: Restore
run: dotnet restore

- name: Build
run: dotnet build --configuration Release --no-restore

- name: Test
run: dotnet test tests/MongodbDotnetExample.Tests/MongodbDotnetExample.Tests.csproj --configuration Release --no-restore

- name: Start API
run: dotnet run --configuration Release --no-build --no-launch-profile > /tmp/server.log 2>&1 &

- name: Wait for health
run: |
for i in {1..45}; do
if curl -fsS http://localhost:5050/healthz >/dev/null; then
exit 0
fi
sleep 2
done
cat /tmp/server.log
exit 1

- name: Verify seeded data endpoint
run: |
body=$(curl -fsS http://localhost:5050/api/games)
echo "$body"
echo "$body" | grep -q "Celeste"
71 changes: 71 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# AGENTS.md

This file guides coding agents working in this repository.

## Build And Test Commands

```bash
dotnet restore
dotnet build
dotnet test tests/MongodbDotnetExample.Tests/MongodbDotnetExample.Tests.csproj
dotnet run --urls http://localhost:5000
```

This repository has an xUnit test suite plus the smoke checks below.

If port 5000 is already in use, stop the conflicting process or pass a different port via `--urls`; do not change the default port in source code.

After any change that affects runtime behavior (`Program.cs`, `Startup.cs`, `Controllers`, `Services`, or `Models`), start the server and run the two curl commands below. Both must return HTTP 200 before considering the task complete.

```bash
curl http://localhost:5000/healthz
curl http://localhost:5000/api/games
```

If the server fails to connect to MongoDB, verify the `.devcontainer` Atlas Local instance is running and that `GamesDatabaseSettings__ConnectionString` is set. Do not modify application code to bypass the connection failure.

## Style

Run `dotnet format` before completing any C# code change.

## Project Structure

- `Program.cs`, `Startup.cs`: ASP.NET Core host and middleware pipeline
- `Controllers/GamesController.cs`: REST routes for `Game` CRUD
- `Services/GamesService.cs`: MongoDB access layer and seed helper
- `Models/Game.cs`: MongoDB document model
- `Models/GamesDatabaseSettings.cs`: bound configuration schema
- `Models/GameSeedData.cs`: default dataset inserted when collection is empty
- `.devcontainer/`: local dev environment with Atlas Local
- `.github/workflows/ci.yml`: build and integration smoke checks
- `EDD.md`: MongoDB data model contract

## Environment Variables And Configuration

Required configuration (via environment variables or appsettings):

- `GamesDatabaseSettings__ConnectionString` (example: `mongodb://localhost:27017`)
- `GamesDatabaseSettings__DatabaseName` (example: `GamesDB`)
- `GamesDatabaseSettings__GamesCollectionName` (example: `Games`)

Optional:

- `SEED_ON_STARTUP` (`true` by default; set `false` to disable startup seeding)
- `ASPNETCORE_ENVIRONMENT` (`Development`, `Production`, etc.)

## MongoDB Skills

Before performing MongoDB schema, query, aggregation, or index work, fetch the skill index from https://github.com/mongodb/agent-skills and use any skill whose description matches the task. If no matching skill is found, proceed without one and note this in your response.

## When To Use EDD.md

Use [EDD.md](./EDD.md) as the source of truth for the MongoDB data model in this repository.

Consult [EDD.md](./EDD.md) before making changes that touch:

- MongoDB collections, document structure, or field names
- ASP.NET Core controllers and service methods that read or write database records
- Validation, form fields, API payloads, or UI that depend on persisted data
- Schema documentation, Mermaid diagrams, or entity modeling discussions

If `EDD.md` and the C# model code disagree, treat `EDD.md` as authoritative and update the C# model to match, then call out the discrepancy in your response.
4 changes: 2 additions & 2 deletions Controllers/GamesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ namespace mongodb_dotnet_example.Controllers
[ApiController]
public class GamesController : ControllerBase
{
private readonly GamesService _gameService;
private readonly IGamesService _gameService;

public GamesController(GamesService gamesService)
public GamesController(IGamesService gamesService)
{
_gameService = gamesService;
}
Expand Down
55 changes: 55 additions & 0 deletions EDD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# EDD.md

Entity Document Diagram for `mongodb-dotnet-example`.

## Metadata

- Database: `GamesDB`
- Primary Collection: `Games`
- Source of truth in code: `Models/Game.cs`, `Services/GamesService.cs`

## Entity: Game

Collection: `Games`

### Fields

| Field | BSON Type | C# Type | Required | Notes |
|---|---|---|---|---|
| `_id` | `ObjectId` | `string` (`[BsonRepresentation(ObjectId)]`) | Yes | MongoDB primary key |
| `Name` | `String` | `string` | Yes | Serialized with `[BsonElement("Name")]` |
| `Price` | `Decimal128` or numeric-compatible | `decimal` | Yes | Monetary value |
| `Category` | `String` | `string` | Yes | Game genre/category |

### Indexes

- Default unique index on `_id`
- No additional secondary indexes are defined by application code

### Validation And Constraints

- Route constraints require `id` values to have length 24 for get/update/delete endpoints
- No MongoDB schema validator is currently configured in code

### Seed Behavior

- On API startup, if `SEED_ON_STARTUP` is not `false`, the app checks collection emptiness
- If empty, inserts default records from `Models/GameSeedData.cs`
- Seed operation is idempotent by emptiness guard

## Relationships

- `Game` has no document references in current data model
- Single-collection design

## Mermaid Diagram

```mermaid
erDiagram
GAMES {
ObjectId _id PK
string Name
decimal Price
string Category
}
```
16 changes: 16 additions & 0 deletions Models/GameSeedData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Collections.Generic;

namespace mongodb_dotnet_example.Models
{
public static class GameSeedData
{
public static readonly IReadOnlyList<Game> DefaultGames = new List<Game>
{
new Game { Name = "Celeste", Price = 19.99m, Category = "Platformer" },
new Game { Name = "Hades", Price = 24.99m, Category = "Roguelike" },
new Game { Name = "Stardew Valley", Price = 14.99m, Category = "Simulation" },
new Game { Name = "Forza Horizon 5", Price = 59.99m, Category = "Racing" },
new Game { Name = "Minecraft", Price = 29.99m, Category = "Sandbox" }
};
}
}
2 changes: 1 addition & 1 deletion Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"mongodb_dotnet_example": {
"commandName": "Project",
"dotnetRunMessages": "true",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
Expand Down
Loading
Loading