Contributing to Reminders
July 29, 2026 · View on GitHub
Thank you for your interest in contributing to the Reminders project! This document provides guidelines and information for contributors.
Table of Contents
- Code of Conduct
- Change Workflow
- Getting Started
- Development Setup
- Project Structure
- Database Migrations
- Making Changes
- Testing
- Pull Request Process
Code of Conduct
This is a learning project, and we welcome contributions from developers of all skill levels. Please be respectful, constructive, and supportive of others.
Change Workflow
Every change follows the same path:
- Discussion (RFC): questions and ideas that need debate start as a GitHub Discussion.
- PRD: feature-sized work gets a one-page PRD in docs/product/ capturing problem, users, success criteria, and scope before implementation.
- ADR: decisions that shape architecture, workflow, or tooling are recorded in docs/adr/ before implementation.
- Issue: every piece of work maps to a GitHub Issue with explicit acceptance criteria. Check open issues before proposing new work.
- Branch: short-lived branch off
main, named<type>/<short-description>(e.g.feat/redis-cache). - PR: small and focused, follows the PR template, references the issue (
Closes #123). - Review: maintainer review is required (CODEOWNERS); CI must be green.
- Merge: squash merge onto
main, which must always stay releasable.
Small fixes can skip steps 1-3 and start at the issue. See ADR-0001 and ADR-0006 for the reasoning behind this workflow.
Getting Started
- Fork the repository on GitHub
- Clone your fork locally
- Create a new branch for your feature or bugfix
- Make your changes
- Test your changes
- Submit a pull request
Development Setup
Prerequisites
- Docker & Docker Compose
- .NET SDK 8.0
- Node.js 18+
- Git
Initial Setup
# Clone your fork
git clone https://github.com/YOUR_USERNAME/Reminders.git
cd Reminders
# Set up environment variables
cp .env.example .env
# Edit .env and configure your settings
# Start infrastructure services
docker compose --profile api up postgres ganache -d
# Build the API
cd src/server/api/dotnet/Reminders.Api
dotnet build
# Install React dependencies
cd ../../../../app/reactjs/reminders-app
npm install
Project Structure
Reminders/
├── blockchain/ # Hardhat smart contracts
│ ├── contracts/ # Solidity contracts
│ ├── scripts/ # Deployment scripts
│ └── test/ # Contract tests
├── docs/ # GitHub Pages documentation
├── infrastructure/ # Nginx configs, k6 tests
├── src/
│ ├── app/
│ │ ├── dotnet/ # ASP.NET MVC application
│ │ ├── flutter/ # Flutter mobile app (Android)
│ │ └── reactjs/ # Next.js React application
│ ├── server/
│ │ ├── api/
│ │ │ ├── dotnet/ # ASP.NET Core Web API
│ │ │ ├── go/ # Go (Gin) API
│ │ │ └── cpp/ # C++ API
│ │ └── services/dotnet/ # Migration runner service
│ └── test/
│ ├── cypress/ # E2E tests
│ └── server/dotnet/ # API unit tests
Database Migrations
Important: Dual Database Support
The project supports both PostgreSQL (default) and SQL Server. Migrations are stored separately:
- PostgreSQL:
src/server/api/dotnet/Reminders.Api/Layers/Data/EntityFramework/Postgres/Migrations/ - SQL Server:
src/server/api/dotnet/Reminders.Api/Layers/Data/EntityFramework/SqlServer/Migrations/
Expected Behavior
Migrations are applied by a dedicated migration runner service (src/server/services/dotnet/Reminders.MigrationsRunner/), not by the API itself. Docker Compose starts postgres, waits for it to report healthy, then runs migrations to completion before either API instance starts. When PostgreSQL is the active provider (default), the runner also attempts the SQL Server migration set and logs an expected failure for it - this is expected and harmless. Only the PostgreSQL migrations are actually applied.
How the Runner Works
- Technology: .NET 8.0 console app with an embedded HTTP health endpoint (
http://localhost:8081/healthz, development mode only). Runs once per deployment and exits, it is not a long-running service. - Order:
postgresstarts and reports healthy, thenmigrationsruns with retry logic (exponential backoff, 5 attempts, 2s base delay), and once it exits with code 0 bothdotnet-apiandgo-apistart (each depends onmigrationswithcondition: service_completed_successfully). - Health signal: the runner exposes HTTP 500 while running and HTTP 200 once migrations succeed.
Running Migrations Manually
Local development (without Docker):
cd src/server/services/dotnet/Reminders.MigrationsRunner
export ConnectionStrings__DefaultConnection="Host=localhost;Database=Reminders;Username=postgres;Password=yourpassword"
export DatabaseProvider="Postgres"
dotnet run
# check health endpoint in another terminal
curl http://localhost:8081/healthz
Via Docker Compose (recommended):
docker compose --profile all up -d
# check migration runner logs
docker compose logs migrations
# verify it completed successfully - should show "Exited (0)"
docker compose ps migrations
Runner Configuration
Settings live in appsettings.json, or override via environment variables:
{
"ConnectionStrings": {
"DefaultConnection": "Host=postgres;Database=Reminders;..."
},
"DatabaseProvider": "Postgres",
"MigrationRunner": {
"MaxRetryAttempts": 5,
"RetryBaseDelaySeconds": 2
}
}
ConnectionStrings__DefaultConnection="..."
DatabaseProvider="Postgres"
MigrationRunner__MaxRetryAttempts=5
MigrationRunner__RetryBaseDelaySeconds=2
Creating New Migrations
Always specify the context and output directory:
For PostgreSQL:
dotnet ef migrations add MigrationName \
--project src/server/api/dotnet/Reminders.Api \
--context RemindersContext \
--output-dir Layers/Data/EntityFramework/Postgres/Migrations
For SQL Server:
dotnet ef migrations add MigrationName \
--project src/server/api/dotnet/Reminders.Api \
--context RemindersContext \
--output-dir Layers/Data/EntityFramework/SqlServer/Migrations
Troubleshooting Migrations
- Runner fails to start: check
docker compose logs migrations. Usual causes are the database not being ready yet, an invalid connection string, or missing environment variables. - Migrations fail to apply: check the logs for the detailed error, then test the connection directly with
docker compose exec postgres psql -U root -d Reminders -c "\dt". As a last resort,docker compose down -v && docker compose --profile all up -dresets the database (this deletes all data). - API won't start after a migration failure: the runner must exit with code 0 for the APIs to start. Check
docker compose ps migrations; if the exit code is non-zero, fix the underlying issue and rundocker compose up migrations -d --force-recreate.
Making Changes
Branching Strategy
Trunk-based development (see ADR-0001):
mainis the trunk and must always be releasable- Work in short-lived branches off
main, named<type>/<short-description>(e.g.feat/redis-cache,fix/async-service-chain) - Rebase on
mainbefore merging; squash merge keeps trunk history linear
Commit Messages
All commits follow Conventional Commits: <type>(<scope>): <description>, imperative mood, lowercase, no trailing period. See CLAUDE.md for the full list of types and scopes.
feat(api): add redis caching for reminder queries
fix(react): resolve reminder edit route crash
docs: update api documentation
test(api): add unit tests for reminder service
Code Style
- .NET: Follow Microsoft's C# coding conventions
- TypeScript/React: Follow the existing ESLint configuration
- Solidity: Follow Solidity style guide
- UI: changes follow the design system
Testing
Run All Tests
# .NET API Integration Tests (requires running API)
# Start API first:
docker compose --profile api up postgres ganache -d
cd src/server/api/dotnet/Reminders.Api
dotnet run &
# Then run tests:
cd src/test/server/dotnet/Reminders.Api.Test
dotnet test
# React Unit Tests (all passing ✅)
cd src/app/reactjs/reminders-app
npm test
# Flutter Tests
cd src/app/flutter/reminders_app
flutter analyze && flutter test
# Cypress E2E Tests
cd src/test/cypress
npm run cy:run
# Blockchain Tests (all passing ✅)
cd blockchain
npm test
Test Status
| Test Suite | Status | Notes |
|---|---|---|
| React/Jest | ✅ Passing | 10 tests, 99.6% coverage |
| Blockchain/Hardhat | ✅ Passing | 10 tests |
| Cypress E2E | ✅ Passing | Runs against deployed app |
| .NET Integration | ⚠️ Manual | Requires API running on port 5000 |
| .NET Selenium | ⚠️ Manual | Requires browser drivers installed |
Before Submitting
Ensure all tests pass:
- Unit tests
- Integration tests
- E2E tests
- Linting checks
Pull Request Process
-
Update Documentation: If you've changed APIs or added features, update the relevant documentation
-
Add Tests: Include appropriate test coverage for your changes
-
Update CHANGELOG: Add a brief description of your changes (if applicable)
-
Ensure CI Passes: All GitHub Actions workflows must pass
-
Description: Provide a clear description of:
- What changes you made
- Why you made them
- Any breaking changes
- Screenshots (for UI changes)
-
Link Issues: Reference any related issues using
Fixes #123orCloses #456
PR Title Format
PR titles follow the same Conventional Commits format as commits and are validated by the PR Title Check workflow:
<type>(<scope>): <description>
Example: feat(api): add email notification for reminders
Development Tips
Running Individual Services
# Just the database
docker compose --profile api up postgres -d
# Just the blockchain
docker compose up ganache -d
# API locally (with hot reload)
cd src/server/api/dotnet/Reminders.Api
dotnet watch run
# React app (with hot reload)
cd src/app/reactjs/reminders-app
npm run dev
Debugging
- .NET API: Use VS Code with C# extension or Visual Studio
- React: Use browser DevTools and React DevTools
- Blockchain: Use Hardhat console and Ganache logs
Common Issues
Port Already in Use
# Find and kill process using a port (example: 5000)
lsof -ti:5000 | xargs kill -9
# Or stop all containers and try again
docker compose down
docker compose --profile all up -d
Docker Build Fails or Takes Too Long
The first build can take 10+ minutes since Docker has to download base images (.NET, Node.js, PostgreSQL, Nginx, Ganache) and install all dependencies. Subsequent builds are much faster thanks to layer caching. If a build is actually failing:
# Clean Docker cache
docker system prune -a
docker compose down -v
Database Connection Issues
- Ensure PostgreSQL container is running and healthy:
docker compose ps/docker logs reminders-postgres - Check
.envfile has correct credentials - Verify port 5432 is not blocked, and give PostgreSQL a few seconds to finish initializing
React App Shows API Connection Error
- Ensure the API is reachable:
curl http://localhost:9999/health - Check CORS configuration in your
.envfile - Verify Nginx is running:
docker compose ps reminders-nginx
Questions or Need Help?
- Open an issue for bugs or feature requests
- Start a discussion for questions
- Check existing issues for solutions
License
By contributing, you agree that your contributions will be licensed under the same license as the project.
Thank you for contributing to Reminders! 🎉