@atlashub/smartstack-cli 4.32.0 → 4.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.documentation/index.html +2 -2
  2. package/.documentation/init.html +358 -174
  3. package/dist/index.js +45 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/mcp-entry.mjs +271 -44
  6. package/dist/mcp-entry.mjs.map +1 -1
  7. package/package.json +1 -1
  8. package/templates/mcp-scaffolding/controller.cs.hbs +54 -128
  9. package/templates/project/README.md +19 -0
  10. package/templates/project/claude-md/api.CLAUDE.md.template +315 -0
  11. package/templates/project/claude-md/application.CLAUDE.md.template +181 -0
  12. package/templates/project/claude-md/domain.CLAUDE.md.template +125 -0
  13. package/templates/project/claude-md/infrastructure.CLAUDE.md.template +168 -0
  14. package/templates/project/claude-md/root.CLAUDE.md.template +339 -0
  15. package/templates/project/claude-md/web.CLAUDE.md.template +339 -0
  16. package/templates/skills/apex/SKILL.md +16 -10
  17. package/templates/skills/apex/_shared.md +1 -1
  18. package/templates/skills/apex/references/checks/architecture-checks.sh +154 -0
  19. package/templates/skills/apex/references/checks/backend-checks.sh +194 -0
  20. package/templates/skills/apex/references/checks/frontend-checks.sh +448 -0
  21. package/templates/skills/apex/references/checks/infrastructure-checks.sh +255 -0
  22. package/templates/skills/apex/references/checks/security-checks.sh +153 -0
  23. package/templates/skills/apex/references/checks/seed-checks.sh +536 -0
  24. package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +49 -192
  25. package/templates/skills/apex/references/post-checks.md +124 -2156
  26. package/templates/skills/apex/references/smartstack-api.md +160 -957
  27. package/templates/skills/apex/references/smartstack-frontend.md +134 -1022
  28. package/templates/skills/apex/references/smartstack-layers.md +12 -6
  29. package/templates/skills/apex/steps/step-00-init.md +81 -238
  30. package/templates/skills/apex/steps/step-03-execute.md +25 -752
  31. package/templates/skills/apex/steps/step-03a-layer0-domain.md +118 -0
  32. package/templates/skills/apex/steps/step-03b-layer1-seed.md +91 -0
  33. package/templates/skills/apex/steps/step-03c-layer2-backend.md +240 -0
  34. package/templates/skills/apex/steps/step-03d-layer3-frontend.md +300 -0
  35. package/templates/skills/apex/steps/step-03e-layer4-devdata.md +44 -0
  36. package/templates/skills/apex/steps/step-04-examine.md +70 -150
  37. package/templates/skills/application/references/frontend-i18n-and-output.md +2 -2
  38. package/templates/skills/application/references/frontend-route-naming.md +5 -1
  39. package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +49 -198
  40. package/templates/skills/application/references/frontend-verification.md +11 -11
  41. package/templates/skills/application/steps/step-05-frontend.md +26 -15
  42. package/templates/skills/application/templates-frontend.md +4 -0
  43. package/templates/skills/cli-app-sync/SKILL.md +2 -2
  44. package/templates/skills/cli-app-sync/references/comparison-map.md +1 -1
  45. package/templates/skills/controller/references/controller-code-templates.md +70 -67
  46. package/templates/skills/controller/references/mcp-scaffold-workflow.md +5 -1
