Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
55e2e34
Code cleanup of developer CLI
tjementum Nov 24, 2025
4b7081f
Fix bug in Developer CLI when no .zshrc profile exists
tjementum Aug 19, 2025
7e68e83
Rename configure-continuous-deployments command to deploy
tjementum Nov 22, 2025
1e9a515
Rename sync-windsurf-ai-rules CLI command to sync-ai-rules
tjementum Nov 24, 2025
6d4caf0
Fix coverage CLI command to cover all systems without including tests…
tjementum Nov 24, 2025
59eaede
Add --quiet option to CLI commands to minimize output in AI context
tjementum Nov 24, 2025
038ea9a
Add --no-build option and remove --skip-format and --skip-inspect fro…
tjementum Nov 24, 2025
2038d5d
Add --filter option to test CLI command to run a subset of tests
tjementum Nov 24, 2025
cfdbbd3
Add --filter and --exclude-category options to Developer CLI test com…
tjementum Nov 24, 2025
e779f4b
Delete dead code and clean up syntax in CLI commands and helper classes
tjementum Nov 24, 2025
b99326b
Create MCP CLI command for AI tools to use as an MCP server to trigge…
tjementum Nov 24, 2025
800be02
Delete coauthor CLI command
tjementum Nov 24, 2025
5fad598
Add --cli option to build, format, inspect, and check commands
tjementum Nov 24, 2025
a2e37f4
Upgrade translate CLI command to use cheaper GPT5-mini and change ICh…
tjementum Nov 25, 2025
33f32de
Add --force option to install command to allow reinstallation
tjementum Nov 25, 2025
1ad19a3
Fix pull-platformplatform-changes failing when local main is behind o…
tjementum Nov 26, 2025
0d0caed
Add git-config CLI command for configuring author identity and recomm…
tjementum Nov 26, 2025
f7a5be9
Add global --trace option to show external processes being executed
tjementum Nov 26, 2025
8bbeccc
Rename --solution-name option to --self-contained-system in workflows…
tjementum Nov 26, 2025
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
6 changes: 3 additions & 3 deletions .cursor/rules/developer-cli/developer-cli.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ Carefully follow these instructions when implementing and extending the custom D
2. Command Options:
- Use double-dash (`--`) for long option names and single-dash (`-`) for abbreviations.
- Provide clear, concise descriptions for all options.
- Use consistent naming across commands for similar options (e.g., `--solution-name` and `-s`).
- Use consistent naming across commands for similar options (e.g., `--self-contained-system` and `-s`).
- Define option types explicitly (e.g., `Option<bool>`, `Option<string?>`).
- For positional arguments, include both positional and named options (e.g., `["<solution-name>", "--solution-name", "-s"]`).
- For positional arguments, include both positional and named options (e.g., `["<self-contained-system>", "--self-contained-system", "-s"]`).
- Set default values where appropriate using lambda expressions.

