423 lines
11 KiB
Markdown
423 lines
11 KiB
Markdown
Goal for this phase: get a clean, compiling skeleton in place that matches the spec and folder conventions, with zero real logic and minimal dependencies. After this, all future work plugs into this structure.
|
||
|
||
I’ll break it into concrete tasks you can assign to agents.
|
||
|
||
---
|
||
|
||
## 1. Define the repository layout
|
||
|
||
**Owner: “Skeleton” / infra agent**
|
||
|
||
Target layout (no code yet, just dirs):
|
||
|
||
```text
|
||
/ (repo root)
|
||
StellaOps.Router.sln
|
||
/src
|
||
/StellaOps.Gateway.WebService
|
||
/__Libraries
|
||
/StellaOps.Router.Common
|
||
/StellaOps.Router.Config
|
||
/StellaOps.Microservice
|
||
/StellaOps.Microservice.SourceGen (empty stub for now)
|
||
/tests
|
||
/StellaOps.Router.Common.Tests
|
||
/StellaOps.Gateway.WebService.Tests
|
||
/StellaOps.Microservice.Tests
|
||
/docs
|
||
/router
|
||
specs.md (already exists)
|
||
README.md (placeholder, 2–3 lines)
|
||
```
|
||
|
||
Tasks:
|
||
|
||
1. Create `src`, `src/__Libraries`, `tests`, `docs/router` directories if missing.
|
||
2. Move/confirm `docs/router/specs.md` is the canonical spec.
|
||
3. Add `docs/router/README.md` with a pointer: “Start with specs.md; this folder will host router-related docs.”
|
||
|
||
---
|
||
|
||
## 2. Create the solution and projects
|
||
|
||
**Owner: skeleton agent**
|
||
|
||
### 2.1 Create solution
|
||
|
||
* At repo root:
|
||
|
||
```bash
|
||
dotnet new sln -n StellaOps.Router
|
||
```
|
||
|
||
* Add projects as they are created in the next step.
|
||
|
||
### 2.2 Create projects
|
||
|
||
For each project below:
|
||
|
||
* `dotnet new` with appropriate template.
|
||
* Set `RootNamespace` / `AssemblyName` to match folder & spec.
|
||
|
||
Projects:
|
||
|
||
1. **Gateway webservice**
|
||
|
||
```bash
|
||
cd src/StellaOps.Gateway.WebService
|
||
dotnet new webapi -n StellaOps.Gateway.WebService
|
||
```
|
||
|
||
* This will create an ASP.NET Core Web API project; we’ll trim later.
|
||
|
||
2. **Common library**
|
||
|
||
```bash
|
||
cd src/__Libraries
|
||
dotnet new classlib -n StellaOps.Router.Common
|
||
```
|
||
|
||
3. **Config library**
|
||
|
||
```bash
|
||
dotnet new classlib -n StellaOps.Router.Config
|
||
```
|
||
|
||
4. **Microservice SDK**
|
||
|
||
```bash
|
||
dotnet new classlib -n StellaOps.Microservice
|
||
```
|
||
|
||
5. **Microservice Source Generator (stub)**
|
||
|
||
```bash
|
||
dotnet new classlib -n StellaOps.Microservice.SourceGen
|
||
```
|
||
|
||
* This will be converted to an Analyzer/SourceGen project later; for now it can compile as a plain library.
|
||
|
||
6. **Test projects**
|
||
|
||
Under `tests`:
|
||
|
||
```bash
|
||
cd tests
|
||
dotnet new xunit -n StellaOps.Router.Common.Tests
|
||
dotnet new xunit -n StellaOps.Gateway.WebService.Tests
|
||
dotnet new xunit -n StellaOps.Microservice.Tests
|
||
```
|
||
|
||
### 2.3 Add projects to solution
|
||
|
||
At repo root:
|
||
|
||
```bash
|
||
dotnet sln StellaOps.Router.sln add \
|
||
src/StellaOps.Gateway.WebService/StellaOps.Gateway.WebService.csproj \
|
||
src/__Libraries/StellaOps.Router.Common/StellaOps.Router.Common.csproj \
|
||
src/__Libraries/StellaOps.Router.Config/StellaOps.Router.Config.csproj \
|
||
src/__Libraries/StellaOps.Microservice/StellaOps.Microservice.csproj \
|
||
src/__Libraries/StellaOps.Microservice.SourceGen/StellaOps.Microservice.SourceGen.csproj \
|
||
tests/StellaOps.Router.Common.Tests/StellaOps.Router.Common.Tests.csproj \
|
||
tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj \
|
||
tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Wire basic project references
|
||
|
||
**Owner: skeleton agent**
|
||
|
||
The reference graph should be:
|
||
|
||
* `StellaOps.Gateway.WebService`
|
||
|
||
* references `StellaOps.Router.Common`
|
||
* references `StellaOps.Router.Config`
|
||
|
||
* `StellaOps.Microservice`
|
||
|
||
* references `StellaOps.Router.Common`
|
||
* (later) references `StellaOps.Microservice.SourceGen` as analyzer; for now no reference.
|
||
|
||
* `StellaOps.Router.Config`
|
||
|
||
* references `StellaOps.Router.Common` (for `EndpointDescriptor`, `InstanceDescriptor`, etc.)
|
||
|
||
Test projects:
|
||
|
||
* `StellaOps.Router.Common.Tests` → `StellaOps.Router.Common`
|
||
* `StellaOps.Gateway.WebService.Tests` → `StellaOps.Gateway.WebService`
|
||
* `StellaOps.Microservice.Tests` → `StellaOps.Microservice`
|
||
|
||
Use `dotnet add reference`:
|
||
|
||
```bash
|
||
dotnet add src/StellaOps.Gateway.WebService/StellaOps.Gateway.WebService.csproj reference \
|
||
src/__Libraries/StellaOps.Router.Common/StellaOps.Router.Common.csproj \
|
||
src/__Libraries/StellaOps.Router.Config/StellaOps.Router.Config.csproj
|
||
|
||
dotnet add src/__Libraries/StellaOps.Microservice/StellaOps.Microservice.csproj reference \
|
||
src/__Libraries/StellaOps.Router.Common/StellaOps.Router.Common.csproj
|
||
|
||
dotnet add src/__Libraries/StellaOps.Router.Config/StellaOps.Router.Config.csproj reference \
|
||
src/__Libraries/StellaOps.Router.Common/StellaOps.Router.Common.csproj
|
||
|
||
dotnet add tests/StellaOps.Router.Common.Tests/StellaOps.Router.Common.Tests.csproj reference \
|
||
src/__Libraries/StellaOps.Router.Common/StellaOps.Router.Common.csproj
|
||
|
||
dotnet add tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj reference \
|
||
src/StellaOps.Gateway.WebService/StellaOps.Gateway.WebService.csproj
|
||
|
||
dotnet add tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj reference \
|
||
src/__Libraries/StellaOps.Microservice/StellaOps.Microservice.csproj
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Set common build settings
|
||
|
||
**Owner: infra agent**
|
||
|
||
Add a `Directory.Build.props` at repo root to centralize:
|
||
|
||
* Target framework (e.g. `net8.0`).
|
||
* Nullable context.
|
||
* LangVersion.
|
||
|
||
Example (minimal):
|
||
|
||
```xml
|
||
<Project>
|
||
<PropertyGroup>
|
||
<TargetFramework>net8.0</TargetFramework>
|
||
<Nullable>enable</Nullable>
|
||
<LangVersion>preview</LangVersion> <!-- if needed for newer features -->
|
||
<ImplicitUsings>enable</ImplicitUsings>
|
||
</PropertyGroup>
|
||
</Project>
|
||
```
|
||
|
||
Then, strip redundant `<TargetFramework>` from individual `.csproj` files if desired.
|
||
|
||
---
|
||
|
||
## 5. Stub namespaces and “empty” entry points
|
||
|
||
**Owner: each project’s agent**
|
||
|
||
### 5.1 Common library
|
||
|
||
Create empty placeholder types that match the spec names (no logic, just shells) so everything compiles and IntelliSense knows the shapes.
|
||
|
||
Example files:
|
||
|
||
* `TransportType.cs`
|
||
* `FrameType.cs`
|
||
* `InstanceHealthStatus.cs`
|
||
* `ClaimRequirement.cs`
|
||
* `EndpointDescriptor.cs`
|
||
* `InstanceDescriptor.cs`
|
||
* `ConnectionState.cs`
|
||
* `RoutingContext.cs`
|
||
* `RoutingDecision.cs`
|
||
* `PayloadLimits.cs`
|
||
* Interfaces: `IGlobalRoutingState`, `IRoutingPlugin`, `ITransportServer`, `ITransportClient`.
|
||
|
||
Each type can be an auto-property-only record/class/enum; no methods yet.
|
||
|
||
Example:
|
||
|
||
```csharp
|
||
namespace StellaOps.Router.Common;
|
||
|
||
public enum TransportType
|
||
{
|
||
Udp,
|
||
Tcp,
|
||
Certificate,
|
||
RabbitMq
|
||
}
|
||
```
|
||
|
||
and so on.
|
||
|
||
### 5.2 Config library
|
||
|
||
Add a minimal `RouterConfig` and `PayloadLimits` class aligned with the spec; again, just properties.
|
||
|
||
```csharp
|
||
namespace StellaOps.Router.Config;
|
||
|
||
public sealed class RouterConfig
|
||
{
|
||
public IList<ServiceConfig> Services { get; init; } = new List<ServiceConfig>();
|
||
public PayloadLimits PayloadLimits { get; init; } = new();
|
||
}
|
||
|
||
public sealed class ServiceConfig
|
||
{
|
||
public string Name { get; init; } = string.Empty;
|
||
public string DefaultVersion { get; init; } = "1.0.0";
|
||
}
|
||
```
|
||
|
||
No YAML binding, no logic yet.
|
||
|
||
### 5.3 Microservice library
|
||
|
||
Create:
|
||
|
||
* `StellaMicroserviceOptions` with required properties.
|
||
* `RouterEndpointConfig` (host/port/transport).
|
||
* Extension method `AddStellaMicroservice(...)` with an empty body that just registers options and placeholder services.
|
||
|
||
```csharp
|
||
namespace StellaOps.Microservice;
|
||
|
||
public sealed class StellaMicroserviceOptions
|
||
{
|
||
public string ServiceName { get; set; } = string.Empty;
|
||
public string Version { get; set; } = string.Empty;
|
||
public string Region { get; set; } = string.Empty;
|
||
public string InstanceId { get; set; } = string.Empty;
|
||
public IList<RouterEndpointConfig> Routers { get; set; } = new List<RouterEndpointConfig>();
|
||
public string? ConfigFilePath { get; set; }
|
||
}
|
||
|
||
public sealed class RouterEndpointConfig
|
||
{
|
||
public string Host { get; set; } = string.Empty;
|
||
public int Port { get; set; }
|
||
public TransportType TransportType { get; set; }
|
||
}
|
||
```
|
||
|
||
`AddStellaMicroservice`:
|
||
|
||
```csharp
|
||
public static class ServiceCollectionExtensions
|
||
{
|
||
public static IServiceCollection AddStellaMicroservice(
|
||
this IServiceCollection services,
|
||
Action<StellaMicroserviceOptions> configure)
|
||
{
|
||
services.Configure(configure);
|
||
// TODO: register internal SDK services in later phases
|
||
return services;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.4 Microservice.SourceGen
|
||
|
||
For now:
|
||
|
||
* Leave this as an empty classlib with an empty `README.md` stating:
|
||
|
||
* “This project will host Roslyn source generators for endpoint discovery. No implementation yet.”
|
||
|
||
Don’t hook it as an analyzer until there is content.
|
||
|
||
### 5.5 Gateway webservice
|
||
|
||
Simplify the scaffolded Web API to minimal:
|
||
|
||
* In `Program.cs`:
|
||
|
||
* Build a barebones `WebApplication` that:
|
||
|
||
* Binds `GatewayNodeConfig` from config.
|
||
* Adds controllers or minimal endpoints.
|
||
* Runs; no router logic yet.
|
||
|
||
Example:
|
||
|
||
```csharp
|
||
var builder = WebApplication.CreateBuilder(args);
|
||
|
||
builder.Services.Configure<GatewayNodeConfig>(
|
||
builder.Configuration.GetSection("GatewayNode"));
|
||
|
||
builder.Services.AddControllers();
|
||
|
||
var app = builder.Build();
|
||
|
||
app.MapControllers(); // may be empty for now
|
||
|
||
app.Run();
|
||
```
|
||
|
||
* Add `GatewayNodeConfig` class in `StellaOps.Gateway.WebService` project.
|
||
|
||
---
|
||
|
||
## 6. Make tests compile (even if empty)
|
||
|
||
**Owner: test agent**
|
||
|
||
For each test project:
|
||
|
||
* Reference the appropriate main project (already done).
|
||
* Add a single dummy test class so CI passes:
|
||
|
||
```csharp
|
||
public class SmokeTests
|
||
{
|
||
[Fact]
|
||
public void SolutionCompiles()
|
||
{
|
||
Assert.True(true);
|
||
}
|
||
}
|
||
```
|
||
|
||
This is just to ensure the pipeline runs; real tests come later.
|
||
|
||
---
|
||
|
||
## 7. Add initial CI/build pipeline
|
||
|
||
**Owner: infra agent**
|
||
|
||
Set up minimal CI (GitHub Actions, GitLab, Azure DevOps, whatever you use):
|
||
|
||
* Steps:
|
||
|
||
* `dotnet restore`
|
||
* `dotnet build StellaOps.Router.sln -c Release`
|
||
* `dotnet test StellaOps.Router.sln -c Release`
|
||
|
||
No packaging or deployment yet; just compile + tests.
|
||
|
||
---
|
||
|
||
## 8. Sanity check & readiness criteria
|
||
|
||
Before you let agents move to “Common model implementation” (next phase), confirm:
|
||
|
||
* The solution builds cleanly in a clean checkout (`dotnet restore`, `dotnet build`).
|
||
* All test projects run and pass (even with dummy tests).
|
||
* Namespaces and project names match the spec:
|
||
|
||
* `StellaOps.Gateway.WebService`
|
||
* `StellaOps.Router.Common`
|
||
* `StellaOps.Router.Config`
|
||
* `StellaOps.Microservice`
|
||
* There is no real business logic yet:
|
||
|
||
* No transport logic.
|
||
* No routing decisions.
|
||
* No reflection or YAML.
|
||
* `docs/router/specs.md` is referenced in `docs/router/README.md` as the spec.
|
||
|
||
At that point, the skeleton is in place and stable. Next phases can then focus on:
|
||
|
||
* Filling in `Common` contracts properly.
|
||
* Implementing the in-memory transport.
|
||
* Wiring minimal microservice/gateway flows.
|
||
|
||
If you want, I can outline the next phase (“implement core model + in-memory transport”) with a similar task breakdown next.
|