Thank you for your interest in contributing to ServiceHub! This document explains how to get started, what to expect, and how to report issues.
- Code of Conduct
- Reporting Security Issues
- Reporting Bugs
- Requesting Features
- Development Setup
- Running Tests
- Pull Request Process
- Code Style
- Architecture Overview
This project follows the Contributor Covenant Code of Conduct. By participating you agree to abide by its terms.
Do NOT open a public GitHub issue for security vulnerabilities.
Please read SECURITY.md for instructions on responsible disclosure. We aim to respond within 72 hours.
Before filing a bug:
- Search existing issues to avoid duplicates.
- Collect the relevant logs (redact any connection strings or secrets).
- Note your OS, .NET version, and Node version.
Then open a GitHub Issue with the Bug report template.
Open a GitHub Issue with the Feature request template. Describe the use-case, not just the solution.
| Tool | Version |
|---|---|
| .NET SDK | 10.0 or later |
| Node.js | 22.x or later |
| npm | 10.x or later |
# Clone
git clone https://github.com/debdevops/servicehub.git
cd servicehub
# Start everything (API + React dev server + hot reload)
./run.sh
# or on Windows
./run.ps1The React UI is served at http://localhost:3000 and the API at http://localhost:5153 (proxied via Vite).
See self-hosting/README.md for full local development instructions.
cd services/api
dotnet test tests/ServiceHub.UnitTests --configuration Release
# With coverage report (requires reportgenerator):
dotnet test tests/ServiceHub.UnitTests \
--settings coverlet.runsettings \
--results-directory TestResults
reportgenerator -reports:"TestResults/**/coverage.cobertura.xml" \
-targetdir:"TestResults/CoverageReport" -reporttypes:Htmlcd apps/web
npm run test:coverage./run.sh --simulator # starts API in simulator mode + Vite
cd apps/web
npm run test:e2eCoverage threshold: Both backend and frontend must maintain ≥60% line coverage. CI enforces this automatically.
- Fork the repository and create a feature branch from
main. - Make your changes with clear, focused commits.
- Write or update tests to cover your changes.
- Run
dotnet build --configuration Releaseandnpm run buildlocally — both must pass with zero warnings. - Run the full test suites (see above) — all must pass.
- Open a PR against
mainwith a clear description of what changed and why. - Address any CI failures or review feedback promptly.
Branch naming convention:
feature/<short-description>— new featuresfix/<short-description>— bug fixeshotfix/<short-description>— urgent production fixesdocs/<short-description>— documentation only
- Follow existing file-scoped namespace conventions (
namespace Foo.Bar;) - Use
sealedon non-inheritable classes - All public and protected members must have XML doc-comments
- Use
Result<T>/Resultpattern for fallible operations — do not throw business exceptions - Sanitise any user-supplied string before logging with
LogRedactor.SanitiseForLog() - Use
ArgumentNullException.ThrowIfNull()or explicit null guard in constructors - No
string.Format— use interpolated strings or structured logging parameters
- All exported components must have a JSDoc comment
- Hooks live in
src/hooks/; API calls live insrc/lib/api/ - Do not add new
anytypes — use proper generics orunknown - Run
npx tsc -bbefore committing to catch type errors
- No secrets, API keys, or credentials in source code — ever.
- Comments should explain why, not what. The code already shows what.
servicehub/
├── apps/web/ # React 19 SPA (Vite + TypeScript)
│ └── src/
│ ├── components/ # Reusable UI components
│ ├── hooks/ # React Query hooks
│ ├── lib/api/ # API client and typed wrappers
│ └── pages/ # Route-level page components
│
├── services/api/ # .NET 10 Web API
│ └── src/
│ ├── ServiceHub.Api/ # Controllers, middleware, DI
│ ├── ServiceHub.Core/ # Domain entities, interfaces, DTOs
│ ├── ServiceHub.Infrastructure/ # Azure Service Bus, persistence
│ ├── ServiceHub.Infrastructure.Aws/ # AWS SQS/SNS
│ ├── ServiceHub.Infrastructure.Gcp/ # GCP Pub/Sub
│ └── ServiceHub.Shared/ # Result<T>, constants, helpers
│
├── self-hosting/ # Deployment guides (local, Azure, AWS, GCP)
└── run.sh / run.ps1 # One-command local dev launcher
The API uses a Result/Error pattern (no exceptions for business logic), AES-256-GCM for connection string encryption, and tenant isolation via OwnerId on every data access. The SPA authenticates via an ephemeral SPA token injected into <meta> at page load time.