Development Guide
This guide covers how to set up and run DiscordDataMirror locally.
Prerequisites
Required Software
| Tool | Version | Notes |
|---|---|---|
| .NET SDK | 10.0+ | Download |
| Docker Desktop | Latest | Download |
| Git | Latest | Download |
Verify Installation
# Check .NET version
dotnet --version
# Should output: 10.x.x
# Check Docker
docker --version
docker compose version
# Verify Docker is running
docker ps
Quick Start
# 1. Clone the repository
git clone <repo-url>
cd DiscordDataMirror
# 2. Configure Discord bot token
.\scripts\setup-bot.ps1
# 3. Run with Aspire
cd src\DiscordDataMirror.AppHost
dotnet run
Project Structure
DiscordDataMirror/
├── src/
│ ├── DiscordDataMirror.AppHost/ # Aspire orchestrator (start here!)
│ ├── DiscordDataMirror.ServiceDefaults/ # Shared Aspire configuration
│ ├── DiscordDataMirror.Domain/ # Domain entities, value objects
│ ├── DiscordDataMirror.Application/ # CQRS commands, queries, handlers
│ ├── DiscordDataMirror.Infrastructure/ # EF Core, Discord.Net, repositories
│ ├── DiscordDataMirror.Bot/ # Discord bot worker service
│ └── DiscordDataMirror.Dashboard/ # Blazor web dashboard
├── tests/ # Unit and integration tests
├── scripts/ # Setup and utility scripts
└── docs/ # Documentation
Configuration
Discord Bot Token
See BOT_SETUP.md for complete bot setup instructions.
Quick setup:
# Using the setup script (recommended)
.\scripts\setup-bot.ps1
# Or manually
cd src\DiscordDataMirror.Bot
dotnet user-secrets set "Discord:Token" "your-token-here"
Application Settings
Configuration is loaded from appsettings.json and can be overridden:
{
"Discord": {
"Token": "", // Set via user-secrets, not here!
"SyncOnStartup": true // Whether to sync historical data on startup
},
"Sync": {
"BatchSize": 100,
"DelayBetweenBatchesMs": 1000,
"MaxHistoricalMessages": 10000
}
}
Database Setup
DiscordDataMirror uses PostgreSQL via .NET Aspire. No manual setup required!
How It Works
- Aspire automatically provisions a PostgreSQL container
- Connection strings are injected automatically
- EF Core migrations run on startup
Manual Database Operations
# Create a new migration
cd src\DiscordDataMirror.Infrastructure
dotnet ef migrations add <MigrationName> --startup-project ..\DiscordDataMirror.Bot
# Apply migrations manually (usually automatic)
dotnet ef database update --startup-project ..\DiscordDataMirror.Bot
# Generate SQL script
dotnet ef migrations script --startup-project ..\DiscordDataMirror.Bot -o migration.sql
Database Connection
When running locally via Aspire:
- Host:
localhost - Port: Dynamically assigned (check Aspire dashboard)
- Database:
discorddatamirror - Credentials: Managed by Aspire
To connect manually, find the connection string in the Aspire dashboard.
Running the Application
Option 1: Full Stack via Aspire (Recommended)
cd src\DiscordDataMirror.AppHost
dotnet run
This starts:
- ✅ PostgreSQL database
- ✅ Discord bot worker
- ✅ Blazor dashboard
- ✅ Aspire dashboard (https://localhost:17113)
Option 2: Individual Services
For debugging specific services:
# Start database first (via Docker)
docker run -d --name discordmirror-db \
-e POSTGRES_PASSWORD=devpassword \
-e POSTGRES_DB=discorddatamirror \
-p 5432:5432 \
postgres:16
# Then run services individually
cd src\DiscordDataMirror.Bot
dotnet run
# In another terminal
cd src\DiscordDataMirror.Dashboard
dotnet run
Option 3: Docker Compose (Production-like)
docker compose up --build
Development Workflow
Building
# Build all projects
dotnet build
# Build specific project
dotnet build src\DiscordDataMirror.Bot
Running Tests
# Run all tests
dotnet test
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
# Run specific test project
dotnet test tests\DiscordDataMirror.Domain.Tests
Code Formatting
# Check formatting
dotnet format --verify-no-changes
# Fix formatting
dotnet format
Hot Reload
For the Dashboard (Blazor):
cd src\DiscordDataMirror.Dashboard
dotnet watch run
Note: The Bot worker service doesn't support hot reload well due to Discord connection state.
IDE Setup
Visual Studio 2022
- Open
DiscordDataMirror.sln - Set
DiscordDataMirror.AppHostas startup project - Press F5 to debug
Visual Studio Code
Recommended extensions:
- C# Dev Kit
- Docker
- REST Client
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch AppHost",
"type": "coreclr",
"request": "launch",
"program": "${workspaceFolder}/src/DiscordDataMirror.AppHost/bin/Debug/net10.0/DiscordDataMirror.AppHost.dll",
"cwd": "${workspaceFolder}/src/DiscordDataMirror.AppHost"
}
]
}
JetBrains Rider
- Open the solution
- Run/Debug
DiscordDataMirror.AppHost
Debugging
View Logs
- Aspire Dashboard: https://localhost:17113 → Traces/Logs
- Console: Logs stream to console when running
- Structured Logs: JSON format in production
Common Debug Scenarios
Bot not connecting:
# Check if token is set
cd src\DiscordDataMirror.Bot
dotnet user-secrets list
Database connection issues:
# Check if PostgreSQL container is running
docker ps | Select-String postgres
# View container logs
docker logs <container-id>
Memory issues with large syncs:
- Reduce
Sync:BatchSizein appsettings - Increase
Sync:DelayBetweenBatchesMs
Troubleshooting
Docker Issues
"Cannot connect to the Docker daemon"
- Start Docker Desktop
- Wait for it to fully initialize
- Check Docker settings if on Windows with WSL2
Port conflicts
# Find what's using a port
netstat -ano | findstr :5432
.NET Issues
"SDK not found"
- Ensure .NET 10 SDK is installed (not just runtime)
- Check
global.jsonmatches your SDK version
"User secrets not working"
# Initialize user secrets if needed
dotnet user-secrets init --project src\DiscordDataMirror.Bot
Database Issues
"Connection refused"
- Ensure PostgreSQL container is running
- Check Aspire dashboard for correct port
- Verify no firewall blocking
"Relation does not exist"
- Migrations haven't run
- Check startup logs for migration errors
- Try running migrations manually
Discord Issues
See BOT_SETUP.md troubleshooting section.
Architecture Notes
CQRS Pattern
Commands and queries are handled via MediatR:
Application/Commands/- Write operationsApplication/Queries/- Read operationsApplication/Handlers/- Business logic
Event Flow
Discord Gateway → DiscordEventHandler → MediatR Command → Handler → Repository → Database
Key Services
| Service | Responsibility |
|---|---|
DiscordClientService |
Manages Discord connection lifecycle |
DiscordEventHandler |
Converts Discord events to commands |
HistoricalSyncOrchestrator |
Backfills historical data |
Contributing
- Create a feature branch
- Make changes with tests
- Ensure
dotnet formatpasses - Submit PR