@@ -0,0 +1,181 @@
1
+ # {{ProjectName}}.Application - Memory
2
+
3
+ ## Purpose
4
+
5
+ Use cases orchestration. Defines WHAT the application does. Contains business logic that doesn't belong to entities.
6
+
7
+ ## Dependencies
8
+
9
+ - **{{ProjectName}}.Domain** (entities, interfaces)
10
+ - **MediatR** (CQRS) - add when needed
11
+ - **FluentValidation** - add when needed
12
+ - **AutoMapper** - add when needed
13
+
14
+ ## Structure
15
+
16
+ ```
17
+ {{ProjectName}}.Application/
18
+ ├── Common/
19
+ │ ├── Authorization/ → Permissions constants
20
+ │ ├── Behaviors/ → MediatR pipeline behaviors
21
+ │ ├── Exceptions/ → Application exceptions
22
+ │ ├── Interfaces/
23
+ │ │ ├── Identity/ → ICurrentUserService, IJwtService
24
+ │ │ └── Persistence/ → IExtensionsDbContext
25
+ │ └── Licensing/ → License validation
26
+ ├── {Feature}/ → Feature-specific commands/queries
27
+ │ ├── Commands/
28
+ │ ├── Queries/
29
+ │ └── DTOs/
30
+ └── DependencyInjection.cs
31
+ ```
32
+
33
+ ## Patterns
34
+
35
+ ### Command Template (with MediatR)
36
+
37
+ ```csharp
38
+ namespace {{ProjectName}}.Application.{Feature}.Commands;
39
+
40
+ // Command
41
+ public record CreateOrderCommand(string Name, decimal Amount) : IRequest<Guid>;
42
+
43
+ // Handler
44
+ public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, Guid>
45
+ {
46
+ private readonly IExtensionsDbContext _context;
47
+
48
+ public CreateOrderCommandHandler(IExtensionsDbContext context)
49
+ {
50
+ _context = context;
51
+ }
52
+
53
+ public async Task<Guid> Handle(CreateOrderCommand request, CancellationToken ct)
54
+ {
55
+ var order = Order.Create(request.Name, request.Amount);
56
+
57
+ await _context.Orders.AddAsync(order, ct);
58
+ await _context.SaveChangesAsync(ct);
59
+
60
+ return order.Id;
61
+ }
62
+ }
63
+
64
+ // Validator (FluentValidation)
65
+ public class CreateOrderCommandValidator : AbstractValidator<CreateOrderCommand>
66
+ {
67
+ public CreateOrderCommandValidator()
68
+ {
69
+ RuleFor(x => x.Name)
70
+ .NotEmpty().WithMessage("Name is required")
71
+ .MaximumLength(200).WithMessage("Name max 200 chars");
72
+
73
+ RuleFor(x => x.Amount)
74
+ .GreaterThan(0).WithMessage("Amount must be positive");
75
+ }
76
+ }
77
+ ```
78
+
79
+ ### Query Template
80
+
81
+ ```csharp
82
+ namespace {{ProjectName}}.Application.{Feature}.Queries;
83
+
84
+ // Query
85
+ public record GetOrdersQuery(string? SearchTerm = null) : IRequest<IReadOnlyList<OrderDto>>;
86
+
87
+ // Handler
88
+ public class GetOrdersQueryHandler : IRequestHandler<GetOrdersQuery, IReadOnlyList<OrderDto>>
89
+ {
90
+ private readonly IExtensionsDbContext _context;
91
+ private readonly IMapper _mapper;
92
+
93
+ public GetOrdersQueryHandler(IExtensionsDbContext context, IMapper mapper)
94
+ {
95
+ _context = context;
96
+ _mapper = mapper;
97
+ }
98
+
99
+ public async Task<IReadOnlyList<OrderDto>> Handle(GetOrdersQuery request, CancellationToken ct)
100
+ {
101
+ var query = _context.Orders.AsNoTracking();
102
+
103
+ if (!string.IsNullOrWhiteSpace(request.SearchTerm))
104
+ query = query.Where(o => o.Name.Contains(request.SearchTerm));
105
+
106
+ return await query
107
+ .ProjectTo<OrderDto>(_mapper.ConfigurationProvider)
108
+ .ToListAsync(ct);
109
+ }
110
+ }
111
+ ```
112
+
113
+ ### DTO Template
114
+
115
+ ```csharp
116
+ namespace {{ProjectName}}.Application.{Feature}.DTOs;
117
+
118
+ public record OrderDto(Guid Id, string Name, decimal Amount, DateTime CreatedAt);
119
+
120
+ // AutoMapper Profile
121
+ public class OrderProfile : Profile
122
+ {
123
+ public OrderProfile()
124
+ {
125
+ CreateMap<Order, OrderDto>();
126
+ }
127
+ }
128
+ ```
129
+
130
+ ### Interface Template (ExtensionsDbContext)
131
+
132
+ ```csharp
133
+ namespace {{ProjectName}}.Application.Common.Interfaces.Persistence;
134
+
135
+ public interface IExtensionsDbContext
136
+ {
137
+ DbSet<Order> Orders { get; }
138
+ // Add DbSets for your entities here
139
+ Task<int> SaveChangesAsync(CancellationToken ct = default);
140
+ }
141
+ ```
142
+
143
+ ## DependencyInjection Setup
144
+
145
+ ```csharp
146
+ public static class DependencyInjection
147
+ {
148
+ public static IServiceCollection AddApplication(this IServiceCollection services)
149
+ {
150
+ var assembly = typeof(DependencyInjection).Assembly;
151
+
152
+ services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(assembly));
153
+ services.AddValidatorsFromAssembly(assembly);
154
+ services.AddAutoMapper(assembly);
155
+ services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
156
+ services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
157
+
158
+ return services;
159
+ }
160
+ }
161
+ ```
162
+
163
+ ## Rules
164
+
165
+ 1. **NO** direct database access - use `IExtensionsDbContext` (from Common/Interfaces/Persistence)
166
+ 2. **NO** HttpContext, Controllers - that's API layer
167
+ 3. **Commands** modify state, return Id or nothing
168
+ 4. **Queries** read-only, return DTOs
169
+ 5. **Handlers** are the use cases
170
+ 6. **One handler per command/query**
171
+
172
+ ## When Adding New Feature
173
+
174
+ 1. Create folder in `{Feature}/` (appropriate namespace path)
175
+ 2. Add `Commands/` and/or `Queries/` subfolders
176
+ 3. Add `DTOs/` subfolder if needed
177
+ 4. Create Command/Query record
178
+ 5. Create Handler class
179
+ 6. Create Validator (optional but recommended)
180
+ 7. Add DTO record and AutoMapper profile if needed
181
+ 8. Register in `DependencyInjection.cs`
@@ -0,0 +1,125 @@
1
+ # {{ProjectName}}.Domain - Memory
2
+
3
+ ## Purpose
4
+
5
+ Core business logic. **ZERO external dependencies**. This layer defines WHAT the business does, not HOW.
6
+
7
+ ## Structure
8
+
9
+ ```
10
+ {{ProjectName}}.Domain/
11
+ ├── Common/
12
+ │ ├── BaseEntity.cs → Base for all entities (Id, CreatedAt, UpdatedAt)
13
+ │ └── IAuditableEntity.cs → Audit tracking interface
14
+ ├── Enums/ → Domain enumerations
15
+ ├── {Feature}/ → Feature-specific entities
16
+ │ ├── Order.cs → Aggregate root
17
+ │ └── OrderItem.cs → Child entity
18
+ ├── Exceptions/ → DomainException, custom exceptions
19
+ └── Interfaces/ → Repository contracts
20
+ ```
21
+
22
+ ## Rules (STRICT)
23
+
24
+ 1. **NO** NuGet packages except BCL
25
+ 2. **NO** `using` statements referencing other projects
26
+ 3. **NO** EF Core attributes (`[Key]`, `[Required]`) - use Fluent API in Infrastructure
27
+ 4. **NO** DTOs - entities only
28
+ 5. **ALL** business rules live here
29
+
30
+ ## Patterns
31
+
32
+ ### Entity Template
33
+
34
+ ```csharp
35
+ namespace {{ProjectName}}.Domain.{Feature};
36
+
37
+ public class Order : BaseEntity
38
+ {
39
+ public string Name { get; private set; } = null!;
40
+ public decimal Amount { get; private set; }
41
+ public bool IsActive { get; private set; }
42
+
43
+ private Order() { } // EF Core
44
+
45
+ public static Order Create(string name, decimal amount)
46
+ {
47
+ if (string.IsNullOrWhiteSpace(name))
48
+ throw new DomainException("Name is required");
49
+ if (amount <= 0)
50
+ throw new DomainException("Amount must be positive");
51
+
52
+ return new Order
53
+ {
54
+ Id = Guid.NewGuid(),
55
+ Name = name,
56
+ Amount = amount,
57
+ IsActive = true,
58
+ CreatedAt = DateTime.UtcNow
59
+ };
60
+ }
61
+
62
+ public void Deactivate()
63
+ {
64
+ IsActive = false;
65
+ UpdatedAt = DateTime.UtcNow;
66
+ }
67
+ }
68
+ ```
69
+
70
+ ### Value Object Template
71
+
72
+ ```csharp
73
+ namespace {{ProjectName}}.Domain.Common.ValueObjects;
74
+
75
+ public record Money(decimal Amount, string Currency)
76
+ {
77
+ public static Money Create(decimal amount, string currency)
78
+ {
79
+ if (amount < 0)
80
+ throw new DomainException("Amount cannot be negative");
81
+ if (string.IsNullOrWhiteSpace(currency))
82
+ throw new DomainException("Currency is required");
83
+
84
+ return new Money(amount, currency);
85
+ }
86
+ }
87
+ ```
88
+
89
+ ### Domain Event Template
90
+
91
+ ```csharp
92
+ namespace {{ProjectName}}.Domain.Common.Events;
93
+
94
+ public record OrderCreatedEvent(Guid OrderId, string Name, DateTime OccurredAt);
95
+ ```
96
+
97
+ ### Repository Interface Template
98
+
99
+ ```csharp
100
+ namespace {{ProjectName}}.Domain.Interfaces;
101
+
102
+ public interface IRepository<T> where T : BaseEntity
103
+ {
104
+ Task<T?> GetByIdAsync(Guid id, CancellationToken ct = default);
105
+ Task<IReadOnlyList<T>> GetAllAsync(CancellationToken ct = default);
106
+ Task AddAsync(T entity, CancellationToken ct = default);
107
+ void Update(T entity);
108
+ void Remove(T entity);
109
+ }
110
+ ```
111
+
112
+ ## Validation
113
+
114
+ - **Entities validate themselves** in constructors and methods
115
+ - Throw `DomainException` for business rule violations
116
+ - Use **Guard clauses** at method start
117
+
118
+ ## When Adding New Entity
119
+
120
+ 1. Create in the appropriate domain folder
121
+ 2. Inherit from `BaseEntity`
122
+ 3. Private parameterless constructor for EF
123
+ 4. Static `Create()` factory method
124
+ 5. Encapsulate all state changes in methods
125
+ 6. Add repository interface in `Interfaces/`
@@ -0,0 +1,168 @@
1
+ # {{ProjectName}}.Infrastructure - Memory
2
+
3
+ ## Purpose
4
+
5
+ Technical implementations. HOW things work. EF Core, external APIs, file system, email, etc.
6
+
7
+ ## Dependencies
8
+
9
+ - **{{ProjectName}}.Domain** (entities, repository interfaces)
10
+ - **{{ProjectName}}.Application** (IExtensionsDbContext, service interfaces)
11
+ - **Microsoft.EntityFrameworkCore.SqlServer**
12
+ - **Microsoft.EntityFrameworkCore.Design**
13
+
14
+ ## Structure
15
+
16
+ ```
17
+ {{ProjectName}}.Infrastructure/
18
+ ├── Persistence/
19
+ │ ├── ExtensionsDbContext.cs → EF Core DbContext (implements IExtensionsDbContext)
20
+ │ ├── Configurations/ → Entity configurations (Fluent API)
21
+ │ │ ├── {Feature}/ → Feature-specific configs
22
+ │ │ └── SchemaConstants.cs → Extensions="extensions"
23
+ │ ├── Migrations/ → EF Core migrations
24
+ │ └── Seeding/ → Database seeders
25
+ ├── Services/ → Service implementations
26
+ └── DependencyInjection.cs
27
+ ```
28
+
29
+ ## Patterns
30
+
31
+ ### DbContext Template
32
+
33
+ ```csharp
34
+ namespace {{ProjectName}}.Infrastructure.Persistence;
35
+
36
+ public class ExtensionsDbContext : DbContext, IExtensionsDbContext
37
+ {
38
+ public ExtensionsDbContext(DbContextOptions<ExtensionsDbContext> options)
39
+ : base(options) { }
40
+
41
+ public DbSet<Order> Orders => Set<Order>();
42
+
43
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
44
+ {
45
+ base.OnModelCreating(modelBuilder);
46
+ modelBuilder.HasDefaultSchema(SchemaConstants.Extensions);
47
+ modelBuilder.ApplyConfigurationsFromAssembly(typeof(ExtensionsDbContext).Assembly);
48
+ }
49
+
50
+ public override async Task<int> SaveChangesAsync(CancellationToken ct = default)
51
+ {
52
+ return await base.SaveChangesAsync(ct);
53
+ }
54
+ }
55
+ ```
56
+
57
+ ### Entity Configuration Template
58
+
59
+ ```csharp
60
+ namespace {{ProjectName}}.Infrastructure.Persistence.Configurations.{Feature};
61
+
62
+ public class OrderConfiguration : IEntityTypeConfiguration<Order>
63
+ {
64
+ public void Configure(EntityTypeBuilder<Order> builder)
65
+ {
66
+ builder.ToTable("ext_Orders", SchemaConstants.Extensions);
67
+
68
+ builder.HasKey(o => o.Id);
69
+
70
+ builder.Property(o => o.Name)
71
+ .IsRequired()
72
+ .HasMaxLength(200);
73
+
74
+ builder.Property(o => o.Amount)
75
+ .HasPrecision(18, 2);
76
+
77
+ builder.HasIndex(o => o.Name);
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### Repository Implementation Template
83
+
84
+ ```csharp
85
+ namespace {{ProjectName}}.Infrastructure.Persistence.Repositories;
86
+
87
+ public class OrderRepository : IOrderRepository
88
+ {
89
+ private readonly ExtensionsDbContext _context;
90
+
91
+ public OrderRepository(ExtensionsDbContext context)
92
+ {
93
+ _context = context;
94
+ }
95
+
96
+ public async Task<Order?> GetByIdAsync(Guid id, CancellationToken ct = default)
97
+ => await _context.Orders.FindAsync(new object[] { id }, ct);
98
+
99
+ public async Task<IReadOnlyList<Order>> GetAllAsync(CancellationToken ct = default)
100
+ => await _context.Orders.ToListAsync(ct);
101
+
102
+ public async Task AddAsync(Order entity, CancellationToken ct = default)
103
+ => await _context.Orders.AddAsync(entity, ct);
104
+
105
+ public void Update(Order entity)
106
+ => _context.Orders.Update(entity);
107
+
108
+ public void Remove(Order entity)
109
+ => _context.Orders.Remove(entity);
110
+ }
111
+ ```
112
+
113
+ ## DependencyInjection
114
+
115
+ ```csharp
116
+ public static class DependencyInjection
117
+ {
118
+ public static IServiceCollection AddInfrastructure(
119
+ this IServiceCollection services,
120
+ IConfiguration configuration)
121
+ {
122
+ services.AddDbContext<ExtensionsDbContext>(options =>
123
+ options.UseSqlServer(
124
+ configuration.GetConnectionString("DefaultConnection"),
125
+ b => b.MigrationsAssembly(typeof(ExtensionsDbContext).Assembly.FullName)));
126
+
127
+ services.AddScoped<IExtensionsDbContext>(provider =>
128
+ provider.GetRequiredService<ExtensionsDbContext>());
129
+
130
+ return services;
131
+ }
132
+ }
133
+ ```
134
+
135
+ ## EF Core Commands
136
+
137
+ ```bash
138
+ # Create migration (ExtensionsDbContext)
139
+ dotnet ef migrations add <Name> --context ExtensionsDbContext -p src/{{ProjectName}}.Infrastructure -s src/{{ProjectName}}.Api -o Persistence/Migrations
140
+
141
+ # Update database
142
+ dotnet ef database update --context ExtensionsDbContext -p src/{{ProjectName}}.Infrastructure -s src/{{ProjectName}}.Api
143
+
144
+ # Remove last migration
145
+ dotnet ef migrations remove --context ExtensionsDbContext -p src/{{ProjectName}}.Infrastructure -s src/{{ProjectName}}.Api
146
+ ```
147
+
148
+ ## Rules
149
+
150
+ 1. **ALL** EF configurations in `Configurations/` folder, organized by feature
151
+ 2. **NO** data annotations on entities - use Fluent API only
152
+ 3. **Repositories** implement interfaces from Application
153
+ 4. **DbContext** implements `IExtensionsDbContext` from Application
154
+ 5. **Migrations** stay in this project under `Persistence/Migrations/`
155
+ 6. **SQL objects via SqlObjectHelper** - TVFs/views use `SqlObjectHelper.ApplyAll(migrationBuilder)` and embedded `.sql` files
156
+ 7. **NO sequential/deterministic GUIDs in seed data** - All GUIDs must be generated via `[guid]::NewGuid()`
157
+ 8. **Schema prefix pattern** - Table names use format `{prefix}_{EntityName}` with schema `extensions`. Use `SchemaConstants.Extensions` constant.
158
+
159
+ ## When Adding New Entity
160
+
161
+ 1. Create entity in `{{ProjectName}}.Domain` with factory method
162
+ 2. Create repository interface in `{{ProjectName}}.Application/Common/Interfaces/Persistence/`
163
+ 3. Add `DbSet<Entity>` to `ExtensionsDbContext`
164
+ 4. Create configuration in `Persistence/Configurations/{Feature}/{Entity}Configuration.cs`
165
+ 5. Create repository in `Persistence/Repositories/{Entity}Repository.cs` (if needed)
166
+ 6. Register repository in `DependencyInjection.cs`
167
+ 7. Create migration: `/efcore:migration Add{Entity}`
168
+ 8. Run `/efcore:db-deploy` to apply migration