Nano Banana Pro
Agent skill for nano-banana-pro
This is a .NET 9 project management API demonstrating **Clean Architecture** and **Domain-Driven Design** principles. The project showcases enterprise-grade development practices with modern .NET patterns.
Sign in to like and favorite skills
This is a .NET 9 project management API demonstrating Clean Architecture and Domain-Driven Design principles. The project showcases enterprise-grade development practices with modern .NET patterns.
Current State: Rich domain layer with 4 bounded contexts implemented. Application and Infrastructure layers are placeholder classes awaiting implementation.
src/ ├── DotNetSkills.API/ # Minimal API with weather template (replace with real endpoints) ├── DotNetSkills.Application/ # Placeholder Class1.cs (implement CQRS + MediatR) ├── DotNetSkills.Domain/ # ✅ Complete - 4 bounded contexts with rich domain models └── DotNetSkills.Infrastructure/ # Placeholder Class1.cs (implement EF Core repositories)
UserManagement/, TeamCollaboration/, ProjectManagement/, TaskExecution/ - each with Entities/, Events/, ValueObjects/, Enums/Team.AddMember(), User.JoinTeam())record UserId(Guid Value) : IStronglyTypedId<Guid> pattern with implicit Guid conversionAggregateRoot<TId>.RaiseDomainEvent() - stored in private _domainEvents list, cleared manuallyUser, Team, Project, Task are separate roots; TeamMember is part of Team aggregate// Strongly-typed ID pattern - ALL entities use this public record UserId(Guid Value) : IStronglyTypedId<Guid> { public static UserId New() => new(Guid.NewGuid()); public static implicit operator Guid(UserId id) => id.Value; public static explicit operator UserId(Guid value) => new(value); } // Aggregate Root pattern with domain events public class User : AggregateRoot<UserId> { public void JoinTeam(Team team, TeamRole role) { // Business rule validation first if (_teamMemberships.Any(m => m.TeamId == team.Id)) throw new DomainException("User is already a member of this team"); // State change var membership = new TeamMember(Id, team.Id, role); _teamMemberships.Add(membership); // Domain event (cross-aggregate communication) RaiseDomainEvent(new UserJoinedTeamDomainEvent(Id, team.Id, role)); } } // Global usings per layer - see Domain/GlobalUsings.cs for the pattern global using DotNetSkills.Domain.Common.Entities; global using DotNetSkills.Domain.UserManagement.ValueObjects;
# Build entire solution dotnet build # Run API (currently placeholder weather API at https://localhost:7240) dotnet run --project src/DotNetSkills.API # Run tests (domain logic tests exist but minimal) dotnet test dotnet test tests/DotNetSkills.Domain.UnitTests # EF migrations (when Infrastructure layer is implemented) dotnet ef migrations add <Name> --project src/DotNetSkills.Infrastructure --startup-project src/DotNetSkills.API
Team.MaxMembers = 50 constant enforced in AddMember()TeamMember entity (part of Team aggregate)ArgumentException for parameter validationDomainException for domain constraint violationsCurrentTask.md for validation standardizationCurrent State: Domain layer complete with 4 bounded contexts. Working on validation standardization (see
CurrentTask.md).
Implementation Priority (based on
plan/feature-dotnetskills-mvp-1.md):
src/DotNetSkills.Domain/{BoundedContext}/Entities/ - Rich domain models with business logicsrc/DotNetSkills.Domain/{BoundedContext}/ValueObjects/ - Strongly-typed IDs and value typessrc/DotNetSkills.Domain/{BoundedContext}/Events/ - Use BaseDomainEvent patternAggregateRoot<TId>, BaseEntity<TId> in Domain/Common/Entities/GlobalUsings.cs with layer-specific importsUser entity with roles, status, team membershipsTeam and TeamMember entities with membership management.github/instructions/dotnet-arquitecture.instructions.mdstring? for nullable, string.Empty for non-nullable defaultsRaiseDomainEvent() in aggregate roots, ClearDomainEvents() after processingDomain/GlobalUsings.cs pattern)Active Task: Domain validation standardization (see
CurrentTask.md)
MVP Plan: Comprehensive implementation roadmap in plan/feature-dotnetskills-mvp-1.md
When implementing new features: