@chill-sharp/ui-core 1.1.12
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/.agents/skills/chillsharp-current-user-preferences/SKILL.md +70 -0
- package/.agents/skills/chillsharp-ui-template/SKILL.md +18 -0
- package/README.md +103 -0
- package/chill-sharp-ui-core.d.ts.map +1 -0
- package/doc/AIAssistedDevelopment/README.md +185 -0
- package/doc/AttachmentModel/README.md +173 -0
- package/doc/AuthenticationModel/README.md +213 -0
- package/doc/AuthenticationModel/how-to-integreate-auth-minimal-api.md +293 -0
- package/doc/ChillSharpClient.md +464 -0
- package/doc/ClientGeneration/README.md +172 -0
- package/doc/ComplianceGuide/README.md +178 -0
- package/doc/Configuration/README.md +94 -0
- package/doc/CurrentUserPreferences.md +114 -0
- package/doc/DateTimePolicy/README.md +154 -0
- package/doc/DateTimeSerialization.md +423 -0
- package/doc/Endpoints.md +260 -0
- package/doc/HowTo/01-simple-blog-sqlite.md +153 -0
- package/doc/HowTo/02-blog-schema-labels.md +140 -0
- package/doc/HowTo/03-authentication.md +218 -0
- package/doc/HowTo/04-blog-posts-one-to-many.md +194 -0
- package/doc/HowTo/05-docker-env-variables.md +274 -0
- package/doc/HowTo/06-chunk-transactions-autocomplete.md +196 -0
- package/doc/Mcp/ChatGPT.md +291 -0
- package/doc/Mcp/README.md +799 -0
- package/doc/MenuGuide/README.md +49 -0
- package/doc/ModelPreparation.md +255 -0
- package/doc/PermissionModel/README.md +277 -0
- package/doc/README.md +228 -0
- package/doc/ReferenceExistence.md +130 -0
- package/doc/RegisterContext.md +217 -0
- package/doc/UiCore/CRUD.md +170 -0
- package/doc/UiCore/README.md +13 -0
- package/doc/ValidationModel/README.md +117 -0
- package/doc/it/AIAssistedDevelopment/README.md +185 -0
- package/doc/it/AttachmentModel/README.md +173 -0
- package/doc/it/AuthenticationModel/README.md +171 -0
- package/doc/it/AuthenticationModel/how-to-integreate-auth-minimal-api.md +292 -0
- package/doc/it/ChillSharpClient.md +464 -0
- package/doc/it/ClientGeneration/README.md +152 -0
- package/doc/it/ComplianceGuide/README.md +178 -0
- package/doc/it/Configuration/README.md +94 -0
- package/doc/it/CurrentUserPreferences.md +114 -0
- package/doc/it/DateTimePolicy/README.md +154 -0
- package/doc/it/DateTimeSerialization.md +423 -0
- package/doc/it/Endpoints.md +260 -0
- package/doc/it/HowTo/01-simple-blog-sqlite.md +152 -0
- package/doc/it/HowTo/02-blog-schema-labels.md +139 -0
- package/doc/it/HowTo/03-authentication.md +221 -0
- package/doc/it/HowTo/04-blog-posts-one-to-many.md +193 -0
- package/doc/it/HowTo/05-docker-env-variables.md +268 -0
- package/doc/it/HowTo/06-chunk-transactions-autocomplete.md +196 -0
- package/doc/it/Mcp/ChatGPT.md +291 -0
- package/doc/it/Mcp/README.md +799 -0
- package/doc/it/MenuGuide/README.md +49 -0
- package/doc/it/ModelPreparation.md +254 -0
- package/doc/it/PermissionModel/README.md +190 -0
- package/doc/it/README.md +172 -0
- package/doc/it/ReferenceExistence.md +130 -0
- package/doc/it/RegisterContext.md +218 -0
- package/doc/it/UiCore/CRUD.md +170 -0
- package/doc/it/UiCore/README.md +13 -0
- package/doc/it/ValidationModel/README.md +117 -0
- package/fesm2022/chill-sharp-ui-core.mjs +16725 -0
- package/fesm2022/chill-sharp-ui-core.mjs.map +1 -0
- package/index.d.ts +6 -0
- package/lib/chill-sharp-ui-root.component.d.ts +6 -0
- package/lib/chill-sharp-ui-root.component.d.ts.map +1 -0
- package/lib/chill-sharp-ui.routes.d.ts +3 -0
- package/lib/chill-sharp-ui.routes.d.ts.map +1 -0
- package/lib/chill.config.d.ts +5 -0
- package/lib/chill.config.d.ts.map +1 -0
- package/lib/layouts/auth-shell.component.d.ts +8 -0
- package/lib/layouts/auth-shell.component.d.ts.map +1 -0
- package/lib/layouts/workspace-page.component.d.ts +49 -0
- package/lib/layouts/workspace-page.component.d.ts.map +1 -0
- package/lib/lib/chill-form.component.d.ts +151 -0
- package/lib/lib/chill-form.component.d.ts.map +1 -0
- package/lib/lib/chill-i18n-button-label.component.d.ts +27 -0
- package/lib/lib/chill-i18n-button-label.component.d.ts.map +1 -0
- package/lib/lib/chill-i18n-label.component.d.ts +30 -0
- package/lib/lib/chill-i18n-label.component.d.ts.map +1 -0
- package/lib/lib/chill-json-input.component.d.ts +31 -0
- package/lib/lib/chill-json-input.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-boolean-control.component.d.ts +12 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-boolean-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-editor-control.component.d.ts +17 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-editor-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-lookup-control.component.d.ts +45 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-lookup-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-scalar-control.component.d.ts +19 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-scalar-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-select-control.component.d.ts +12 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-select-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-textarea-control.component.d.ts +13 -0
- package/lib/lib/chill-polymorphic-input-controls/chill-polymorphic-textarea-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-input.component.d.ts +452 -0
- package/lib/lib/chill-polymorphic-input.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-boolean-control.component.d.ts +7 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-boolean-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-lookup-control.component.d.ts +7 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-lookup-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-number-control.component.d.ts +7 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-number-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-temporal-control.component.d.ts +8 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-temporal-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-value-control.component.d.ts +7 -0
- package/lib/lib/chill-polymorphic-output-controls/chill-polymorphic-output-value-control.component.d.ts.map +1 -0
- package/lib/lib/chill-polymorphic-output.component.d.ts +75 -0
- package/lib/lib/chill-polymorphic-output.component.d.ts.map +1 -0
- package/lib/lib/chill-table.component.d.ts +434 -0
- package/lib/lib/chill-table.component.d.ts.map +1 -0
- package/lib/lib/chill-text-editor-dialog.component.d.ts +14 -0
- package/lib/lib/chill-text-editor-dialog.component.d.ts.map +1 -0
- package/lib/lib/crud-configuration.utils.d.ts +4 -0
- package/lib/lib/crud-configuration.utils.d.ts.map +1 -0
- package/lib/lib/culture-name-options.d.ts +3 -0
- package/lib/lib/culture-name-options.d.ts.map +1 -0
- package/lib/lib/date-format-options.d.ts +3 -0
- package/lib/lib/date-format-options.d.ts.map +1 -0
- package/lib/lib/iana-time-zone-options.d.ts +3 -0
- package/lib/lib/iana-time-zone-options.d.ts.map +1 -0
- package/lib/lib/notice-transition.directive.d.ts +17 -0
- package/lib/lib/notice-transition.directive.d.ts.map +1 -0
- package/lib/lib/schema-property-dialog.component.d.ts +74 -0
- package/lib/lib/schema-property-dialog.component.d.ts.map +1 -0
- package/lib/models/chill-auth.models.d.ts +176 -0
- package/lib/models/chill-auth.models.d.ts.map +1 -0
- package/lib/models/chill-menu.models.d.ts +12 -0
- package/lib/models/chill-menu.models.d.ts.map +1 -0
- package/lib/models/chill-schema.models.d.ts +141 -0
- package/lib/models/chill-schema.models.d.ts.map +1 -0
- package/lib/models/workspace-dialog.models.d.ts +16 -0
- package/lib/models/workspace-dialog.models.d.ts.map +1 -0
- package/lib/models/workspace-task.models.d.ts +36 -0
- package/lib/models/workspace-task.models.d.ts.map +1 -0
- package/lib/pages/confirm-reset-page.component.d.ts +21 -0
- package/lib/pages/confirm-reset-page.component.d.ts.map +1 -0
- package/lib/pages/crud/attachment-upload-dialog.component.d.ts +24 -0
- package/lib/pages/crud/attachment-upload-dialog.component.d.ts.map +1 -0
- package/lib/pages/crud/crud-page.component.d.ts +244 -0
- package/lib/pages/crud/crud-page.component.d.ts.map +1 -0
- package/lib/pages/login-page.component.d.ts +21 -0
- package/lib/pages/login-page.component.d.ts.map +1 -0
- package/lib/pages/permissions/auth-role-dialog.component.d.ts +29 -0
- package/lib/pages/permissions/auth-role-dialog.component.d.ts.map +1 -0
- package/lib/pages/permissions/auth-search-select.component.d.ts +28 -0
- package/lib/pages/permissions/auth-search-select.component.d.ts.map +1 -0
- package/lib/pages/permissions/auth-user-dialog.component.d.ts +35 -0
- package/lib/pages/permissions/auth-user-dialog.component.d.ts.map +1 -0
- package/lib/pages/permissions/permission-editor.component.d.ts +55 -0
- package/lib/pages/permissions/permission-editor.component.d.ts.map +1 -0
- package/lib/pages/permissions/permissions-page.component.d.ts +38 -0
- package/lib/pages/permissions/permissions-page.component.d.ts.map +1 -0
- package/lib/pages/permissions/role-permission.component.d.ts +43 -0
- package/lib/pages/permissions/role-permission.component.d.ts.map +1 -0
- package/lib/pages/permissions/user-permission.component.d.ts +43 -0
- package/lib/pages/permissions/user-permission.component.d.ts.map +1 -0
- package/lib/pages/register-page.component.d.ts +24 -0
- package/lib/pages/register-page.component.d.ts.map +1 -0
- package/lib/pages/reset-password-page.component.d.ts +18 -0
- package/lib/pages/reset-password-page.component.d.ts.map +1 -0
- package/lib/provide-chill-sharp-ui-core.d.ts +8 -0
- package/lib/provide-chill-sharp-ui-core.d.ts.map +1 -0
- package/lib/services/chill.service.d.ts +249 -0
- package/lib/services/chill.service.d.ts.map +1 -0
- package/lib/services/workspace-dialog.service.d.ts +22 -0
- package/lib/services/workspace-dialog.service.d.ts.map +1 -0
- package/lib/services/workspace-layout.service.d.ts +13 -0
- package/lib/services/workspace-layout.service.d.ts.map +1 -0
- package/lib/services/workspace-task-registry.service.d.ts +35 -0
- package/lib/services/workspace-task-registry.service.d.ts.map +1 -0
- package/lib/services/workspace-toolbar.service.d.ts +23 -0
- package/lib/services/workspace-toolbar.service.d.ts.map +1 -0
- package/lib/services/workspace.service.d.ts +114 -0
- package/lib/services/workspace.service.d.ts.map +1 -0
- package/lib/storage-keys.d.ts +5 -0
- package/lib/storage-keys.d.ts.map +1 -0
- package/lib/tasks/crud-task/crud-task.component.d.ts +33 -0
- package/lib/tasks/crud-task/crud-task.component.d.ts.map +1 -0
- package/lib/tasks/goto-url-task/goto-url-task.component.d.ts +31 -0
- package/lib/tasks/goto-url-task/goto-url-task.component.d.ts.map +1 -0
- package/lib/workspace/confirm-message-dialog.component.d.ts +16 -0
- package/lib/workspace/confirm-message-dialog.component.d.ts.map +1 -0
- package/lib/workspace/entity-options-dialog.component.d.ts +29 -0
- package/lib/workspace/entity-options-dialog.component.d.ts.map +1 -0
- package/lib/workspace/external-task-api.d.ts +2 -0
- package/lib/workspace/external-task-api.d.ts.map +1 -0
- package/lib/workspace/user-profile-dialog.component.d.ts +30 -0
- package/lib/workspace/user-profile-dialog.component.d.ts.map +1 -0
- package/lib/workspace/workspace-dialog-host.component.d.ts +26 -0
- package/lib/workspace/workspace-dialog-host.component.d.ts.map +1 -0
- package/lib/workspace/workspace-menu-item-dialog.component.d.ts +61 -0
- package/lib/workspace/workspace-menu-item-dialog.component.d.ts.map +1 -0
- package/lib/workspace/workspace-menu.component.d.ts +104 -0
- package/lib/workspace/workspace-menu.component.d.ts.map +1 -0
- package/lib/workspace/workspace-taskbar.component.d.ts +14 -0
- package/lib/workspace/workspace-taskbar.component.d.ts.map +1 -0
- package/package.json +54 -0
- package/public-api.d.ts +56 -0
- package/public-api.d.ts.map +1 -0
- package/service-worker/chill-sharp-service-worker.js +166 -0
- package/styles/core-theme.scss +1268 -0
- package/template-customization/upgrade.ps1.template +342 -0
- package/template-customization/upgrade.sh.template +271 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# HOW-TO: Creare Un'Immagine Docker E Configurarla Con Variabili D'Ambiente
|
|
2
|
+
|
|
3
|
+
Versione originale in inglese: [English](../../HowTo/05-docker-env-variables.md)
|
|
4
|
+
|
|
5
|
+
Questo esempio mostra come impacchettare una API ChillSharp in un'immagine Docker e configurarla a runtime tramite variabili d'ambiente invece di valori hardcoded.
|
|
6
|
+
|
|
7
|
+
## Obiettivo
|
|
8
|
+
|
|
9
|
+
Costruire una sola immagine container riusabile in ambienti diversi cambiando solo le variabili d'ambiente.
|
|
10
|
+
|
|
11
|
+
## 1. Leggere La Configurazione Da `IConfiguration`
|
|
12
|
+
|
|
13
|
+
ASP.NET Core mappa gia le variabili d'ambiente in `builder.Configuration`. Usa quello invece di hardcodare il path SQLite, i toggle dei moduli, le durate dei token, le impostazioni SMTP o le credenziali root.
|
|
14
|
+
|
|
15
|
+
Per il mapper DTO di date e orari, ChillSharp legge anche `CHILLSHARP_SYSTEM_TIMEZONE` direttamente dall'ambiente del processo. Deve essere un id IANA, per esempio `Europe/Rome`.
|
|
16
|
+
|
|
17
|
+
Questa impostazione viene usata per la gestione `DateTime` di ChillSharp e per la normalizzazione UTC-locale di alcuni input `DateTimeOffset`. `DateOnly` e `TimeOnly` mantengono l'output stringa standard di .NET.
|
|
18
|
+
|
|
19
|
+
`ChillSharp.Attachment` legge direttamente anche `CHILLSHARP_ATTACHMENT_ARCHIVE_ROOT`. Nei container conviene puntarlo a un volume montato, per esempio `/attachments`.
|
|
20
|
+
|
|
21
|
+
```csharp
|
|
22
|
+
using ChillSharp.Api;
|
|
23
|
+
using ChillSharp.Auth;
|
|
24
|
+
using ChillSharp.Auth.Api;
|
|
25
|
+
using ChillSharp.Attachment.Services;
|
|
26
|
+
using Microsoft.AspNetCore.Identity;
|
|
27
|
+
using Microsoft.EntityFrameworkCore;
|
|
28
|
+
|
|
29
|
+
var builder = WebApplication.CreateBuilder(args);
|
|
30
|
+
|
|
31
|
+
var databasePath = builder.Configuration["CHILLSHARP_DB_PATH"] ?? "/data/blogging.db";
|
|
32
|
+
var attachmentArchiveRoot = builder.Configuration["CHILLSHARP_ATTACHMENT_ARCHIVE_ROOT"] ?? "/attachments";
|
|
33
|
+
|
|
34
|
+
builder.Services.AddDbContext<BloggingContext>(options =>
|
|
35
|
+
options.UseSqlite($"Data Source={databasePath}"));
|
|
36
|
+
|
|
37
|
+
builder.Services.AddIdentityCore<IdentityUser>()
|
|
38
|
+
.AddEntityFrameworkStores<BloggingContext>()
|
|
39
|
+
.AddSignInManager()
|
|
40
|
+
.AddDefaultTokenProviders();
|
|
41
|
+
|
|
42
|
+
builder.Services.AddAuthentication(ChillAuthIdentityDefaults.AuthenticationScheme)
|
|
43
|
+
.AddChillAuthBearer();
|
|
44
|
+
|
|
45
|
+
builder.Services.AddAuthorization();
|
|
46
|
+
|
|
47
|
+
builder.Services.AddChillApi<BloggingContext>(options =>
|
|
48
|
+
{
|
|
49
|
+
options.ProtectedApi = GetBool("CHILLSHARP_API_PROTECTED", true);
|
|
50
|
+
options.EnableSchemaApi = GetBool("CHILLSHARP_ENABLE_SCHEMA", true);
|
|
51
|
+
options.EnableAuthApi = GetBool("CHILLSHARP_ENABLE_AUTH", true);
|
|
52
|
+
options.EnableI18nApi = GetBool("CHILLSHARP_ENABLE_I18N", true);
|
|
53
|
+
options.EnableMcpApi = GetBool("CHILLSHARP_ENABLE_MCP", true);
|
|
54
|
+
options.EnableAttachmentApi = GetBool("CHILLSHARP_ENABLE_ATTACHMENT", false);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
builder.Services.AddChillAuthIdentityApi<BloggingContext, IdentityUser>(options =>
|
|
58
|
+
{
|
|
59
|
+
options.AccessTokenLifetime = TimeSpan.FromMinutes(GetInt("CHILLSHARP_AUTH_ACCESS_TOKEN_MINUTES", 20));
|
|
60
|
+
options.RefreshTokenLifetime = TimeSpan.FromDays(GetInt("CHILLSHARP_AUTH_REFRESH_TOKEN_DAYS", 14));
|
|
61
|
+
options.ReturnPasswordResetTokensInResponse = GetBool("CHILLSHARP_AUTH_RETURN_PASSWORD_RESET_TOKENS", false);
|
|
62
|
+
options.SendPasswordResetEmails = GetBool("CHILLSHARP_AUTH_SEND_PASSWORD_RESET_EMAILS", true);
|
|
63
|
+
options.InitializeRootUserOnStartup = GetBool("CHILLSHARP_AUTH_INITIALIZE_ROOT_USER", true);
|
|
64
|
+
options.CreateChillAuthUserForRoot = GetBool("CHILLSHARP_AUTH_CREATE_ROOT_AUTH_USER", true);
|
|
65
|
+
options.PasswordResetEmailSubject = builder.Configuration["CHILLSHARP_AUTH_PASSWORD_RESET_SUBJECT"] ?? "Reset your password";
|
|
66
|
+
options.PasswordResetUrlBase = builder.Configuration["CHILLSHARP_AUTH_PASSWORD_RESET_URL"];
|
|
67
|
+
options.SmtpHost = builder.Configuration["CHILLSHARP_SMTP_HOST"];
|
|
68
|
+
options.SmtpPort = GetInt("CHILLSHARP_SMTP_PORT", 587);
|
|
69
|
+
options.SmtpEnableSsl = GetBool("CHILLSHARP_SMTP_ENABLE_SSL", true);
|
|
70
|
+
options.SmtpUserName = builder.Configuration["CHILLSHARP_SMTP_USERNAME"];
|
|
71
|
+
options.SmtpPassword = builder.Configuration["CHILLSHARP_SMTP_PASSWORD"];
|
|
72
|
+
options.PasswordResetFromEmail = builder.Configuration["CHILLSHARP_SMTP_FROM_EMAIL"];
|
|
73
|
+
options.PasswordResetFromDisplayName = builder.Configuration["CHILLSHARP_SMTP_FROM_DISPLAY_NAME"];
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
builder.Services.Configure<ChillAttachmentOptions>(options =>
|
|
77
|
+
{
|
|
78
|
+
options.ArchiveRoot = attachmentArchiveRoot;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
var app = builder.Build();
|
|
82
|
+
|
|
83
|
+
app.UseAuthentication();
|
|
84
|
+
app.UseAuthorization();
|
|
85
|
+
|
|
86
|
+
Directory.CreateDirectory(Path.GetDirectoryName(databasePath)!);
|
|
87
|
+
Directory.CreateDirectory(attachmentArchiveRoot);
|
|
88
|
+
|
|
89
|
+
using (var scope = app.Services.CreateScope())
|
|
90
|
+
{
|
|
91
|
+
var db = scope.ServiceProvider.GetRequiredService<BloggingContext>();
|
|
92
|
+
db.Database.EnsureCreated();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
app.MapChillApi();
|
|
96
|
+
app.Run();
|
|
97
|
+
|
|
98
|
+
bool GetBool(string name, bool defaultValue)
|
|
99
|
+
{
|
|
100
|
+
return bool.TryParse(builder.Configuration[name], out var value) ? value : defaultValue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
int GetInt(string name, int defaultValue)
|
|
104
|
+
{
|
|
105
|
+
return int.TryParse(builder.Configuration[name], out var value) ? value : defaultValue;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
I moduli MCP e Attachment vengono registrati da `AddChillApi<TContext>()` solo quando il `DbContext` implementa le interfacce richieste:
|
|
110
|
+
|
|
111
|
+
- `ChillSharp.Schema` e `ChillSharp.Mcp`: `IChillSchemaDbContext`
|
|
112
|
+
- `ChillSharp.Auth`: `IChillAuthDbContext`
|
|
113
|
+
- `ChillSharp.I18n`: `IChillI18nDbContext`
|
|
114
|
+
- `ChillSharp.Attachment`: `IChillAttachmentDbContext`
|
|
115
|
+
|
|
116
|
+
Mantieni `CHILLSHARP_ENABLE_ATTACHMENT=false` finche il context non espone il modello attachment e lo storage di archivio. Poi impostalo a `true` e lascia `/attachments` montato.
|
|
117
|
+
|
|
118
|
+
## 2. Usare Variabili D'Ambiente Per Moduli E Runtime
|
|
119
|
+
|
|
120
|
+
Questi nomi sono una buona base container per i moduli integrati attuali:
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
CHILLSHARP_DB_PATH
|
|
124
|
+
CHILLSHARP_SYSTEM_TIMEZONE
|
|
125
|
+
CHILLSHARP_API_PROTECTED
|
|
126
|
+
CHILLSHARP_ENABLE_SCHEMA
|
|
127
|
+
CHILLSHARP_ENABLE_AUTH
|
|
128
|
+
CHILLSHARP_ENABLE_I18N
|
|
129
|
+
CHILLSHARP_ENABLE_MCP
|
|
130
|
+
CHILLSHARP_ENABLE_ATTACHMENT
|
|
131
|
+
CHILLSHARP_ATTACHMENT_ARCHIVE_ROOT
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Le variabili `CHILLSHARP_ENABLE_*` sono variabili dell'host di esempio: l'app le legge da `IConfiguration` e le mappa su `ChillApiOptions`. `CHILLSHARP_SYSTEM_TIMEZONE`, `CHILLSHARP_ATTACHMENT_ARCHIVE_ROOT` e le variabili dell'utente root sotto sono lette direttamente anche dai servizi ChillSharp.
|
|
135
|
+
|
|
136
|
+
Quando abilitati, gli endpoint predefiniti includono:
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
http://localhost:8080/api/chill
|
|
140
|
+
http://localhost:8080/api/chill-auth
|
|
141
|
+
http://localhost:8080/api/chill-attachment
|
|
142
|
+
http://localhost:8080/api/chill-mcp
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## 3. Usare Variabili D'Ambiente Per L'Utente Root
|
|
146
|
+
|
|
147
|
+
`AddChillAuthIdentityApi(...)` conosce gia queste variabili:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
CHILLSHARP_AUTH_ROOT_USERNAME
|
|
151
|
+
CHILLSHARP_AUTH_ROOT_PASSWORD
|
|
152
|
+
CHILLSHARP_AUTH_ROOT_EMAIL
|
|
153
|
+
CHILLSHARP_AUTH_ROOT_DISPLAY_NAME
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Quando `CreateChillAuthUserForRoot = true`, viene creato anche l'`AuthUser` root con `CanManagePermissions = true`.
|
|
157
|
+
|
|
158
|
+
## 4. Creare Il Dockerfile
|
|
159
|
+
|
|
160
|
+
Questa immagine compila l'applicazione una volta ed esegue il risultato con l'immagine runtime ASP.NET Core.
|
|
161
|
+
|
|
162
|
+
```dockerfile
|
|
163
|
+
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
|
164
|
+
WORKDIR /src
|
|
165
|
+
|
|
166
|
+
COPY MyBlogApp.csproj ./
|
|
167
|
+
RUN dotnet restore
|
|
168
|
+
|
|
169
|
+
COPY . ./
|
|
170
|
+
RUN dotnet publish -c Release -o /app/out
|
|
171
|
+
|
|
172
|
+
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
|
173
|
+
WORKDIR /app
|
|
174
|
+
|
|
175
|
+
COPY --from=build /app/out ./
|
|
176
|
+
|
|
177
|
+
ENV ASPNETCORE_URLS=http://+:8080
|
|
178
|
+
ENV CHILLSHARP_DB_PATH=/data/blogging.db
|
|
179
|
+
ENV CHILLSHARP_SYSTEM_TIMEZONE=Europe/Rome
|
|
180
|
+
ENV CHILLSHARP_ATTACHMENT_ARCHIVE_ROOT=/attachments
|
|
181
|
+
|
|
182
|
+
VOLUME ["/data"]
|
|
183
|
+
VOLUME ["/attachments"]
|
|
184
|
+
EXPOSE 8080
|
|
185
|
+
|
|
186
|
+
ENTRYPOINT ["dotnet", "MyBlogApp.dll"]
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## 5. Build Dell'Immagine
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
docker build -t myblogapp:latest .
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## 6. Avviare Il Container Con Variabili D'Ambiente
|
|
196
|
+
|
|
197
|
+
Questo esempio avvia l'API, persiste i dati SQLite e i file allegati in volumi Docker locali e crea l'amministratore root all'avvio.
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
docker run --rm -p 8080:8080 \
|
|
201
|
+
-v myblogapp-data:/data \
|
|
202
|
+
-v myblogapp-attachments:/attachments \
|
|
203
|
+
-e CHILLSHARP_DB_PATH=/data/blogging.db \
|
|
204
|
+
-e CHILLSHARP_SYSTEM_TIMEZONE=Europe/Rome \
|
|
205
|
+
-e CHILLSHARP_API_PROTECTED=true \
|
|
206
|
+
-e CHILLSHARP_ENABLE_SCHEMA=true \
|
|
207
|
+
-e CHILLSHARP_ENABLE_AUTH=true \
|
|
208
|
+
-e CHILLSHARP_ENABLE_I18N=true \
|
|
209
|
+
-e CHILLSHARP_ENABLE_MCP=true \
|
|
210
|
+
-e CHILLSHARP_ENABLE_ATTACHMENT=false \
|
|
211
|
+
-e CHILLSHARP_ATTACHMENT_ARCHIVE_ROOT=/attachments \
|
|
212
|
+
-e CHILLSHARP_AUTH_ROOT_USERNAME=root \
|
|
213
|
+
-e CHILLSHARP_AUTH_ROOT_PASSWORD=Pass123$ \
|
|
214
|
+
-e CHILLSHARP_AUTH_ROOT_EMAIL=root@example.com \
|
|
215
|
+
-e CHILLSHARP_AUTH_ROOT_DISPLAY_NAME="Root Administrator" \
|
|
216
|
+
myblogapp:latest
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Con i valori sopra, l'applicazione sara disponibile a:
|
|
220
|
+
|
|
221
|
+
```text
|
|
222
|
+
http://localhost:8080/api/chill
|
|
223
|
+
http://localhost:8080/api/chill-auth
|
|
224
|
+
http://localhost:8080/api/chill-mcp
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Imposta `CHILLSHARP_ENABLE_ATTACHMENT=true` quando il context host implementa `IChillAttachmentDbContext`; a quel punto l'API attachment e disponibile a `http://localhost:8080/api/chill-attachment`.
|
|
228
|
+
|
|
229
|
+
## 7. Esempio Facoltativo `docker compose`
|
|
230
|
+
|
|
231
|
+
```yaml
|
|
232
|
+
services:
|
|
233
|
+
myblogapp:
|
|
234
|
+
image: myblogapp:latest
|
|
235
|
+
build: .
|
|
236
|
+
ports:
|
|
237
|
+
- "8080:8080"
|
|
238
|
+
environment:
|
|
239
|
+
ASPNETCORE_URLS: http://+:8080
|
|
240
|
+
CHILLSHARP_DB_PATH: /data/blogging.db
|
|
241
|
+
CHILLSHARP_SYSTEM_TIMEZONE: Europe/Rome
|
|
242
|
+
CHILLSHARP_API_PROTECTED: "true"
|
|
243
|
+
CHILLSHARP_ENABLE_SCHEMA: "true"
|
|
244
|
+
CHILLSHARP_ENABLE_AUTH: "true"
|
|
245
|
+
CHILLSHARP_ENABLE_I18N: "true"
|
|
246
|
+
CHILLSHARP_ENABLE_MCP: "true"
|
|
247
|
+
CHILLSHARP_ENABLE_ATTACHMENT: "false"
|
|
248
|
+
CHILLSHARP_ATTACHMENT_ARCHIVE_ROOT: /attachments
|
|
249
|
+
CHILLSHARP_AUTH_ROOT_USERNAME: root
|
|
250
|
+
CHILLSHARP_AUTH_ROOT_PASSWORD: Pass123$
|
|
251
|
+
CHILLSHARP_AUTH_ROOT_EMAIL: root@example.com
|
|
252
|
+
CHILLSHARP_AUTH_ROOT_DISPLAY_NAME: Root Administrator
|
|
253
|
+
volumes:
|
|
254
|
+
- myblogapp-data:/data
|
|
255
|
+
- myblogapp-attachments:/attachments
|
|
256
|
+
|
|
257
|
+
volumes:
|
|
258
|
+
myblogapp-data:
|
|
259
|
+
myblogapp-attachments:
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Note
|
|
263
|
+
|
|
264
|
+
- Mantieni l'immagine generica e sposta i valori specifici dell'ambiente nella configurazione runtime.
|
|
265
|
+
- Persisti SQLite sotto un volume montato, altrimenti il database viene perso quando il container viene rimosso.
|
|
266
|
+
- In produzione, inietta i secret tramite piattaforma container o secret manager invece di hardcodarli nella history di `docker run` o nei file `compose`.
|
|
267
|
+
|
|
268
|
+
Esempio successivo: [Gestire una relazione Blog-Posts uno-a-molti e leggerla con una sola chiamata client](04-blog-posts-one-to-many.md)
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# HOW-TO: Usare Chunk, Transazioni e Autocomplete
|
|
2
|
+
|
|
3
|
+
Versione originale in inglese: [English](../../HowTo/06-chunk-transactions-autocomplete.md)
|
|
4
|
+
|
|
5
|
+
Questo esempio mostra come inviare piu operazioni ChillSharp in una sola chiamata con `chunk`, come racchiudere le operazioni di scrittura in una singola transazione database e come usare `autocomplete` per DTO di entita e query.
|
|
6
|
+
|
|
7
|
+
## Obiettivo
|
|
8
|
+
|
|
9
|
+
Usare in modo efficiente la API core di ChillSharp quando il client deve:
|
|
10
|
+
|
|
11
|
+
- eseguire piu operazioni in una singola richiesta HTTP
|
|
12
|
+
- confermare un gruppo di scritture in modo atomico
|
|
13
|
+
- chiedere al server di completare o normalizzare i valori di un DTO prima del salvataggio
|
|
14
|
+
|
|
15
|
+
## 1. Preparare Il Client
|
|
16
|
+
|
|
17
|
+
Tutti gli esempi sotto usano il client .NET e assumono che la API core sia mappata su `/api/chill`.
|
|
18
|
+
|
|
19
|
+
```csharp
|
|
20
|
+
using ChillSharp.Client;
|
|
21
|
+
using ChillSharp.Client.Dto;
|
|
22
|
+
|
|
23
|
+
var client = new ChillSharpClient("http://localhost:5000/api/chill");
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 2. Inviare Piu Operazioni Con `chunk`
|
|
27
|
+
|
|
28
|
+
`chunk` invia una lista di `ChillOperation` a `/api/chill/chunk`.
|
|
29
|
+
Ogni operazione puo contenere una `Query` o una `Entity`, a seconda del `Verb`.
|
|
30
|
+
|
|
31
|
+
Imposta `Index` in modo esplicito quando l'ordine di esecuzione e importante.
|
|
32
|
+
|
|
33
|
+
```csharp
|
|
34
|
+
using ChillSharp.Client.Dto;
|
|
35
|
+
|
|
36
|
+
var firstPost = new ChillDtoEntity
|
|
37
|
+
{
|
|
38
|
+
ChillType = "Model.Post",
|
|
39
|
+
Guid = Guid.Parse("11111111-1111-1111-1111-111111111111")
|
|
40
|
+
};
|
|
41
|
+
firstPost.Properties["Title"] = "First";
|
|
42
|
+
firstPost.Properties["Author"] = "Ada";
|
|
43
|
+
|
|
44
|
+
var secondPost = new ChillDtoEntity
|
|
45
|
+
{
|
|
46
|
+
ChillType = "Model.Post",
|
|
47
|
+
Guid = Guid.Parse("22222222-2222-2222-2222-222222222222")
|
|
48
|
+
};
|
|
49
|
+
secondPost.Properties["Title"] = "Second";
|
|
50
|
+
secondPost.Properties["Author"] = "Linus";
|
|
51
|
+
|
|
52
|
+
var updateFirstPost = new ChillDtoEntity
|
|
53
|
+
{
|
|
54
|
+
ChillType = "Model.Post",
|
|
55
|
+
Guid = firstPost.Guid
|
|
56
|
+
};
|
|
57
|
+
updateFirstPost.Properties["Title"] = "First updated";
|
|
58
|
+
|
|
59
|
+
var operations = client.Chunk(new List<ChillOperation>
|
|
60
|
+
{
|
|
61
|
+
new() { Index = 0, Verb = ChillOperationVerb.CREATE, Entity = firstPost },
|
|
62
|
+
new() { Index = 1, Verb = ChillOperationVerb.CREATE, Entity = secondPost },
|
|
63
|
+
new() { Index = 2, Verb = ChillOperationVerb.UPDATE, Entity = updateFirstPost }
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Cosa ti da questo:
|
|
68
|
+
|
|
69
|
+
- una richiesta HTTP invece di tre
|
|
70
|
+
- esecuzione ordinata tramite `Index`
|
|
71
|
+
- una risposta combinata contenente le operazioni elaborate
|
|
72
|
+
|
|
73
|
+
## 3. Racchiudere Un Chunk In Una Transazione
|
|
74
|
+
|
|
75
|
+
Usa `transaction` e `commit` quando tutte le operazioni di scrittura racchiuse devono avere successo o fallire insieme.
|
|
76
|
+
|
|
77
|
+
```csharp
|
|
78
|
+
var blog = new ChillDtoEntity
|
|
79
|
+
{
|
|
80
|
+
ChillType = "Model.Blog",
|
|
81
|
+
Guid = Guid.NewGuid()
|
|
82
|
+
};
|
|
83
|
+
blog.Properties["Name"] = "Batch blog";
|
|
84
|
+
blog.Properties["Url"] = "https://example.local/batch-blog";
|
|
85
|
+
|
|
86
|
+
var post = new ChillDtoEntity
|
|
87
|
+
{
|
|
88
|
+
ChillType = "Model.Post",
|
|
89
|
+
Guid = Guid.NewGuid()
|
|
90
|
+
};
|
|
91
|
+
post.Properties["Title"] = "Batch post";
|
|
92
|
+
post.Properties["Blog"] = blog.Mock();
|
|
93
|
+
|
|
94
|
+
var transactionalOperations = client.Chunk(new List<ChillOperation>
|
|
95
|
+
{
|
|
96
|
+
new() { Index = 0, Verb = ChillOperationVerb.TRANSACTION },
|
|
97
|
+
new() { Index = 1, Verb = ChillOperationVerb.CREATE, Entity = blog },
|
|
98
|
+
new() { Index = 2, Verb = ChillOperationVerb.CREATE, Entity = post },
|
|
99
|
+
new() { Index = 3, Verb = ChillOperationVerb.COMMIT }
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Usa questo pattern solo per le operazioni di scrittura che devono condividere la stessa transazione database.
|
|
104
|
+
Se un'operazione fallisce prima di `commit`, la transazione non viene confermata.
|
|
105
|
+
|
|
106
|
+
## 4. Eseguire Autocomplete Su Un DTO Entita
|
|
107
|
+
|
|
108
|
+
`autocomplete` usa lo stesso stile DTO di `create`, `update` e `delete`, ma chiama `/api/chill/autocomplete`.
|
|
109
|
+
|
|
110
|
+
Per le entita, ChillSharp esegue `OnAutocomplete(...)` senza persistere modifiche:
|
|
111
|
+
|
|
112
|
+
- se l'entita esiste gia, viene caricata dal `DbContext` corrente
|
|
113
|
+
- altrimenti viene collegata al contesto in stato `Added`
|
|
114
|
+
- la logica di autocomplete gira dentro una transazione temporanea
|
|
115
|
+
- la transazione viene annullata alla fine, quindi il database non cambia
|
|
116
|
+
|
|
117
|
+
Questo e utile per vedere in anteprima valori calcolati come slug, label, testo derivato o combinazioni di campi predefinite.
|
|
118
|
+
|
|
119
|
+
```csharp
|
|
120
|
+
var draftBlog = new ChillDtoEntity
|
|
121
|
+
{
|
|
122
|
+
ChillType = "Model.Blog",
|
|
123
|
+
Guid = Guid.NewGuid()
|
|
124
|
+
};
|
|
125
|
+
draftBlog.Properties["Title"] = " My first ChillSharp blog ";
|
|
126
|
+
|
|
127
|
+
var autocompletedBlog = client.Autocomplete(draftBlog);
|
|
128
|
+
|
|
129
|
+
Console.WriteLine(autocompletedBlog.GetString("Title"));
|
|
130
|
+
Console.WriteLine(autocompletedBlog.GetString("Url"));
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Logica tipica lato entita:
|
|
134
|
+
|
|
135
|
+
```csharp
|
|
136
|
+
public override void OnAutocomplete(IChillContext context)
|
|
137
|
+
{
|
|
138
|
+
base.OnAutocomplete(context);
|
|
139
|
+
|
|
140
|
+
Title = Title?.Trim();
|
|
141
|
+
|
|
142
|
+
if (string.IsNullOrWhiteSpace(Url) && !string.IsNullOrWhiteSpace(Title))
|
|
143
|
+
{
|
|
144
|
+
Url = "/blogs/" + Title.ToLowerInvariant().Replace(' ', '-');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 5. Eseguire Autocomplete Su Un DTO Query
|
|
150
|
+
|
|
151
|
+
Anche le query usano `/api/chill/autocomplete`, ma non partecipano al flusso transazionale del contesto EF Core.
|
|
152
|
+
Il DTO query viene semplicemente passato a `OnAutocomplete(...)` sulla `IChillQuery` risolta.
|
|
153
|
+
|
|
154
|
+
Questo e utile per normalizzare i filtri prima di `Query(...)`, per esempio:
|
|
155
|
+
|
|
156
|
+
- rimuovere spazi superflui dagli input testuali
|
|
157
|
+
- espandere un campo di ricerca in un campo full-text
|
|
158
|
+
- impostare valori predefiniti di paging o ordinamento
|
|
159
|
+
|
|
160
|
+
```csharp
|
|
161
|
+
var blogQuery = new ChillDtoQuery
|
|
162
|
+
{
|
|
163
|
+
ChillType = "Query.BlogQuery"
|
|
164
|
+
};
|
|
165
|
+
blogQuery.Properties["Title"] = " chillsharp ";
|
|
166
|
+
|
|
167
|
+
var autocompletedQuery = client.Autocomplete(blogQuery);
|
|
168
|
+
|
|
169
|
+
Console.WriteLine(autocompletedQuery.GetString("Title"));
|
|
170
|
+
Console.WriteLine(autocompletedQuery.GetString("FullTextSearch"));
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Logica tipica lato query:
|
|
174
|
+
|
|
175
|
+
```csharp
|
|
176
|
+
public override void OnAutocomplete(IChillContext context)
|
|
177
|
+
{
|
|
178
|
+
base.OnAutocomplete(context);
|
|
179
|
+
|
|
180
|
+
Title = Title?.Trim();
|
|
181
|
+
|
|
182
|
+
if (!string.IsNullOrWhiteSpace(Title))
|
|
183
|
+
{
|
|
184
|
+
FullTextSearch = Title;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## 6. Scegliere La API Giusta
|
|
190
|
+
|
|
191
|
+
- usa `create`, `update` e `delete` quando l'operazione deve cambiare subito il database
|
|
192
|
+
- usa `chunk` quando piu operazioni devono viaggiare in una sola richiesta
|
|
193
|
+
- usa `transaction` piu `commit` dentro `chunk` quando piu scritture devono essere atomiche
|
|
194
|
+
- usa `autocomplete` quando il server deve calcolare o normalizzare valori senza salvarli
|
|
195
|
+
|
|
196
|
+
Prossimo: [Torna all'indice della documentazione](../README.md)
|