@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,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chillsharp-current-user-preferences
|
|
3
|
+
description: Configure, expose, and consume ChillSharp.Auth's cached current-user culture, time zone, date-format, number-format, and theme preferences in server logic and UI clients.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ChillSharp Current User Preferences
|
|
7
|
+
|
|
8
|
+
Use this skill when a ChillSharp feature needs the authenticated user's display culture, time zone, date format, or number format. It covers server-side lifecycle hooks and UI/client consumption of the authoritative `AuthUser` preferences. Do not use it for browser-only preferences unrelated to `AuthUser`.
|
|
9
|
+
|
|
10
|
+
## Model
|
|
11
|
+
|
|
12
|
+
`ChillUserPreferences` is an immutable snapshot with `DisplayCultureName`, `DisplayTimeZone`, `DisplayDateFormat`, `DisplayNumberFormat`, and `PreferredTheme`. The backend stores `PreferredTheme` as an opaque string. In UI Core, unauthenticated users follow browser `prefers-color-scheme`; clients register extra themes with `provideChillSharpUiCore({ additionalThemes: ['theme-name'] })`. Entity hooks read the snapshot synchronously through:
|
|
13
|
+
|
|
14
|
+
```csharp
|
|
15
|
+
var preferences = context.GetCurrentUserPreferences();
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Never load `AuthUser` from an `OnCreate`, `OnUpdate`, or other lifecycle hook merely to obtain these values.
|
|
19
|
+
|
|
20
|
+
## Auth integration
|
|
21
|
+
|
|
22
|
+
`AddChillAuthApi` registers `IChillAuthUserPreferencesAccessor` and the singleton `IChillAuthUserPreferencesCache`. Login and token refresh warm the snapshot; `ChillAuthService` refreshes it after an `AuthUser` save and removes it for deleted or renamed external identities.
|
|
23
|
+
|
|
24
|
+
For a custom host DbContext, inject the scoped accessor and implement the two `IChillContext` methods below. Keep the accessor optional only when the context must also be constructible outside DI, such as for migrations or tests.
|
|
25
|
+
|
|
26
|
+
```csharp
|
|
27
|
+
private readonly IChillAuthUserPreferencesAccessor? _userPreferencesAccessor;
|
|
28
|
+
|
|
29
|
+
public ChillUserPreferences GetCurrentUserPreferences() =>
|
|
30
|
+
_userPreferencesAccessor?.Current ?? ChillUserPreferences.Empty;
|
|
31
|
+
|
|
32
|
+
public string GetDefaultUserCultureName()
|
|
33
|
+
{
|
|
34
|
+
var cultureName = GetCurrentUserPreferences().DisplayCultureName;
|
|
35
|
+
return string.IsNullOrWhiteSpace(cultureName) ? GetPrimaryCultureName() : cultureName;
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The accessor is cache-only: when there is no authenticated principal or no warmed snapshot, it returns `ChillUserPreferences.Empty`. Do not add a fallback database query to lifecycle hooks.
|
|
40
|
+
|
|
41
|
+
## API and client use
|
|
42
|
+
|
|
43
|
+
The authenticated endpoint `GET /api/chill-auth/current-user-preferences` returns the same `ChillUserPreferences` snapshot as JSON:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"displayCultureName": "it-IT",
|
|
48
|
+
"displayTimeZone": "Europe/Rome",
|
|
49
|
+
"displayDateFormat": "dd/MM/yyyy",
|
|
50
|
+
"displayNumberFormat": "N2"
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Use this endpoint after authentication and when restoring a session; do not infer the active display culture or time zone from the browser, operating system, token claims, or auth-management user endpoints. The C#, Python, TypeScript, Angular, Vue, and React clients expose it as `GetCurrentUserPreferences`, `get_current_user_preferences`, or `getCurrentUserPreferences`; the Vue and React packages also provide `useCurrentUserPreferences`.
|
|
55
|
+
|
|
56
|
+
In Angular UI Core, inject `ChillService` and read its `userPreferences` signal (or its `displayCultureName`, `displayTimeZone`, `displayDateFormat`, and `displayNumberFormat` projections). Use these values to select UI language, format and parse dates and numbers, and convert UTC timestamps. Treat all fields as optional and choose an explicit fallback only when needed.
|
|
57
|
+
|
|
58
|
+
## Entity use
|
|
59
|
+
|
|
60
|
+
Use `DisplayTimeZone` as an IANA zone identifier only after validating it with the application's time-zone policy. Treat all fields as optional and provide an explicit fallback where one is required.
|
|
61
|
+
|
|
62
|
+
```csharp
|
|
63
|
+
public override void OnUpdate(IChillContext context)
|
|
64
|
+
{
|
|
65
|
+
var timeZone = context.GetCurrentUserPreferences().DisplayTimeZone;
|
|
66
|
+
// Apply application-specific behavior only when timeZone is available.
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
For full setup and cache behavior, read [CurrentUserPreferences.md](../../../doc/CurrentUserPreferences.md).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chillsharp-ui-template
|
|
3
|
+
description: Build and customize Angular ChillSharp client projects from the UI template, including plugins, overrides, i18n, permissions, and runtime configuration.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ChillSharp UI Client Template
|
|
7
|
+
|
|
8
|
+
Use this skill for work in `chill-sharp-ui-template` or a client repository created from it.
|
|
9
|
+
|
|
10
|
+
The template owns runtime configuration, branding, routes, client plugins, and overrides. Shared controls, data access, schema rendering, auth, i18n primitives, and permission evaluation belong in `@chill-sharp/ui-core` and the ChillSharp client packages. Do not copy or patch shared package internals.
|
|
11
|
+
|
|
12
|
+
Keep `provideClientTemplateProviders()` in the app provider chain. Register feature routes in `src/app/core/plugins/register-client-plugins.ts`; register deliberate provider replacements in `src/app/core/overrides/register-client-overrides.ts`. Use public package APIs only.
|
|
13
|
+
|
|
14
|
+
Treat backend schema as the source of entity/property metadata rather than duplicating it in Angular. Use runtime API configuration from `public/env.js`. Request localized text with an explicit culture and preserve backend fallback behavior. UI permission checks can hide or disable operations, but the protected backend is the enforcement boundary.
|
|
15
|
+
|
|
16
|
+
Permission-sensitive features must account for `Module -> Entity -> Property`: entity `Query/Create/Update/Delete` is separate from property `See/Modify`. Never infer write access from a visible field.
|
|
17
|
+
|
|
18
|
+
Add plugins under the client-owned plugin folder, register providers through the override/provider points, keep tenant/feature flags/branding in runtime config, add focused tests, and run `npm run build` after registration changes. This `.agents/skills` directory travels with the template into client repositories.
|
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @chill-sharp/ui-core
|
|
2
|
+
|
|
3
|
+
Private Angular package that contains the shared ChillSharp UI implementation extracted from the standard `chill-sharp-ng-ui` application.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
This package contains:
|
|
8
|
+
|
|
9
|
+
- shared layouts
|
|
10
|
+
- shared pages
|
|
11
|
+
- shared services
|
|
12
|
+
- workspace/task infrastructure
|
|
13
|
+
- reusable ChillSharp form and table components
|
|
14
|
+
- shared models and runtime helpers
|
|
15
|
+
- base theme styles
|
|
16
|
+
|
|
17
|
+
This package intentionally does not contain a client-specific shell application.
|
|
18
|
+
|
|
19
|
+
Client shells and client-owned plugins should live outside this package.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @chill-sharp/ui-core
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Build And Release
|
|
28
|
+
|
|
29
|
+
See [`HOW_TO_BUILD.md`](/c:/source/personal/chill-sharp/chill-sharp/extra/chill-sharp-ui-core/HOW_TO_BUILD.md) for the workflow to rebuild, version, and publish the library after a change.
|
|
30
|
+
|
|
31
|
+
## Plugin Documentation
|
|
32
|
+
|
|
33
|
+
`@chill-sharp/ui-core` currently supports client extension through template-owned routes, provider override placeholders, and runtime-loaded remote workspace tasks. It does not yet expose a single formal plugin registration API.
|
|
34
|
+
|
|
35
|
+
See [`../HOW_TO_CREATE_UI_CORE_PLUGIN_README.md`](../HOW_TO_CREATE_UI_CORE_PLUGIN_README.md) before documenting a client plugin or remote workspace task package.
|
|
36
|
+
|
|
37
|
+
## Theme import
|
|
38
|
+
|
|
39
|
+
Import the shared theme from your client shell:
|
|
40
|
+
|
|
41
|
+
```scss
|
|
42
|
+
@import '@chill-sharp/ui-core/styles/core-theme.scss';
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Package entry points
|
|
46
|
+
|
|
47
|
+
- `ChillSharpUiRootComponent`: router host component for the shell
|
|
48
|
+
- `CHILL_SHARP_UI_ROUTES`: default route tree for the standard ChillSharp UI
|
|
49
|
+
- `provideChillSharpUiCore()`: shared providers and initializers
|
|
50
|
+
|
|
51
|
+
## Status
|
|
52
|
+
|
|
53
|
+
This is the initial extraction of the current Angular implementation into a reusable `ui-core` package. Client shells should consume it and own only bootstrap, configuration, branding, theme overrides, and local plugins.
|
|
54
|
+
|
|
55
|
+
## Service worker cache
|
|
56
|
+
|
|
57
|
+
`@chill-sharp/ui-core` ships `service-worker/chill-sharp-service-worker.js`.
|
|
58
|
+
The template and GDF load it from their client-owned `public/sw.js`; future package
|
|
59
|
+
upgrades update the shared behavior without replacing client options.
|
|
60
|
+
|
|
61
|
+
For an existing client, integrate once:
|
|
62
|
+
|
|
63
|
+
1. Upgrade `@chill-sharp/ui-core` to a package containing the worker (1.1.6 or later).
|
|
64
|
+
2. Add this entry to the Angular build assets (and test assets if applicable):
|
|
65
|
+
`{"glob":"*.js","input":"node_modules/@chill-sharp/ui-core/service-worker","output":"/"}`.
|
|
66
|
+
3. Create/adapt `public/sw.js`:
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
self.CHILL_SHARP_SW_OPTIONS = {
|
|
70
|
+
cachePrefix: 'my-app',
|
|
71
|
+
cacheVersion: 'v2',
|
|
72
|
+
cacheTimeoutMs: 10 * 60 * 1000,
|
|
73
|
+
appShell: ['/', '/index.html'],
|
|
74
|
+
legacyCacheNames: []
|
|
75
|
+
};
|
|
76
|
+
importScripts('./chill-sharp-service-worker.js');
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
4. Register `/sw.js` with `{ updateViaCache: 'none' }` on page load. Serve both
|
|
80
|
+
worker scripts with `Cache-Control: no-cache, must-revalidate`, not immutable.
|
|
81
|
+
HTTPS (or localhost) is required. Apps hosted below `/` must adjust shell URLs,
|
|
82
|
+
registration URL and scope for their base path.
|
|
83
|
+
|
|
84
|
+
Do not register a second worker alongside an existing custom worker for the same
|
|
85
|
+
scope; integrate the shared worker into the client wrapper. Cache names belonging
|
|
86
|
+
to `cachePrefix` with old versions are removed on activation. Use `legacyCacheNames`
|
|
87
|
+
for explicitly named old caches with a different prefix. Unrelated caches survive.
|
|
88
|
+
|
|
89
|
+
Schema, schema-list and entity-options GETs expire at ten minutes, including
|
|
90
|
+
cross-origin API requests. Expired entries fetch from the network without using
|
|
91
|
+
the browser HTTP cache; expired metadata is not returned as an offline fallback.
|
|
92
|
+
Bearer responses vary by Authorization. Other APIs and runtime configuration are
|
|
93
|
+
network-only. Static runtime assets use the same lifetime; the precached app shell
|
|
94
|
+
remains available as a navigation fallback when offline.
|
|
95
|
+
|
|
96
|
+
Every `get-schema?update=true` request reaches the server. It clears all cached
|
|
97
|
+
schemas, lists and entity options before and after the request, as do `set-schema`
|
|
98
|
+
and `set-entity-options`. Reads during a write wait for it to finish, and old
|
|
99
|
+
in-flight reads cannot refill the cache after invalidation. The first ordinary GET
|
|
100
|
+
after the update or a page reload fetches a fresh schema and starts a new lifetime.
|
|
101
|
+
|
|
102
|
+
Run `npm run test:service-worker` in `extra/chill-sharp-ui-core` for the regression
|
|
103
|
+
tests covering expiration, invalidation, authorization and request races.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chill-sharp-ui-core.d.ts","sourceRoot":"","sources":["../src/chill-sharp-ui-core.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# AI-Assisted Development Guide
|
|
2
|
+
|
|
3
|
+
Versione italiana: [Italiano](../it/AIAssistedDevelopment/README.md)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
This document explains how ChillSharp can help when you build software with AI assistance and still want the codebase to remain structured, stable, and reviewable.
|
|
7
|
+
|
|
8
|
+
The key idea is simple: AI tools are much more reliable when they work inside a constrained, repetitive, well-defined architecture than when they are asked to manually keep many controllers, DTOs, endpoints, and validation paths in sync.
|
|
9
|
+
|
|
10
|
+
ChillSharp does not make AI-generated code automatically correct. What it does is reduce the amount of surface area that AI has to generate and maintain.
|
|
11
|
+
|
|
12
|
+
## Why This Matters
|
|
13
|
+
|
|
14
|
+
A common failure mode in AI-assisted backend development is that the model touches too many moving parts at once:
|
|
15
|
+
|
|
16
|
+
- controllers
|
|
17
|
+
- DTO mappings
|
|
18
|
+
- request/response contracts
|
|
19
|
+
- validation logic
|
|
20
|
+
- authorization checks
|
|
21
|
+
- duplicated CRUD behaviors
|
|
22
|
+
|
|
23
|
+
The more files and custom endpoints you have, the easier it is for AI to introduce accidental interface drift, inconsistent behavior, or broad refactors that were never intended.
|
|
24
|
+
|
|
25
|
+
ChillSharp reduces that risk by moving a large part of the backend surface into a uniform model-driven runtime.
|
|
26
|
+
|
|
27
|
+
## How ChillSharp Helps
|
|
28
|
+
|
|
29
|
+
### 1. Business logic grows inside a structured environment
|
|
30
|
+
|
|
31
|
+
With ChillSharp, the main extension points are explicit and predictable:
|
|
32
|
+
|
|
33
|
+
- `ChillEntity`
|
|
34
|
+
- `ChillQuery`
|
|
35
|
+
- `OnValidation()`
|
|
36
|
+
- lifecycle hooks such as `OnCreate()`, `OnUpdate()`, `OnAfterUpdate()`, `OnDelete()`, and `OnSelect()`
|
|
37
|
+
- metadata through `[ChillProperty]` and related annotations
|
|
38
|
+
|
|
39
|
+
That gives AI a narrower and more structured place to make changes.
|
|
40
|
+
|
|
41
|
+
Instead of asking an AI model to invent yet another controller, request DTO, response DTO, mapper, validator, and route contract, you can often ask it to:
|
|
42
|
+
|
|
43
|
+
- add a property
|
|
44
|
+
- add validation
|
|
45
|
+
- add a query filter
|
|
46
|
+
- add lifecycle logic
|
|
47
|
+
- adjust permission rules
|
|
48
|
+
|
|
49
|
+
This usually produces smaller and safer edits.
|
|
50
|
+
|
|
51
|
+
### 2. Lower risk of accidental endpoint refactoring
|
|
52
|
+
|
|
53
|
+
ChillSharp exposes a standard API surface through `app.MapChillApi()`, with stable operations such as:
|
|
54
|
+
|
|
55
|
+
- `POST /api/chill/query`
|
|
56
|
+
- `POST /api/chill/lookup`
|
|
57
|
+
- `POST /api/chill/find`
|
|
58
|
+
- `POST /api/chill/create`
|
|
59
|
+
- `POST /api/chill/update`
|
|
60
|
+
- `POST /api/chill/delete`
|
|
61
|
+
|
|
62
|
+
Because the transport surface is centralized, adding or evolving business entities does not require AI to keep rewriting a growing set of per-entity controllers and route definitions.
|
|
63
|
+
|
|
64
|
+
This reduces a specific AI risk:
|
|
65
|
+
|
|
66
|
+
- changing endpoint names by accident
|
|
67
|
+
- changing payload shapes inconsistently
|
|
68
|
+
- implementing one endpoint differently from the rest
|
|
69
|
+
- breaking clients through unnecessary API refactors
|
|
70
|
+
|
|
71
|
+
The interface still evolves when your model evolves, but the CRUD and query mechanics do not have to be re-authored every time.
|
|
72
|
+
|
|
73
|
+
### 3. Endpoints grow in a uniform way
|
|
74
|
+
|
|
75
|
+
In a traditional hand-written backend, every new entity tends to create more duplicated API code. Over time, small differences accumulate:
|
|
76
|
+
|
|
77
|
+
- one controller validates differently
|
|
78
|
+
- another controller returns slightly different payloads
|
|
79
|
+
- another endpoint forgets an authorization check
|
|
80
|
+
- another DTO mapper omits a field
|
|
81
|
+
|
|
82
|
+
AI tools amplify this problem because they continue the local pattern they see, even when the local pattern is already inconsistent.
|
|
83
|
+
|
|
84
|
+
ChillSharp pushes the system in the opposite direction: entities and queries plug into the same runtime model, so growth is more uniform by default.
|
|
85
|
+
|
|
86
|
+
That uniformity helps both:
|
|
87
|
+
|
|
88
|
+
- human maintainers reviewing AI-produced changes
|
|
89
|
+
- AI tools reasoning over the codebase with less ambiguity
|
|
90
|
+
|
|
91
|
+
### 4. Smaller program payload for AI tools
|
|
92
|
+
|
|
93
|
+
When a project relies on many custom CRUD controllers, DTO classes, mapping layers, and repetitive endpoint definitions, AI needs more repository context to make a safe change.
|
|
94
|
+
|
|
95
|
+
That increases:
|
|
96
|
+
|
|
97
|
+
- token usage
|
|
98
|
+
- latency
|
|
99
|
+
- cost
|
|
100
|
+
- the chance that the model misses one of the duplicated layers
|
|
101
|
+
|
|
102
|
+
ChillSharp reduces this burden because much of the repetitive transport logic is already handled by the framework runtime.
|
|
103
|
+
|
|
104
|
+
In practice this means an AI task can often be solved by reading and changing:
|
|
105
|
+
|
|
106
|
+
- one entity
|
|
107
|
+
- one query
|
|
108
|
+
- one validation rule
|
|
109
|
+
- one permission definition
|
|
110
|
+
|
|
111
|
+
instead of a long chain of related files.
|
|
112
|
+
|
|
113
|
+
### 5. Lower pressure for continuous large-scale refactoring
|
|
114
|
+
|
|
115
|
+
Without a model-driven framework, teams often ask AI to keep refactoring a growing list of:
|
|
116
|
+
|
|
117
|
+
- endpoints
|
|
118
|
+
- controllers
|
|
119
|
+
- DTOs
|
|
120
|
+
- validators
|
|
121
|
+
- mappers
|
|
122
|
+
- permission checks
|
|
123
|
+
|
|
124
|
+
That is expensive and fragile. It also encourages broad automated rewrites that may not deliver business value.
|
|
125
|
+
|
|
126
|
+
ChillSharp reduces the need for that style of maintenance because the generic CRUD/query surface is already centralized.
|
|
127
|
+
|
|
128
|
+
That has practical benefits:
|
|
129
|
+
|
|
130
|
+
- lower AI token consumption
|
|
131
|
+
- fewer broad refactors across repetitive files
|
|
132
|
+
- less review effort for generated code
|
|
133
|
+
- lower compute usage for the same feature work
|
|
134
|
+
|
|
135
|
+
If you care about both engineering efficiency and energy efficiency, this is one of the strongest arguments for using a uniform runtime instead of a large amount of repeated endpoint boilerplate.
|
|
136
|
+
|
|
137
|
+
## What ChillSharp Is Good At In AI Workflows
|
|
138
|
+
|
|
139
|
+
ChillSharp is a good fit when you want AI to help with:
|
|
140
|
+
|
|
141
|
+
- extending domain entities
|
|
142
|
+
- adding validation rules
|
|
143
|
+
- adding query capabilities
|
|
144
|
+
- exposing model changes through an existing generic API surface
|
|
145
|
+
- keeping permissions and metadata closer to the model
|
|
146
|
+
|
|
147
|
+
This is usually a better fit than asking AI to repeatedly generate large sets of CRUD infrastructure code.
|
|
148
|
+
|
|
149
|
+
## What ChillSharp Does Not Solve
|
|
150
|
+
|
|
151
|
+
ChillSharp does not remove the need for engineering review. In particular, you still need to verify:
|
|
152
|
+
|
|
153
|
+
- business rules are correct
|
|
154
|
+
- authorization rules are correct
|
|
155
|
+
- exposed properties are intentional
|
|
156
|
+
- model changes do not break consumers
|
|
157
|
+
- AI-generated lifecycle logic is actually safe
|
|
158
|
+
|
|
159
|
+
ChillSharp reduces duplication and drift. It does not remove the need for judgment.
|
|
160
|
+
|
|
161
|
+
## Recommended Positioning
|
|
162
|
+
|
|
163
|
+
If you want a short and defensible way to describe this in documentation or architecture notes, use something like:
|
|
164
|
+
|
|
165
|
+
"ChillSharp helps AI-assisted development by centralizing repetitive API mechanics into a model-driven runtime. This reduces accidental interface drift, keeps endpoint behavior more uniform, and lowers the amount of code and repository context that AI tools must generate and maintain."
|
|
166
|
+
|
|
167
|
+
## Practical Checklist
|
|
168
|
+
|
|
169
|
+
If you want to use ChillSharp as an AI-friendly backend architecture, the baseline is:
|
|
170
|
+
|
|
171
|
+
1. keep business entities and queries as the main place where feature behavior is defined
|
|
172
|
+
2. use `[ChillProperty]` consistently so the DTO and validation surface remains intentional
|
|
173
|
+
3. prefer `OnValidation()` and lifecycle hooks over ad-hoc controller logic
|
|
174
|
+
4. avoid reintroducing repetitive custom CRUD endpoints unless there is a real need
|
|
175
|
+
5. review model changes carefully because a model-driven surface can affect multiple client operations at once
|
|
176
|
+
6. keep permissions and authentication aligned with the same model-driven approach
|
|
177
|
+
|
|
178
|
+
## Related Documents
|
|
179
|
+
|
|
180
|
+
- [../README.md](../README.md)
|
|
181
|
+
- [../RegisterContext.md](../RegisterContext.md)
|
|
182
|
+
- [../ValidationModel/README.md](../ValidationModel/README.md)
|
|
183
|
+
- [../PermissionModel/README.md](../PermissionModel/README.md)
|
|
184
|
+
- [../AuthenticationModel/README.md](../AuthenticationModel/README.md)
|
|
185
|
+
- [../ClientGeneration/README.md](../ClientGeneration/README.md)
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Attachment Module
|
|
2
|
+
|
|
3
|
+
Versione italiana: [Italiano](../it/AttachmentModel/README.md)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
`ChillSharp.Attachment` adds a built-in attachment entity plus upload and download endpoints backed by a filesystem archive.
|
|
7
|
+
|
|
8
|
+
## What It Adds
|
|
9
|
+
|
|
10
|
+
- `Attachment` Chill entity persisted in the `attachment` table
|
|
11
|
+
- generic Chill CRUD support for attachment metadata
|
|
12
|
+
- `GET /api/chill-attachment/attachment/download?guid=...`
|
|
13
|
+
- `POST /api/chill-attachment/attachment/upload`
|
|
14
|
+
|
|
15
|
+
Because `Attachment` is a real `ChillEntity`, it is also exposed through schema discovery and can be managed through the standard Chill CRUD endpoints once the host `DbContext` implements `IChillAttachmentDbContext`.
|
|
16
|
+
|
|
17
|
+
The module also exposes an `AttachmentQuery` Chill query type, which client helpers can use to list attachments linked to a target entity.
|
|
18
|
+
|
|
19
|
+
## Register The Module
|
|
20
|
+
|
|
21
|
+
Add the module model to your context and expose the `DbSet`:
|
|
22
|
+
|
|
23
|
+
```csharp
|
|
24
|
+
using ChillSharp.Attachment;
|
|
25
|
+
using ChillSharp.Attachment.Model;
|
|
26
|
+
|
|
27
|
+
public class AppDbContext : DbContext, IChillContext, IChillAttachmentDbContext
|
|
28
|
+
{
|
|
29
|
+
public DbSet<Attachment> Attachments => Set<Attachment>();
|
|
30
|
+
|
|
31
|
+
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
32
|
+
{
|
|
33
|
+
base.OnModelCreating(modelBuilder);
|
|
34
|
+
modelBuilder.AddChillAttachmentModel();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public string GetChillTypePrefix() => "MyApp.Data";
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
When the context implements `IChillAttachmentDbContext`, `services.AddChillApi<AppDbContext>()` automatically registers the attachment endpoints.
|
|
42
|
+
|
|
43
|
+
## Archive Root Configuration
|
|
44
|
+
|
|
45
|
+
The module reads the archive root from:
|
|
46
|
+
|
|
47
|
+
- startup options via `services.Configure<ChillAttachmentOptions>(...)`
|
|
48
|
+
- environment variable `CHILLSHARP_ATTACHMENT_ARCHIVE_ROOT`
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
|
|
52
|
+
```csharp
|
|
53
|
+
builder.Services.Configure<ChillAttachmentOptions>(options =>
|
|
54
|
+
{
|
|
55
|
+
options.ArchiveRoot = "/srv/chill/attachments";
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Or through environment:
|
|
60
|
+
|
|
61
|
+
```env
|
|
62
|
+
CHILLSHARP_ATTACHMENT_ARCHIVE_ROOT=/srv/chill/attachments
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Archive Layout
|
|
66
|
+
|
|
67
|
+
Files are stored under the configured archive root using:
|
|
68
|
+
|
|
69
|
+
```csharp
|
|
70
|
+
public static string BuildAttachmentPath(
|
|
71
|
+
string archiveRoot,
|
|
72
|
+
string attachToChillType,
|
|
73
|
+
Guid id,
|
|
74
|
+
string extension,
|
|
75
|
+
DateTime createdAtUtc)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The resulting layout is:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
{archiveRoot}/{attachToChillType}/{year}/{guid[0..2]}/{guid[2..4]}/{guid}{extension}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Example:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
/srv/chill/attachments/Post/2026/ab/cd/abcd1234....pdf
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Upload Endpoint
|
|
91
|
+
|
|
92
|
+
`POST /api/chill-attachment/attachment/upload`
|
|
93
|
+
|
|
94
|
+
Multipart form fields:
|
|
95
|
+
|
|
96
|
+
- `attachToChillType`
|
|
97
|
+
- `attachToGuid`
|
|
98
|
+
- `title`
|
|
99
|
+
- `description`
|
|
100
|
+
- `public`
|
|
101
|
+
- one or more `file` parts
|
|
102
|
+
|
|
103
|
+
For each uploaded file the module:
|
|
104
|
+
|
|
105
|
+
1. creates an `Attachment` Chill entity through `ChillEngine`
|
|
106
|
+
2. stores the physical file in the archive
|
|
107
|
+
3. returns the created attachment DTO payload
|
|
108
|
+
|
|
109
|
+
## Download Endpoint
|
|
110
|
+
|
|
111
|
+
`GET /api/chill-attachment/attachment/download?guid={attachmentGuid}`
|
|
112
|
+
|
|
113
|
+
Behavior:
|
|
114
|
+
|
|
115
|
+
- loads the `Attachment` entity from the database
|
|
116
|
+
- resolves the archived file path
|
|
117
|
+
- returns the file using the stored original filename and mime type
|
|
118
|
+
- allows anonymous download when `Public == true`
|
|
119
|
+
- requires an authenticated user when `Public == false`
|
|
120
|
+
|
|
121
|
+
## Client Helpers
|
|
122
|
+
|
|
123
|
+
### `.NET`
|
|
124
|
+
|
|
125
|
+
`ChillSharp.Client` now includes attachment helpers:
|
|
126
|
+
|
|
127
|
+
```csharp
|
|
128
|
+
var post = new ChillDtoEntity
|
|
129
|
+
{
|
|
130
|
+
Guid = postGuid,
|
|
131
|
+
ChillType = "Model.Post"
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
var uploaded = await client.UploadAttachmentAsync(
|
|
135
|
+
post,
|
|
136
|
+
File.ReadAllBytes("contract.pdf"),
|
|
137
|
+
"contract.pdf",
|
|
138
|
+
"application/pdf",
|
|
139
|
+
title: "Signed contract",
|
|
140
|
+
description: "Customer-facing version",
|
|
141
|
+
isPublic: false);
|
|
142
|
+
|
|
143
|
+
var attachments = await client.GetAttachmentsAsync(post);
|
|
144
|
+
var fileBytes = await client.DownloadAttachmentAsync(uploaded[0]);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Available overloads cover:
|
|
148
|
+
|
|
149
|
+
- upload from file path
|
|
150
|
+
- upload from `byte[]`
|
|
151
|
+
- upload from `Stream`
|
|
152
|
+
- download by attachment `Guid`
|
|
153
|
+
- download by attachment `ChillDtoEntity`
|
|
154
|
+
|
|
155
|
+
### TypeScript / Angular / React / Vue / Python
|
|
156
|
+
|
|
157
|
+
The generic client libraries under `extra-libs/` expose matching helpers:
|
|
158
|
+
|
|
159
|
+
- TypeScript: `uploadAttachment()`, `uploadAttachments()`, `getAttachments()`, `downloadAttachment()`
|
|
160
|
+
- Angular: same helpers through `ChillSharpNgClient` as `Observable` wrappers
|
|
161
|
+
- React and Vue: same helpers through the raw client returned by `useChillSharpClient()`
|
|
162
|
+
- Python: `upload_attachment()`, `upload_attachments()`, `get_attachments()`, `download_attachment()`
|
|
163
|
+
|
|
164
|
+
## Generic CRUD
|
|
165
|
+
|
|
166
|
+
Attachment metadata remains available through the standard Chill endpoints:
|
|
167
|
+
|
|
168
|
+
- `POST /api/chill/create`
|
|
169
|
+
- `POST /api/chill/find`
|
|
170
|
+
- `POST /api/chill/update`
|
|
171
|
+
- `POST /api/chill/delete`
|
|
172
|
+
|
|
173
|
+
Deleting an attachment through ChillSharp also removes the archived file from disk.
|