@atlashub/smartstack-cli 4.4.0 → 4.6.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.
- package/dist/index.js +26 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/project/DependencyInjection.Application.cs.template +2 -2
- package/templates/project/Program.cs.template +91 -37
- package/templates/project/appsettings.json.template +34 -7
- package/templates/skills/apex/references/person-extension-pattern.md +7 -5
- package/templates/skills/apex/references/smartstack-frontend.md +278 -103
- package/templates/skills/apex/references/smartstack-layers.md +2 -2
- package/templates/skills/apex/steps/step-03-execute.md +18 -1
- package/templates/skills/apex/steps/step-05-deep-review.md +1 -1
- package/templates/skills/ralph-loop/references/task-transform-legacy.md +2 -2
- package/templates/skills/ui-components/SKILL.md +310 -0
- package/templates/skills/ui-components/patterns/data-table.md +136 -0
package/package.json
CHANGED
|
@@ -17,8 +17,8 @@ public static class DependencyInjection
|
|
|
17
17
|
this IServiceCollection services)
|
|
18
18
|
{
|
|
19
19
|
// TODO: Register your application services here
|
|
20
|
-
//
|
|
21
|
-
// services.
|
|
20
|
+
// NOTE: MediatR is already registered by AddSmartStack() — do NOT register it again here.
|
|
21
|
+
// Only add client-specific services (e.g., custom validators, domain services).
|
|
22
22
|
|
|
23
23
|
return services;
|
|
24
24
|
}
|
|
@@ -1,47 +1,101 @@
|
|
|
1
|
+
using Serilog;
|
|
2
|
+
using Serilog.Events;
|
|
1
3
|
using Microsoft.EntityFrameworkCore;
|
|
2
4
|
using SmartStack.Api.Extensions;
|
|
3
5
|
using {{ProjectName}}.Infrastructure;
|
|
4
6
|
using {{ProjectName}}.Infrastructure.Persistence;
|
|
5
7
|
using {{ProjectName}}.Application;
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
// Bootstrap logger for startup errors
|
|
10
|
+
Log.Logger = new LoggerConfiguration()
|
|
11
|
+
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
|
12
|
+
.Enrich.FromLogContext()
|
|
13
|
+
.WriteTo.Console()
|
|
14
|
+
.CreateBootstrapLogger();
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
// 1. Add SmartStack Core services (from NuGet package)
|
|
11
|
-
// ===================================================================
|
|
12
|
-
builder.Services.AddSmartStack(builder.Configuration, options =>
|
|
16
|
+
try
|
|
13
17
|
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
18
|
+
Log.Information("Starting {{ProjectName}} API");
|
|
19
|
+
|
|
20
|
+
var builder = WebApplication.CreateBuilder(args);
|
|
21
|
+
|
|
22
|
+
// Configure Kestrel to use HTTP/1.1 on all configured endpoints
|
|
23
|
+
builder.WebHost.ConfigureKestrel((context, options) =>
|
|
24
|
+
{
|
|
25
|
+
options.ConfigureEndpointDefaults(listenOptions =>
|
|
26
|
+
{
|
|
27
|
+
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1;
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Load appsettings.Local.json if it exists (for local development overrides)
|
|
32
|
+
builder.Configuration.AddJsonFile("appsettings.Local.json", optional: true, reloadOnChange: true);
|
|
33
|
+
|
|
34
|
+
// Serilog configuration from appsettings
|
|
35
|
+
builder.Host.UseSmartStackSerilog();
|
|
36
|
+
|
|
37
|
+
// Application Insights SDK (must be added before Serilog runs)
|
|
38
|
+
var aiConnectionString = builder.Configuration["Logging:Sinks:ApplicationInsights:ConnectionString"];
|
|
39
|
+
var aiEnabled = builder.Configuration.GetValue<bool>("Logging:Sinks:ApplicationInsights:Enabled");
|
|
40
|
+
if (!string.IsNullOrEmpty(aiConnectionString) && aiEnabled)
|
|
41
|
+
{
|
|
42
|
+
builder.Services.AddApplicationInsightsTelemetry(options =>
|
|
43
|
+
{
|
|
44
|
+
options.ConnectionString = aiConnectionString;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ===================================================================
|
|
49
|
+
// 1. Add SmartStack Core services (from NuGet package)
|
|
50
|
+
// ===================================================================
|
|
51
|
+
builder.Services.AddSmartStack(builder.Configuration, options =>
|
|
52
|
+
{
|
|
53
|
+
options.EnableDevSeeding = builder.Environment.IsDevelopment();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// ===================================================================
|
|
57
|
+
// 2. Add client-specific services (Dual-DbContext pattern)
|
|
58
|
+
// ===================================================================
|
|
59
|
+
builder.Services.Add{{ProjectName}}Infrastructure(builder.Configuration);
|
|
60
|
+
builder.Services.Add{{ProjectName}}Application();
|
|
61
|
+
|
|
62
|
+
var app = builder.Build();
|
|
40
63
|
|
|
41
|
-
// ===================================================================
|
|
42
|
-
//
|
|
43
|
-
// ===================================================================
|
|
44
|
-
|
|
45
|
-
app.
|
|
64
|
+
// ===================================================================
|
|
65
|
+
// 3. Initialize SmartStack + apply migrations (in correct order!)
|
|
66
|
+
// ===================================================================
|
|
67
|
+
// This initializes SmartStack and applies Core migrations automatically
|
|
68
|
+
await app.InitializeSmartStackAsync();
|
|
46
69
|
|
|
47
|
-
|
|
70
|
+
// Apply Extensions migrations AFTER Core migrations
|
|
71
|
+
// Your client-specific tables may have FK references to Core tables
|
|
72
|
+
if (app.Environment.IsDevelopment())
|
|
73
|
+
{
|
|
74
|
+
using var scope = app.Services.CreateScope();
|
|
75
|
+
var extDb = scope.ServiceProvider.GetRequiredService<ExtensionsDbContext>();
|
|
76
|
+
await extDb.Database.MigrateAsync();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ===================================================================
|
|
80
|
+
// 4. SmartStack middleware & endpoints
|
|
81
|
+
// ===================================================================
|
|
82
|
+
// Swagger UI (development only)
|
|
83
|
+
app.UseSmartStackSwagger();
|
|
84
|
+
|
|
85
|
+
// SmartStack middleware pipeline
|
|
86
|
+
app.UseSmartStack();
|
|
87
|
+
|
|
88
|
+
// Map controllers and SignalR hubs
|
|
89
|
+
app.MapSmartStack();
|
|
90
|
+
|
|
91
|
+
Log.Information("{{ProjectName}} API started successfully");
|
|
92
|
+
app.Run();
|
|
93
|
+
}
|
|
94
|
+
catch (Exception ex)
|
|
95
|
+
{
|
|
96
|
+
Log.Fatal(ex, "Application terminated unexpectedly");
|
|
97
|
+
}
|
|
98
|
+
finally
|
|
99
|
+
{
|
|
100
|
+
Log.CloseAndFlush();
|
|
101
|
+
}
|
|
@@ -6,17 +6,15 @@
|
|
|
6
6
|
"AutoMigrate": true,
|
|
7
7
|
"FailOnMigrationError": true,
|
|
8
8
|
"EnableDevSeeding": false,
|
|
9
|
-
"UseAzureStorage": false,
|
|
10
|
-
"UseEntraId": false,
|
|
11
|
-
"EnableSwagger": true,
|
|
12
9
|
"CorsOrigins": [
|
|
13
|
-
"http://localhost:3000",
|
|
14
10
|
"http://localhost:5173",
|
|
15
11
|
"http://localhost:5174",
|
|
16
|
-
"http://localhost:5175"
|
|
12
|
+
"http://localhost:5175",
|
|
13
|
+
"http://localhost:6173"
|
|
17
14
|
]
|
|
18
15
|
},
|
|
19
16
|
"Jwt": {
|
|
17
|
+
"RsaPrivateKeyPem": "",
|
|
20
18
|
"Secret": "{{JwtSecret}}",
|
|
21
19
|
"Issuer": "{{ProjectName}}",
|
|
22
20
|
"Audience": "{{ProjectName}}",
|
|
@@ -27,14 +25,16 @@
|
|
|
27
25
|
"Microsoft": {
|
|
28
26
|
"ClientId": "",
|
|
29
27
|
"ClientSecret": "",
|
|
28
|
+
"SecretExpiresAt": "",
|
|
30
29
|
"CallbackPath": "/api/auth/microsoft/callback"
|
|
31
30
|
},
|
|
32
31
|
"Google": {
|
|
33
32
|
"ClientId": "",
|
|
34
33
|
"ClientSecret": "",
|
|
34
|
+
"SecretExpiresAt": "",
|
|
35
35
|
"CallbackPath": "/api/auth/google/callback"
|
|
36
36
|
},
|
|
37
|
-
"FrontendUrl": "http://localhost:
|
|
37
|
+
"FrontendUrl": "http://localhost:6173"
|
|
38
38
|
},
|
|
39
39
|
"Session": {
|
|
40
40
|
"IdleTimeoutMinutes": 20,
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"EnableValidation": true,
|
|
44
44
|
"RefreshTokenExpirationDays": 7,
|
|
45
45
|
"CleanupBatchSize": 100,
|
|
46
|
-
"MaxConcurrentSessions":
|
|
46
|
+
"MaxConcurrentSessions": 1,
|
|
47
47
|
"CleanupIntervalMinutes": 5
|
|
48
48
|
},
|
|
49
49
|
"Serilog": {
|
|
@@ -82,6 +82,10 @@
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
|
+
"Redis": {
|
|
86
|
+
"Enabled": false,
|
|
87
|
+
"ConnectionString": "localhost:6379"
|
|
88
|
+
},
|
|
85
89
|
"AzureStorage": {
|
|
86
90
|
"UseAzure": false,
|
|
87
91
|
"Normal": {
|
|
@@ -155,6 +159,11 @@
|
|
|
155
159
|
"UseDeltaSync": true,
|
|
156
160
|
"DefaultConflictResolution": "ManualReview",
|
|
157
161
|
"AutoCreateReferences": true,
|
|
162
|
+
"BackgroundSyncEnabled": false,
|
|
163
|
+
"BackgroundSyncIntervalMinutes": 60,
|
|
164
|
+
"MaxGraphQueryPageSize": 999
|
|
165
|
+
},
|
|
166
|
+
"Glpi": {
|
|
158
167
|
"BackgroundSyncEnabled": false,
|
|
159
168
|
"BackgroundSyncIntervalMinutes": 60
|
|
160
169
|
},
|
|
@@ -166,5 +175,23 @@
|
|
|
166
175
|
"SystemTenantName": "Default Workspace",
|
|
167
176
|
"AutoAssignUsersToSystemTenant": true
|
|
168
177
|
},
|
|
178
|
+
"LicenseServer": {
|
|
179
|
+
"BaseUrl": "https://license.atlashub.ch/",
|
|
180
|
+
"ApiKey": "",
|
|
181
|
+
"Enabled": true,
|
|
182
|
+
"HeartbeatIntervalHours": 168,
|
|
183
|
+
"StartupDelaySeconds": 30,
|
|
184
|
+
"TimeoutSeconds": 30,
|
|
185
|
+
"RetryCount": 3,
|
|
186
|
+
"RetryDelaySeconds": 5
|
|
187
|
+
},
|
|
188
|
+
"Security": {
|
|
189
|
+
"LockoutWindowMinutes": 15,
|
|
190
|
+
"MaxFailedAttempts": 5
|
|
191
|
+
},
|
|
192
|
+
"Localization": {
|
|
193
|
+
"DefaultLanguage": "fr",
|
|
194
|
+
"FallbackLanguage": "fr"
|
|
195
|
+
},
|
|
169
196
|
"AllowedHosts": "*"
|
|
170
197
|
}
|
|
@@ -542,15 +542,17 @@ public record CustomerResponseDto(
|
|
|
542
542
|
|
|
543
543
|
```tsx
|
|
544
544
|
// Composite columns from response DTO (already resolved by backend)
|
|
545
|
-
<
|
|
545
|
+
<DataTable
|
|
546
546
|
columns={[
|
|
547
|
-
{ key: 'code', label: t('module:columns.code', 'Code') },
|
|
548
|
-
{ key: 'displayFirstName', label: t('module:columns.firstName', 'First Name') },
|
|
549
|
-
{ key: 'displayLastName', label: t('module:columns.lastName', 'Last Name') },
|
|
550
|
-
{ key: 'displayEmail', label: t('module:columns.email', 'Email') },
|
|
547
|
+
{ key: 'code', label: t('module:columns.code', 'Code'), sortable: true },
|
|
548
|
+
{ key: 'displayFirstName', label: t('module:columns.firstName', 'First Name'), sortable: true },
|
|
549
|
+
{ key: 'displayLastName', label: t('module:columns.lastName', 'Last Name'), sortable: true },
|
|
550
|
+
{ key: 'displayEmail', label: t('module:columns.email', 'Email'), sortable: true },
|
|
551
551
|
{ key: 'status', label: t('module:columns.status', 'Status') },
|
|
552
552
|
]}
|
|
553
553
|
data={items}
|
|
554
|
+
searchable
|
|
555
|
+
pagination={{ pageSize: 10 }}
|
|
554
556
|
/>
|
|
555
557
|
```
|
|
556
558
|
|