What changed, and why it matters
This commit only reorganizes the project's internal maintainer documentation. It splits one large README into smaller files (coding conventions, local development, Greenfield API) and updates links in related docs and agent skill files. No application code, configuration, or security behavior was changed.
No security action needed. Treat as routine documentation maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff is a pure documentation refactor. Content was moved from docs/maintainers/README.md into new files: coding-conventions.md, local-development.md, and greenfield-api.md. Relative links in .agents/skills/*.md, BTCPayServer.Tests/README.md, Changelog.md, and docs/README.md were updated to point to the new locations. There are no code, build, test, or dependency changes.
Changed components
docs/maintainers/README.mddocs/maintainers/coding-conventions.mddocs/maintainers/local-development.mddocs/maintainers/greenfield-api.mddocs/README.mdBTCPayServer.Tests/README.mdChangelog.md.agents/skills/bem-conventions/SKILL.md.agents/skills/btcpayserver-changelog/SKILL.md.agents/skills/btcpayserver-pr-descriptions/SKILL.md.agents/skills/playwright-test-patterns/SKILL.md.agents/skills/razor-localization/SKILL.mdInspect captured patch +337 / −188
### .agents/skills/bem-conventions/SKILL.md
@@ -5,7 +5,7 @@ description: Use when editing Razor views, view components, CSS, JavaScript DOM
# BEM Conventions
-Follow [Coding conventions](../../../docs/maintainers/README.md#frontend-selectors).
+Follow [Coding conventions](../../../docs/maintainers/coding-conventions.md#frontend-selectors).
## Refactoring Existing Code
### .agents/skills/btcpayserver-changelog/SKILL.md
@@ -5,7 +5,7 @@ description: Use when updating or reviewing Changelog.md in BTCPayServer. Contai
# BTCPayServer Changelog
-Follow the [changelog conventions](../../../docs/maintainers/README.md#changelog). When asked to update or review the changelog, focus on user-visible changes and keep entries concise.
+Follow the [changelog conventions](../../../docs/maintainers/coding-conventions.md#changelog). When asked to update or review the changelog, focus on user-visible changes and keep entries concise.
## Release Range
### .agents/skills/btcpayserver-pr-descriptions/SKILL.md
@@ -5,7 +5,7 @@ description: Use when writing, reviewing, or improving pull request descriptions
# BTCPayServer Pull Request Descriptions
-Follow [Coding conventions](../../../docs/maintainers/README.md#pull-requests) and [API changes](../../../docs/maintainers/README.md#api-changes). Draft the description from the actual diff and repository context; do not infer product impact from the title alone.
+Follow [Coding conventions](../../../docs/maintainers/coding-conventions.md#pull-requests) and [API changes](../../../docs/maintainers/greenfield-api.md). Draft the description from the actual diff and repository context; do not infer product impact from the title alone.
## GitHub CLI Formatting
### .agents/skills/playwright-test-patterns/SKILL.md
@@ -5,7 +5,7 @@ description: Use when writing, refactoring, running, or debugging Playwright tes
# Playwright Test Patterns
-Follow [Testing](../../../docs/maintainers/README.md#testing) and [Coding conventions](../../../docs/maintainers/README.md#frontend-selectors).
+Follow [Testing](../../../docs/maintainers/local-development.md#testing) and [Coding conventions](../../../docs/maintainers/coding-conventions.md#frontend-selectors).
## Running and Debugging Tests
### .agents/skills/razor-localization/SKILL.md
@@ -5,7 +5,7 @@ description: Use when editing or reviewing Razor `.cshtml` files containing para
# Razor Localization
-Follow [Coding conventions](../../../docs/maintainers/README.md#razor-localization).
+Follow [Coding conventions](../../../docs/maintainers/coding-conventions.md#razor-localization).
## Review Checklist
### BTCPayServer.Tests/README.md
@@ -1,7 +1,7 @@
# Tooling
This README describe some useful tooling that you may need during development and testing.
-To learn how to get started with your local development environment, read [our documentation](https://github.com/btcpayserver/btcpayserver/blob/master/docs/maintainers/README.md#local-development).
+To learn how to get started with your local development environment, read [our documentation](https://github.com/btcpayserver/btcpayserver/blob/master/docs/maintainers/local-development.md).
## How to manually test payments
### Changelog.md
@@ -3180,7 +3180,7 @@ Those are low risk injection vulnerabilities.
### Altcoins
-* BTCPay Server build is Bitcoin Only by default. If you are developer and wants to work on the altcoins build, please read [the documentation](https://github.com/btcpayserver/btcpayserver/blob/master/docs/maintainers/README.md#local-development).
+* BTCPay Server build is Bitcoin Only by default. If you are developer and wants to work on the altcoins build, please read [the documentation](https://github.com/btcpayserver/btcpayserver/blob/master/docs/maintainers/local-development.md).
* Show sync progress for monero and show amount of monero payment #1729 @xpayserver
## 1.0.5.3:
### docs/README.md
@@ -17,12 +17,12 @@ Choose the route that matches how you work with BTCPay Server.
- [Developer guide](developers/README.md)
- [Contribution guide](https://docs.btcpayserver.org/Contribute/)
-- [Local development](maintainers/README.md#local-development)
-- [Testing](maintainers/README.md#testing)
+- [Local development](maintainers/local-development.md)
+- [Testing](maintainers/local-development.md#testing)
## Maintainers
- [Maintainer handbook](maintainers/README.md)
- [Architecture](maintainers/README.md#architecture)
-- [Coding conventions](maintainers/README.md#coding-conventions)
+- [Coding conventions](maintainers/coding-conventions.md)
- [Release process](maintainers/README.md#release-cycles)
### docs/maintainers/README.md
@@ -4,6 +4,21 @@ These pages document the repository-specific practices shared by maintainers and
For vulnerability reports, follow the canonical root [security policy](../../SECURITY.md).
+## Guides
+
+- [Local development and testing](local-development.md) covers prerequisites,
+ builds, launch profiles, development dependencies, and test practices.
+- [Coding conventions](coding-conventions.md) covers repository style, pull
+ requests, frontend selectors, Razor localization, and changelog entries.
+- [Greenfield API maintenance](greenfield-api.md) covers routes, authorization,
+ public models, errors, compatibility, OpenAPI, client methods, and tests.
+- [Configuration option maintenance](#configuration-option-maintenance) covers
+ the supported configuration sources, consumers, defaults, and documentation.
+- [Database migrations](#database-migrations) covers the repository-specific
+ Entity Framework and PostgreSQL migration workflow.
+- [Release cycles and checklist](#release-cycles) covers release types,
+ responsibilities, preparation, and publication.
+
## Architecture
BTCPay Server is an ASP.NET Core application targeting the .NET version defined in `Build/Common.csproj`. The solution is split into these main projects:
@@ -21,163 +36,6 @@ The application uses PostgreSQL for persistence and NBXplorer to track blockchai
Built-in features are organized under `BTCPayServer/Plugins`. Keep reusable contracts in the abstractions or client projects only when they are genuinely shared; otherwise, keep behavior close to its feature in the main application.
-## Local Development
-
-### Prerequisites
-
-- Install the .NET SDK required by `Build/Common.csproj` (currently .NET 10).
-- Install Docker with Compose for the local PostgreSQL, NBXplorer, Bitcoin, Lightning, Tor, and Mailpit services.
-- Use Visual Studio 2022 or JetBrains Rider for the repository launch profiles and debugging.
-
-### Build
-
-Build the solution directly:
-
-```sh
-dotnet build btcpayserver.sln
-```
-
-Create the release publish output used by the run scripts:
-
-```sh
-./build.sh
-```
-
-On PowerShell, use `./build.ps1`.
-
-### Run
-
-Start the development dependencies:
-
-```sh
-cd BTCPayServer.Tests
-docker-compose up -d dev
-cd ..
-```
-
-Run BTCPay Server with the `Bitcoin` launch profile:
-
-```sh
-dotnet run --project BTCPayServer/BTCPayServer.csproj --launch-profile Bitcoin
-```
-
-After running the build script, start the published application or inspect its options:
-
-```sh
-./run.sh
-./run.sh --help
-```
-
-On PowerShell, use `./run.ps1`. IDEs use the launch profiles from
-`BTCPayServer/Properties/launchSettings.json`. Use `Bitcoin` for HTTP or
-`Bitcoin-HTTPS` for HTTPS. The HTTPS profile requires a trusted development
-certificate:
-
-```sh
-dotnet dev-certs https --trust
-```
-
-If Brave does not recognize the trusted development certificate, export its
-public certificate:
-
-```sh
-dotnet dev-certs https --export-path ./aspnetcore-localhost.crt --format PEM
-```
-
-Open `brave://certificate-manager/`, select **Authorities** (or **Custom** >
-**Trusted Certificates** in newer versions), and import
-`aspnetcore-localhost.crt`. Enable trust for identifying websites when Brave
-asks, restart the browser, and reopen the local HTTPS URL. The exported file
-contains only the public certificate and can be deleted after import.
-
-For altcoin development, start the alternate dependency environment and use
-the `Altcoins` or `Altcoins-HTTPS` launch profile:
-
-```sh
-cd BTCPayServer.Tests
-docker-compose -f docker-compose.altcoins.yml up -d dev
-```
-
-See [testing](#testing) for focused test commands and regtest tooling.
-
-## Testing
-
-### Test Environment
-
-Start dependencies from `BTCPayServer.Tests` before running integration or Playwright tests:
-
-```sh
-docker-compose up -d dev
-```
-
-Run tests on the host. Run the full project from the repository root with:
-
-```sh
-dotnet test --project BTCPayServer.Tests/BTCPayServer.Tests.csproj
-```
-
-Run one test with its fully qualified method name:
-
-```sh
-dotnet test --project BTCPayServer.Tests/BTCPayServer.Tests.csproj --filter-method BTCPayServer.Tests.BitpayTests.CanUsePairing
-```
-
-If the dependency environment becomes stale, run `docker-compose down --volumes`, then `docker-compose pull` and `docker-compose up -d dev` from `BTCPayServer.Tests`.
-
-### Test Design
-
-- Prefer extending an existing relevant scenario over adding a separate test.
-- Exercise real browser or `BTCPayServerClient` interfaces instead of manually constructing controllers, unless controller internals are the subject of the test.
-- Use Playwright's auto-waiting `Expect` assertions; do not add `WaitForLoadStateAsync` before them.
-- Prefer `Expect` assertions such as `ToHaveCountAsync`, `ToContainTextAsync`,
- `ToHaveValueAsync`, and `ToHaveURLAsync` over manually fetching state. Add
- `using static Microsoft.Playwright.Assertions;` where needed.
-- Keep one-off selectors and helpers in the test. Introduce a Page Model Object only for repeated component or page behavior.
-- Page Model Objects should expose user-level actions and assertions and hide selector details.
-- Prefer stable BEM class hooks for reusable frontend components.
-
-[`BTCPayServer.Tests/README.md`](../../BTCPayServer.Tests/README.md) documents payment simulation, Bitcoin and Lightning helper scripts, Polar, and the altcoin test environment.
-
-## Coding Conventions
-
-### General
-
-- Follow the repository `.editorconfig`; it is the source of truth for formatting and C# style.
-- Prefer `Newtonsoft.Json` over `System.Text.Json` when adding or changing JSON serialization.
-
-### Pull Requests
-
-Write descriptions for users, merchants, operators, support contributors, translators, and reviewers who need to understand the outcome rather than the implementation.
-
-- Explain user-visible behavior, workflows, settings, permissions, API behavior, and operational impact in plain language.
-- State why the change matters and describe the practical before-and-after effect when useful.
-- Mention limitations, compatibility concerns, and follow-up work that affects users or operators.
-- Do not repeat the diff or include routine verification commands.
-- Keep technical implementation details only when they are necessary for review or explain public behavior.
-- Add screenshots for visual changes and a short video or GIF for multi-step UI flows when practical. Briefly explain when useful visual evidence cannot be included.
-
-### Frontend Selectors
-
-Use BEM-style classes for reusable styling, JavaScript, and Playwright hooks:
-`.block`, `.block__element`, `.block--modifier`, and
-`.block__element--modifier`. Use the component name as the block. Scope DOM
-queries to the nearest component or form when possible.
-
-Keep ids required for labels, ARIA and Bootstrap wiring, browser behavior, model binding, or compatibility. Even when an id remains, use a BEM class for new component selectors.
-
-### Razor Localization
-
-- Use `StringLocalizer` for plain text; Razor encodes the localized result.
-- Use `ViewLocalizer` only when the resource intentionally contains HTML.
-- Pass dynamic `ViewLocalizer` parameters through `Html.Encode(...)`.
-- Do not encode intentional HTML returned by helpers such as `Html.ActionLink(...)`.
-
-### Changelog
-
-Record user-visible features, fixes, regressions, deprecations, removals, security-relevant behavior, and compatibility changes in `Changelog.md`. Skip internal refactors, test-only changes, tooling changes unless users or release operators are affected, and entries already covered by an earlier patch release. Put removals and deprecations under **Miscellaneous** unless another existing section is a better fit.
-
-Use concise imperative bullets under the existing sections, preserve product terminology, wrap identifiers in backticks, and include PR numbers and contributor handles when known. When an entry begins with a titled prefix, bold only that title: `* **Title**: Description`.
-
## Configuration Option Maintenance
Treat each supported configuration source and each consumer as part of a public startup option.
@@ -211,27 +69,6 @@ If Entity Framework cannot generate the required operation, add a timestamp-pref
Test both a fresh database and an upgrade from the previous schema when the change has meaningful data or compatibility risk.
-## API Changes
-
-The Greenfield API contract includes controller behavior, models, permissions, serialization, and the hand-maintained OpenAPI templates in `BTCPayServer/wwwroot/swagger/v1/`.
-
-### New Endpoints
-
-- Document every endpoint and schema in the matching `swagger.template.*.json` file.
-- Assign the correct permission; introduce a permission only when no existing one fits.
-- Use REST methods where practical: `POST` for creation or actions, `PUT` for full replacement, `PATCH` for partial updates, and `DELETE` for deletion or archival.
-- Return validation failures as HTTP 422 with `path` and `message` entries. Return business request failures as HTTP 400 with a stable `code` and human-readable `message`.
-- Register JSON converters on the model with attributes. Serialize precision-sensitive or overflow-prone values such as `decimal` and `long` as strings while accepting compatible input forms where required.
-- Serialize `DateTime` and `DateTimeOffset` model properties as Unix timestamps with `NBitcoin.JsonConverters.DateTimeToUnixTimeConverter`, and document them with the shared `UnixTimestamp` OpenAPI schema.
-
-### Compatibility
-
-Changing a property type or removing a property is breaking; version the endpoint unless compatibility can be preserved completely. Adding a required property or one without a safe default can also break clients. For additions, detect omission and retain the existing value on updates or apply a documented default on creation.
-
-Update the matching OpenAPI template in the same pull request whenever request fields, response fields, validation, models, or behavior change. Cover compatibility and permissions with Greenfield API tests.
-
-See [Greenfield API development](../greenfield-development.md) for detailed model-evolution examples and [authorization](../greenfield-authorization.md) for authentication flows.
-
## Release Cycles
BTCPay Server uses three release types.
### docs/maintainers/coding-conventions.md
@@ -0,0 +1,60 @@
+# Coding Conventions
+
+## General
+
+- Follow the repository `.editorconfig`; it is the source of truth for
+ formatting and C# style.
+- Prefer `Newtonsoft.Json` over `System.Text.Json` when adding or changing JSON
+ serialization.
+
+## Pull Requests
+
+Write descriptions for users, merchants, operators, support contributors,
+translators, and reviewers who need to understand the outcome rather than the
+implementation.
+
+- Explain user-visible behavior, workflows, settings, permissions, API
+ behavior, and operational impact in plain language.
+- State why the change matters and describe the practical before-and-after
+ effect when useful.
+- Mention limitations, compatibility concerns, and follow-up work that affects
+ users or operators.
+- Do not repeat the diff or include routine verification commands.
+- Keep technical implementation details only when they are necessary for
+ review or explain public behavior.
+- Add screenshots for visual changes and a short video or GIF for multi-step UI
+ flows when practical. Briefly explain when useful visual evidence cannot be
+ included.
+
+## Frontend Selectors
+
+Use BEM-style classes for reusable styling, JavaScript, and Playwright hooks:
+`.block`, `.block__element`, `.block--modifier`, and
+`.block__element--modifier`. Use the component name as the block. Scope DOM
+queries to the nearest component or form when possible.
+
+Keep ids required for labels, ARIA and Bootstrap wiring, browser behavior,
+model binding, or compatibility. Even when an id remains, use a BEM class for
+new component selectors.
+
+## Razor Localization
+
+- Use `StringLocalizer` for plain text; Razor encodes the localized result.
+- Use `ViewLocalizer` only when the resource intentionally contains HTML.
+- Pass dynamic `ViewLocalizer` parameters through `Html.Encode(...)`.
+- Do not encode intentional HTML returned by helpers such as
+ `Html.ActionLink(...)`.
+
+## Changelog
+
+Record user-visible features, fixes, regressions, deprecations, removals,
+security-relevant behavior, and compatibility changes in `Changelog.md`. Skip
+internal refactors, test-only changes, tooling changes unless users or release
+operators are affected, and entries already covered by an earlier patch
+release. Put removals and deprecations under **Miscellaneous** unless another
+existing section is a better fit.
+
+Use concise imperative bullets under the existing sections, preserve product
+terminology, wrap identifiers in backticks, and include PR numbers and
+contributor handles when known. When an entry begins with a titled prefix, bold
+only that title: `* **Title**: Description`.
### docs/maintainers/greenfield-api.md
@@ -0,0 +1,123 @@
+# Greenfield API Maintenance
+
+The Greenfield API contract includes routes, status codes, controller behavior,
+public models, permissions, serialization, `BTCPayServerClient`, webhooks, and
+the hand-maintained OpenAPI templates in
+`BTCPayServer/wwwroot/swagger/v1/`. Treat changes to semantics as carefully as
+changes to JSON shape.
+
+## Controllers and Routes
+
+- Put core controllers in `BTCPayServer/Controllers/GreenField` and plugin
+ controllers with their feature. The usual controller derives from
+ `ControllerBase` and uses `[ApiController]`, Greenfield authentication, and
+ `CorsPolicies.All`.
+- Use explicit attribute routes under `/api/v1`. Prefer resource-oriented
+ routes and use `POST` for creation or actions, `PUT` for replacement,
+ `PATCH` for partial updates, and `DELETE` for deletion or archival.
+- Use action path segments such as `/activate` when the operation does not map
+ naturally to CRUD. Add both store-nested and resource-only routes only when
+ required for compatibility; do not create aliases by default.
+- Existing mutations normally return HTTP 200, including creation, deletion,
+ and archival. Preserve an endpoint's established success status rather than
+ changing it incidentally to 201 or 204.
+- Reuse existing repositories and feature services. Keep HTTP translation,
+ request validation, authorized context access, and public-model mapping at
+ the controller boundary, and propagate `CancellationToken` through new
+ asynchronous work.
+
+## Authentication and Scope
+
+- Use `AuthenticationSchemes.Greenfield` and assign the narrowest existing
+ permission. Introduce a permission only when no existing policy expresses
+ the access being granted. Use an unscoped permission when an operation, such
+ as creating a store, cannot derive a store scope.
+- Make anonymous, API-key-only, cookie-compatible, or non-`/api/v1` endpoints
+ explicit exceptions. Anonymous workflows must document and test the token or
+ other capability that protects the resource.
+- Store authorization is derived from route, query, or form values and from
+ registered resource identifiers such as `invoiceId`, `appId`, and
+ `pullPaymentId`. These parameter names are security-sensitive. Register a
+ `BuiltInPermissionScopeProvider.RouteValueToStoreIdQuery` or plugin scope
+ provider for a new resource identifier.
+- After authorization, use context populated by the authorization
+ infrastructure, such as `HttpContext.GetStoreData()`, instead of trusting a
+ route value independently. When a route contains both `storeId` and a
+ resource identifier, their ownership must match.
+- For list endpoints, return only resources in the scopes recorded in the
+ request context. Test scoped and unscoped keys, permission without store
+ membership, membership without permission, cross-store access, and the
+ intended 403 or 404 behavior for a missing resource.
+
+## Public Models and Serialization
+
+- Put reusable request and response models in
+ `BTCPayServer.Client/Models`; do not return persistence or domain entities.
+ Map explicitly between internal and public models.
+- Register Newtonsoft.Json converters on model properties. Serialize
+ precision-sensitive or overflow-prone values such as `decimal` and `long`
+ as strings while accepting compatible input forms where required. Serialize
+ enums as strings when that is the established contract.
+- Serialize `DateTime` and `DateTimeOffset` properties as Unix timestamps with
+ `NBitcoin.JsonConverters.DateTimeToUnixTimeConverter`, and document them
+ with the shared `UnixTimestamp` OpenAPI schema. Preserve existing JSON names,
+ time units, null handling, and defaults.
+
+## Validation and Errors
+
+- Add request validation failures to `ModelState` and return
+ `CreateValidationError(ModelState)`. HTTP 422 responses contain an array of
+ `path` and `message` entries; paths should identify nested and indexed request
+ members precisely.
+- Return operational failures with `CreateAPIError` and a stable error code
+ plus a human-readable message. Use 400 for an otherwise valid request
+ rejected by ordinary business logic, 403 for permission or policy
+ restrictions, 404 for absent resources, 409 for state conflicts, 410 for
+ expired or deliberately removed resources, and 503 for temporary dependency
+ failures where applicable.
+- Avoid bare `BadRequest()`, `NotFound()`, and `Forbid()` results. Structured
+ JSON errors are required for `BTCPayServerClient` to expose useful
+ `GreenfieldAPIException` details.
+
+## Collections
+
+The existing API has no single pagination contract. Ordinary list endpoints
+usually use `skip` and `take`, while domain APIs such as Lightning use their
+native cursor. For a new list endpoint, define and document stable ordering,
+parameter defaults, page-size limits, invalid-value behavior, and whether the
+response needs totals or continuation data. Do not change an existing raw
+array response to an envelope without treating it as a compatibility change.
+
+## OpenAPI, Client, and Tests
+
+- Document every endpoint, route alias, parameter, request, response, schema,
+ error status, and required permission in the matching
+ `swagger.template.*.json` file. Use a unique `Resource_Action` operation ID.
+- Update OpenAPI in the same pull request whenever request fields, response
+ fields, validation, permissions, models, serialization, status codes, or
+ behavior change. Schema validation does not check parity with controller
+ routes or policies, so compare the merged document with the implementation.
+- Add or update `BTCPayServerClient` methods with the matching HTTP method,
+ request and response models, query parameters, and `CancellationToken`.
+- Prefer integration tests through `BTCPayServerClient`. Cover the happy path,
+ exact permission and store scope, validation status and paths, stable error
+ status and code, serialization, update compatibility, pagination or filters,
+ and documented responses. Extend an existing feature scenario when
+ practical.
+
+## Compatibility
+
+Changing a property type or removing a property is breaking; version the
+endpoint unless compatibility can be preserved completely. Adding a required
+property or one without a safe default can also break clients. For additions,
+detect omission and retain the existing value on updates or apply a documented
+default on creation. Do not infer omission from the deserialized CLR default.
+
+Historical dual routes, mixed pagination names, local response types, bare
+framework errors, and direct UI-controller or database dependencies exist for
+compatibility. Do not copy them into new endpoints without a concrete need.
+
+See [API implementation and compatibility](../developers/api/compatibility.md)
+for detailed model-evolution examples and
+[API authentication and authorization](../developers/api/authentication.md)
+for authentication flows.
### docs/maintainers/local-development.md
@@ -0,0 +1,129 @@
+# Local Development and Testing
+
+## Prerequisites
+
+- Install the .NET SDK required by `Build/Common.csproj` (currently .NET 10).
+- Install Docker with Compose for the local PostgreSQL, NBXplorer, Bitcoin,
+ Lightning, Tor, and Mailpit services.
+- Use Visual Studio 2022 or JetBrains Rider for the repository launch profiles
+ and debugging.
+
+## Build
+
+Build the solution directly:
+
+```sh
+dotnet build btcpayserver.sln
+```
+
+Create the release publish output used by the run scripts:
+
+```sh
+./build.sh
+```
+
+On PowerShell, use `./build.ps1`.
+
+## Run
+
+Start the development dependencies:
+
+```sh
+cd BTCPayServer.Tests
+docker-compose up -d dev
+cd ..
+```
+
+Run BTCPay Server with the `Bitcoin` launch profile:
+
+```sh
+dotnet run --project BTCPayServer/BTCPayServer.csproj --launch-profile Bitcoin
+```
+
+After running the build script, start the published application or inspect its
+options:
+
+```sh
+./run.sh
+./run.sh --help
+```
+
+On PowerShell, use `./run.ps1`. IDEs use the launch profiles from
+`BTCPayServer/Properties/launchSettings.json`. Use `Bitcoin` for HTTP or
+`Bitcoin-HTTPS` for HTTPS. The HTTPS profile requires a trusted development
+certificate:
+
+```sh
+dotnet dev-certs https --trust
+```
+
+If Brave does not recognize the trusted development certificate, export its
+public certificate:
+
+```sh
+dotnet dev-certs https --export-path ./aspnetcore-localhost.crt --format PEM
+```
+
+Open `brave://certificate-manager/`, select **Authorities** (or **Custom** >
+**Trusted Certificates** in newer versions), and import
+`aspnetcore-localhost.crt`. Enable trust for identifying websites when Brave
+asks, restart the browser, and reopen the local HTTPS URL. The exported file
+contains only the public certificate and can be deleted after import.
+
+For altcoin development, start the alternate dependency environment and use
+the `Altcoins` or `Altcoins-HTTPS` launch profile:
+
+```sh
+cd BTCPayServer.Tests
+docker-compose -f docker-compose.altcoins.yml up -d dev
+```
+
+See [testing](#testing) for focused test commands and regtest tooling.
+
+## Testing
+
+### Test Environment
+
+Start dependencies from `BTCPayServer.Tests` before running integration or
+Playwright tests:
+
+```sh
+docker-compose up -d dev
+```
+
+Run tests on the host. Run the full project from the repository root with:
+
+```sh
+dotnet test --project BTCPayServer.Tests/BTCPayServer.Tests.csproj
+```
+
+Run one test with its fully qualified method name:
+
+```sh
+dotnet test --project BTCPayServer.Tests/BTCPayServer.Tests.csproj --filter-method BTCPayServer.Tests.BitpayTests.CanUsePairing
+```
+
+If the dependency environment becomes stale, run
+`docker-compose down --volumes`, then `docker-compose pull` and
+`docker-compose up -d dev` from `BTCPayServer.Tests`.
+
+### Test Design
+
+- Prefer extending an existing relevant scenario over adding a separate test.
+- Exercise real browser or `BTCPayServerClient` interfaces instead of manually
+ constructing controllers, unless controller internals are the subject of the
+ test.
+- Use Playwright's auto-waiting `Expect` assertions; do not add
+ `WaitForLoadStateAsync` before them.
+- Prefer `Expect` assertions such as `ToHaveCountAsync`, `ToContainTextAsync`,
+ `ToHaveValueAsync`, and `ToHaveURLAsync` over manually fetching state. Add
+ `using static Microsoft.Playwright.Assertions;` where needed.
+- Keep one-off selectors and helpers in the test. Introduce a Page Model Object
+ only for repeated component or page behavior.
+- Page Model Objects should expose user-level actions and assertions and hide
+ selector details.
+- Prefer stable BEM class hooks for reusable frontend components.
+
+[`BTCPayServer.Tests/README.md`](../../BTCPayServer.Tests/README.md) documents
+payment simulation, Bitcoin and Lightning helper scripts, Polar, and the
+altcoin test environment.Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.