Link / Unlink SuperCoach Team Commands
Aggregate: SupercoachTeamAggregate
Commands: LinkSupercoachTeamCommand, UnlinkSupercoachTeamCommand
Endpoint: POST /api/command
Authentication: Bearer JWT, requires Member role
Testing guide: Testing CQRS Command System
Summary
These two commands allow a Ballr user to associate (or disassociate) their existing Ballr team aggregate with a SuperCoach team identity found via search.
- Link — sets
SupercoachTeamExternalId and SupercoachUserId on the aggregate and raises SupercoachTeamLinkedEvent.
- Unlink — clears both fields (resets to
0) and raises SupercoachTeamUnlinkedEvent, with an optional UnlinkReason.
Commands
LinkSupercoachTeamCommand
{
"commandType": "LinkSupercoachTeam",
"command": {
"aggregateRootId": "123e4567-e89b-12d3-a456-426614174000",
"supercoachTeamExternalId": 987654,
"supercoachUserId": 112233
},
"expectedVersion": 0
}
| Field |
Type |
Required |
Description |
commandType |
string |
Yes |
Must be "LinkSupercoachTeam" |
command.aggregateRootId |
GUID |
Yes |
ID of the existing SupercoachTeamAggregate |
command.supercoachTeamExternalId |
long |
Yes |
External SuperCoach team ID (must be > 0) |
command.supercoachUserId |
long |
Yes |
External SuperCoach user ID (must be > 0) |
expectedVersion |
int |
No |
Optimistic concurrency version (default: 0) |
UnlinkSupercoachTeamCommand
{
"commandType": "UnlinkSupercoachTeam",
"command": {
"aggregateRootId": "123e4567-e89b-12d3-a456-426614174000",
"unlinkReason": "Linked the wrong team"
},
"expectedVersion": 0
}
| Field |
Type |
Required |
Description |
commandType |
string |
Yes |
Must be "UnlinkSupercoachTeam" |
command.aggregateRootId |
GUID |
Yes |
ID of the existing SupercoachTeamAggregate |
command.unlinkReason |
string? |
No |
Optional reason the user is unlinking |
expectedVersion |
int |
No |
Optimistic concurrency version (default: 0) |
Events Raised
SupercoachTeamLinkedEvent
Raised when a SuperCoach identity is successfully linked to a Ballr team aggregate.
| Field |
Type |
Description |
SupercoachTeamExternalId |
long |
The external SuperCoach team ID that was linked |
SupercoachUserId |
long |
The external SuperCoach user ID that was linked |
LinkedAt |
DateTimeOffset |
Timestamp when the link occurred (UTC) |
SupercoachTeamUnlinkedEvent
Raised when a SuperCoach identity is successfully unlinked from a Ballr team aggregate.
| Field |
Type |
Description |
UnlinkedAt |
DateTimeOffset |
Timestamp when the unlink occurred (UTC) |
UnlinkReason |
string? |
Optional reason provided by the user |
Validation Rules
LinkSupercoachTeamCommand
| Rule |
Error Message |
| Aggregate must exist (created) |
Cannot link non-existent team |
| Aggregate must not be archived |
Cannot link archived team |
| Team must not already be linked |
Team is already linked to a SuperCoach identity. Unlink first before linking a new one |
SupercoachTeamExternalId must be > 0 |
SupercoachTeamExternalId must be positive |
SupercoachUserId must be > 0 |
SupercoachUserId must be positive |
UnlinkSupercoachTeamCommand
| Rule |
Error Message |
| Aggregate must exist (created) |
Cannot unlink non-existent team |
| Aggregate must not be archived |
Cannot unlink archived team |
| Team must currently be linked |
Team has no linked SuperCoach identity |
Response
LinkSupercoachTeam — Success 200 OK
{
"requestId": "a1b2c3d4-0000-0000-0000-000000000000",
"success": true,
"eventCount": 1,
"commandType": "LinkSupercoachTeam"
}
LinkSupercoachTeam — Failure 400 Bad Request
{
"requestId": "a1b2c3d4-0000-0000-0000-000000000000",
"success": false,
"eventCount": 0,
"errorMessage": "Team is already linked to a SuperCoach identity. Unlink first before linking a new one",
"errorCode": "COMMAND_VALIDATION_ERROR",
"commandType": "LinkSupercoachTeam"
}
UnlinkSupercoachTeam — Success 200 OK
{
"requestId": "a1b2c3d4-0000-0000-0000-000000000000",
"success": true,
"eventCount": 1,
"commandType": "UnlinkSupercoachTeam"
}
UnlinkSupercoachTeam — Failure 400 Bad Request
{
"requestId": "a1b2c3d4-0000-0000-0000-000000000000",
"success": false,
"eventCount": 0,
"errorMessage": "Team has no linked SuperCoach identity",
"errorCode": "COMMAND_VALIDATION_ERROR",
"commandType": "UnlinkSupercoachTeam"
}
Response Fields
| Field |
Type |
Description |
requestId |
GUID? |
Echoed from the request requestId, if provided |
success |
bool |
true when the command was accepted and events were persisted |
eventCount |
int |
Number of domain events raised (1 on success, 0 on failure) |
errorMessage |
string? |
Human-readable description of the failure (only on error) |
errorCode |
string? |
Programmatic error code (only on error) |
commandType |
string |
The command type that was processed |
SDK Types
When consuming these commands from the frontend, use the following types from @luckboxstudios/foundry-sdk:
| Import |
Type |
Purpose |
@luckboxstudios/foundry-sdk |
LinkSupercoachTeam |
Link command input interface |
@luckboxstudios/foundry-sdk |
UnlinkSupercoachTeam |
Unlink command input interface |
@luckboxstudios/foundry-sdk/ballr |
ballrCommands.linkSupercoachTeam(...) |
Link builder function (sets commandType automatically) |
@luckboxstudios/foundry-sdk/ballr |
ballrCommands.unlinkSupercoachTeam(...) |
Unlink builder function (sets commandType automatically) |
Usage Example
import type { LinkSupercoachTeam, UnlinkSupercoachTeam } from '@luckboxstudios/foundry-sdk';
import { ballrCommands } from '@luckboxstudios/foundry-sdk/ballr';
// Link
const linkCmd = ballrCommands.linkSupercoachTeam({
aggregateRootId: '123e4567-e89b-12d3-a456-426614174000',
supercoachTeamExternalId: 987654,
supercoachUserId: 112233
});
await client.execute<LinkSupercoachTeam>(linkCmd, { expectedVersion: 0 });
// Unlink
const unlinkCmd = ballrCommands.unlinkSupercoachTeam({
aggregateRootId: '123e4567-e89b-12d3-a456-426614174000',
unlinkReason: 'Linked the wrong team'
});
await client.execute<UnlinkSupercoachTeam>(unlinkCmd, { expectedVersion: 1 });
| File |
Purpose |
src/Domain/LBS.Ballr.Core/SupercoachTeam/Commands/LinkSupercoachTeamCommand.cs |
Command definition |
src/Domain/LBS.Ballr.Core/SupercoachTeam/Commands/UnlinkSupercoachTeamCommand.cs |
Command definition |
src/Domain/LBS.Ballr.Core/SupercoachTeam/Events/SupercoachTeamLinkedEvent.cs |
Event definition |
src/Domain/LBS.Ballr.Core/SupercoachTeam/Events/SupercoachTeamUnlinkedEvent.cs |
Event definition |
src/Domain/LBS.Ballr.Core/SupercoachTeam/SupercoachTeamAggregate.cs |
Execute / Validate / Apply logic |
src/Domain/LBS.Ballr.Core/SupercoachTeam/ContractBuilder/SupercoachTeamContractBuilder.cs |
Read model projection |