3. Prerequisites and Dependencies:
Expand Down Expand Up @@ -82,7 +82,7 @@ public class BuildCommand : Command
{
public BuildCommand() : base("build", "Builds the solution")
{
AddOption(new Option<string?>(["<solution-name>", "--solution-name", "-s"], "The solution to build")); // ✅ DO: Consistent option naming
AddOption(new Option<string?>(["<self-contained-system>", "--self-contained-system", "-s"], "The self-contained system to build")); // ✅ DO: Consistent option naming
AddOption(new Option<bool>(["--verbose", "-v"], () => false, "Enable verbose output"));
Handler = CommandHandler.Create<string?, bool>(Execute);
}
Expand Down
20 changes: 10 additions & 10 deletions .cursor/rules/tools.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ Use these commands continously when you are working on the codebase.
# Build only backend
[CLI_ALIAS] build --backend

# Build specific backend solution
[CLI_ALIAS] build --backend --solution-name <solution-name>
# Build specific self-contained system backend
[CLI_ALIAS] build --backend --self-contained-system <self-contained-system>

# Build only frontend
[CLI_ALIAS] build --frontend
Expand All @@ -65,8 +65,8 @@ After you have completed a backend task and want to ensure that it works as expe
# Run all tests
[CLI_ALIAS] test

# Run tests for specific solution
[CLI_ALIAS] test --solution-name <solution-name>
# Run tests for specific self-contained system
[CLI_ALIAS] test --self-contained-system <self-contained-system>
```

## End-to-End Test Commands
Expand Down Expand Up @@ -103,21 +103,21 @@ Run these commands before you commit your changes.
# Format only backend (run this before commit)
[CLI_ALIAS] format --backend

# Format specific backend solution (run this before commit)
[CLI_ALIAS] format --backend --solution-name <solution-name>
# Format specific self-contained system backend (run this before commit)
[CLI_ALIAS] format --backend --self-contained-system <self-contained-system>

# Format only frontend (run this before commit)
[CLI_ALIAS] format --frontend
```

## Command Breakdown

Using `--solution-name` with backend commands is recommended as it significantly reduces execution time compared to running commands against the entire codebase. Especially for the `format` and `inspect` commands.
Using `--self-contained-system` (or `-s`) with backend commands is recommended as it significantly reduces execution time compared to running commands against the entire codebase. Especially for the `format` and `inspect` commands.

- `[CLI_ALIAS] inspect --backend --solution-name BackOffice.slnf`
- `[CLI_ALIAS] format --backend --solution-name AccountManagement.slnf`
- `[CLI_ALIAS] inspect --backend --self-contained-system back-office`
- `[CLI_ALIAS] format --backend --self-contained-system account-management`

The value of the `--solution-name` parameter should be the solution filter file (`.slnf`) name from the self-contained system directory.
The value of the `--self-contained-system` parameter should be the kebab-case name of the self-contained system directory (e.g., `account-management`, `back-office`).

## Troubleshooting when `[CLI_ALIAS]` fails

Expand Down
2 changes: 1 addition & 1 deletion .cursor/rules/workflows/prepare-pull-request.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Use this workflow to create pull request titles and descriptions:
6. Build, test, format and inspect the codebase:
- If changes have been made to backend `*.cs` but only to one self-contained system, run:
```bash
[CLI_ALIAS] check --backend --solution-name SelfContainedSystem.slnf
[CLI_ALIAS] check --backend --self-contained-system <self-contained-system>
```
- If backend changes have been made to `*.cs` in multiple self-contained systems or the Shared Kernel, run:
```bash
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/account-management.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ jobs:
- name: Run Code Inspections
working-directory: developer-cli
run: |
dotnet run inspect --backend --solution-name AccountManagement.slnf | tee inspection-output.log
dotnet run inspect --backend --self-contained-system account-management | tee inspection-output.log

if ! grep -q "No backend issues found!" inspection-output.log; then
echo "Code inspection issues found."
Expand All @@ -201,11 +201,11 @@ jobs:
- name: Check for Code Formatting Issues
working-directory: developer-cli
run: |
dotnet run format --backend --solution-name AccountManagement.slnf
dotnet run format --backend --self-contained-system account-management

# Check for any changes made by the code formatter
git diff --exit-code || {
echo "Formatting issues detected. Please run 'dotnet run format --backend --solution-name AccountManagement.slnf' from /developer-cli folder locally and commit the formatted code."
echo "Formatting issues detected. Please run 'dotnet run format --backend --self-contained-system account-management' from /developer-cli folder locally and commit the formatted code."
exit 1
}

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/back-office.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ jobs:
- name: Run Code Inspections
working-directory: developer-cli
run: |
dotnet run inspect --backend --solution-name BackOffice.slnf | tee inspection-output.log
dotnet run inspect --backend --self-contained-system back-office | tee inspection-output.log

if ! grep -q "No backend issues found!" inspection-output.log; then
echo "Code inspection issues found."
Expand All @@ -201,11 +201,11 @@ jobs:
- name: Check for Code Formatting Issues
working-directory: developer-cli
run: |
dotnet run format --backend --solution-name BackOffice.slnf
dotnet run format --backend --self-contained-system back-office

# Check for any changes made by the code formatter
git diff --exit-code || {
echo "Formatting issues detected. Please run 'dotnet run format --backend --solution-name BackOffice.slnf' from /developer-cli folder locally and commit the formatted code."
echo "Formatting issues detected. Please run 'dotnet run format --backend --self-contained-system back-office' from /developer-cli folder locally and commit the formatted code."
exit 1
}

Expand Down
8 changes: 8 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mcpServers": {
"developer-cli": {
"command": "dotnet",
"args": ["run", "--project", "developer-cli", "mcp"]
}
}
}
6 changes: 3 additions & 3 deletions .windsurf/rules/developer-cli/developer-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ Carefully follow these instructions when implementing and extending the custom D
2. Command Options:
- Use double-dash (`--`) for long option names and single-dash (`-`) for abbreviations.
- Provide clear, concise descriptions for all options.
- Use consistent naming across commands for similar options (e.g., `--solution-name` and `-s`).
- Use consistent naming across commands for similar options (e.g., `--self-contained-system` and `-s`).
- Define option types explicitly (e.g., `Option<bool>`, `Option<string?>`).
- For positional arguments, include both positional and named options (e.g., `["<solution-name>", "--solution-name", "-s"]`).
- For positional arguments, include both positional and named options (e.g., `["<self-contained-system>", "--self-contained-system", "-s"]`).
- Set default values where appropriate using lambda expressions.

3. Prerequisites and Dependencies:
Expand Down Expand Up @@ -83,7 +83,7 @@ public class BuildCommand : Command
{
public BuildCommand() : base("build", "Builds the solution")
{
AddOption(new Option<string?>(["<solution-name>", "--solution-name", "-s"], "The solution to build")); // ✅ DO: Consistent option naming
AddOption(new Option<string?>(["<self-contained-system>", "--self-contained-system", "-s"], "The self-contained system to build")); // ✅ DO: Consistent option naming
AddOption(new Option<bool>(["--verbose", "-v"], () => false, "Enable verbose output"));
Handler = CommandHandler.Create<string?, bool>(Execute);
}
Expand Down
20 changes: 10 additions & 10 deletions .windsurf/rules/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ Use these commands continously when you are working on the codebase.
# Build only backend
[CLI_ALIAS] build --backend

# Build specific backend solution
[CLI_ALIAS] build --backend --solution-name <solution-name>
# Build specific self-contained system backend
[CLI_ALIAS] build --backend --self-contained-system <self-contained-system>

# Build only frontend
[CLI_ALIAS] build --frontend
Expand All @@ -65,8 +65,8 @@ After you have completed a backend task and want to ensure that it works as expe
# Run all tests
[CLI_ALIAS] test

# Run tests for specific solution
[CLI_ALIAS] test --solution-name <solution-name>
# Run tests for specific self-contained system
[CLI_ALIAS] test --self-contained-system <self-contained-system>
```

## End-to-End Test Commands
Expand Down Expand Up @@ -103,21 +103,21 @@ Run these commands before you commit your changes.
# Format only backend (run this before commit)
[CLI_ALIAS] format --backend

# Format specific backend solution (run this before commit)
[CLI_ALIAS] format --backend --solution-name <solution-name>
# Format specific self-contained system backend (run this before commit)
[CLI_ALIAS] format --backend --self-contained-system <self-contained-system>

# Format only frontend (run this before commit)
[CLI_ALIAS] format --frontend
```

## Command Breakdown

Using `--solution-name` with backend commands is recommended as it significantly reduces execution time compared to running commands against the entire codebase. Especially for the `format` and `inspect` commands.
Using `--self-contained-system` (or `-s`) with backend commands is recommended as it significantly reduces execution time compared to running commands against the entire codebase. Especially for the `format` and `inspect` commands.

- `[CLI_ALIAS] inspect --backend --solution-name BackOffice.slnf`
- `[CLI_ALIAS] format --backend --solution-name AccountManagement.slnf`
- `[CLI_ALIAS] inspect --backend --self-contained-system back-office`
- `[CLI_ALIAS] format --backend --self-contained-system account-management`

The value of the `--solution-name` parameter should be the solution filter file (`.slnf`) name from the self-contained system directory.
The value of the `--self-contained-system` parameter should be the kebab-case name of the self-contained system directory (e.g., `account-management`, `back-office`).

## Troubleshooting when `[CLI_ALIAS]` fails

Expand Down
2 changes: 1 addition & 1 deletion .windsurf/workflows/prepare-pull-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Use this workflow to create pull request titles and descriptions:
6. Build, test, format and inspect the codebase:
- If changes have been made to backend `*.cs` but only to one self-contained system, run:
```bash
[CLI_ALIAS] check --backend --solution-name SelfContainedSystem.slnf
[CLI_ALIAS] check --backend --self-contained-system <self-contained-system>
```
- If backend changes have been made to `*.cs` in multiple self-contained systems or the Shared Kernel, run:
```bash
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ Run this command to automate Azure Subscription configuration and set up [GitHub

```bash
cd developer-cli
dotnet run configure-continuous-deployments # Tip: Add --verbose-logging to show the used CLI commands
dotnet run deploy # Tip: Add --verbose-logging to show the used CLI commands
```

You need to be the owner of the GitHub repository and the Azure Subscription, plus have permissions to create Service Principals and Active Directory Groups.
Expand Down
7 changes: 7 additions & 0 deletions application/account-management/Tests/EndpointBaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Data.Sqlite;
Expand Down Expand Up @@ -93,6 +94,12 @@ protected EndpointBaseTest()

_webApplicationFactory = new WebApplicationFactory<Program>().WithWebHostBuilder(builder =>
{
builder.ConfigureLogging(logging =>
{
logging.AddFilter(_ => false); // Suppress all logs during tests
}
);

builder.ConfigureTestServices(services =>
{
// Replace the default DbContext in the WebApplication to use an in-memory SQLite database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,30 @@ public sealed class CustomExceptionHandlingTests : EndpointBaseTest<AccountManag
{
private readonly WebApplicationFactory<Program> _webApplicationFactory = new();

[Theory]
[InlineData("Development")]
[InlineData("Production")]
public async Task GlobalExceptionHandling_WhenThrowingException_ShouldHandleExceptionsCorrectly(string environment)
[Fact]
[TestCategory("Noisy")]
public async Task GlobalExceptionHandling_WhenThrowingExceptionInDevelopment_ShouldHandleExceptionsCorrectly()
{
await GlobalExceptionHandling_WhenThrowingException_ShouldHandleExceptionsCorrectly("Development");
}

[Fact]
public async Task GlobalExceptionHandling_WhenThrowingExceptionInProduction_ShouldHandleExceptionsCorrectly()
{
await GlobalExceptionHandling_WhenThrowingException_ShouldHandleExceptionsCorrectly("Production");
}

internal async Task GlobalExceptionHandling_WhenThrowingException_ShouldHandleExceptionsCorrectly(string environment)
{
// Arrange
var client = _webApplicationFactory.WithWebHostBuilder(builder =>
{
builder.UseSetting(WebHostDefaults.EnvironmentKey, environment);
builder.ConfigureLogging(logging =>
{
logging.AddFilter(_ => false); // Suppress all logs during tests
}
);
builder.ConfigureAppConfiguration((_, _) =>
{
// Set the environment variable to enable the test-specific /api/throwException endpoint.
Expand Down Expand Up @@ -53,17 +68,32 @@ await response.ShouldHaveErrorStatusCode(
}
}

[Theory]
[InlineData("Development")]
[InlineData("Production")]
public async Task TimeoutExceptionHandling_WhenThrowingTimeoutException_ShouldHandleTimeoutExceptionsCorrectly(
[Fact]
[TestCategory("Noisy")]
public async Task TimeoutExceptionHandling_WhenThrowingTimeoutExceptionInDevelopment_ShouldHandleTimeoutExceptionsCorrectly()
{
await TimeoutExceptionHandling_WhenThrowingTimeoutException_ShouldHandleTimeoutExceptionsCorrectly("Development");
}

[Fact]
public async Task TimeoutExceptionHandling_WhenThrowingTimeoutExceptionInProduction_ShouldHandleTimeoutExceptionsCorrectly()
{
await TimeoutExceptionHandling_WhenThrowingTimeoutException_ShouldHandleTimeoutExceptionsCorrectly("Production");
}

internal async Task TimeoutExceptionHandling_WhenThrowingTimeoutException_ShouldHandleTimeoutExceptionsCorrectly(
string environment
)
{
// Arrange
var client = _webApplicationFactory.WithWebHostBuilder(builder =>
{
builder.UseSetting(WebHostDefaults.EnvironmentKey, environment);
builder.ConfigureLogging(logging =>
{
logging.AddFilter(_ => false); // Suppress all logs during tests
}
);
builder.ConfigureAppConfiguration((_, _) =>
{
// Set the environment variable to enable the test-specific /api/throwException endpoint.
Expand Down
7 changes: 7 additions & 0 deletions application/back-office/Tests/EndpointBaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Data.Sqlite;
Expand Down Expand Up @@ -93,6 +94,12 @@ protected EndpointBaseTest()

_webApplicationFactory = new WebApplicationFactory<Program>().WithWebHostBuilder(builder =>
{
builder.ConfigureLogging(logging =>
{
logging.AddFilter(_ => false); // Suppress all logs during tests
}
);

builder.ConfigureTestServices(services =>
{
// Replace the default DbContext in the WebApplication to use an in-memory SQLite database
Expand Down
25 changes: 25 additions & 0 deletions application/shared-kernel/Tests/TestCategoryAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Xunit.Abstractions;
using Xunit.Sdk;

namespace PlatformPlatform.SharedKernel.Tests;

/// <summary>
/// Categorizes a test for conditional execution.
/// Common categories: "Noisy" (verbose output), "RequiresDocker", "RequiresAzure", "Integration", etc.
/// Use --exclude-category in the Developer CLI to filter out specific test categories.
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
[TraitDiscoverer("PlatformPlatform.SharedKernel.Tests.TestCategoryDiscoverer", "PlatformPlatform.SharedKernel.Tests")]
public sealed class TestCategoryAttribute(string category) : Attribute, ITraitAttribute
{
public string Category { get; } = category;
}

public class TestCategoryDiscoverer : ITraitDiscoverer
{
public IEnumerable<KeyValuePair<string, string>> GetTraits(IAttributeInfo traitAttribute)
{
var category = traitAttribute.GetNamedArgument<string>(nameof(TestCategoryAttribute.Category));
yield return new KeyValuePair<string, string>("Category", category);
}
}
Loading
Loading