Istruzioni copilot

This commit is contained in:
2026-06-05 11:16:49 +02:00
parent e634123904
commit fcf0cf0b77
+425 -42
View File
@@ -1,67 +1,450 @@
# GitHub Copilot Instructions — Fixiy
## Project Overview
Fixiy is a MAUI Blazor Hybrid application with a shared codebase.
### Solution Structure
* `Fixiy.Shared` contains:
* Business logic
* Razor pages
* Shared components
* DTOs
* Interfaces
* Service abstractions
* `Fixiy.Maui` is the MAUI host application.
* `Fixiy.Web` is the ASP.NET Core host application.
The Shared project is the source of truth. Avoid duplicating logic between hosts.
---
## Agent Behaviour
* Before making changes, inspect the existing implementation and follow established patterns.
* Prefer extending existing functionality over creating new implementations.
* Make the smallest change necessary to satisfy the requirement.
* Never rewrite large portions of working code unless explicitly requested.
* Search for existing services, DTOs, components, pages and interfaces before creating new ones.
* Never create duplicate functionality.
* Do not rename public classes, interfaces, routes, pages or services without verifying all usages.
* When requirements are unclear, ask for clarification instead of making assumptions.
* Preserve the existing architecture.
* Do not move files between projects unless explicitly requested.
* Do not generate placeholder implementations containing TODO comments unless specifically requested.
* Always check whether a change affects both MAUI and Web hosts.
---
## Language and Style
- **C# 12+** with `<Nullable>enable</Nullable>` and `<ImplicitUsings>enable</ImplicitUsings>` throughout. Never disable these per-file without strong justification.
- Use **file-scoped namespaces** (`namespace Fixiy.Shared.Services;`) not block-scoped.
- Prefer `record` types for immutable DTOs.
- Use `async`/`await` consistently — never `.Result` or `.Wait()` on Tasks.
- Remove unused `using` directives.
* Use C# 12+.
* Always keep:
```xml
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
```
* Never disable nullable reference types without strong justification.
* Use file-scoped namespaces:
```csharp
namespace Fixiy.Shared.Services;
```
* Never use block-scoped namespaces.
* Prefer `record` types for immutable DTOs.
* Use expression-bodied members when they improve readability.
* Use collection expressions when appropriate.
* Use `async`/`await` consistently.
* Never use `.Result`, `.Wait()` or `.GetAwaiter().GetResult()`.
* Remove unused `using` directives.
* One type per file.
* File names must match type names.
* Constants use PascalCase.
* Do not use Hungarian notation.
* Omit the `private` modifier on fields.
---
## Blazor Component Conventions
- All shared components live in `Fixiy.Shared/Components/`. Do not create components in `Fixiy.Maui` or `Fixiy.Web`.
- Pages go in `Fixiy.Shared/Components/Pages/`, layout in `Layout/`, reusable elements in `SingleElements/`.
- Scoped CSS goes in a matching `.razor.css` file alongside the component.
- Inject services via `@inject` in `.razor` files — Blazor components do not support constructor injection.
- Prefer `[Parameter]` for component inputs; avoid cascading parameters unless genuinely needed across deep trees.
### Component Locations
Shared components must live inside:
```text
Fixiy.Shared/Components/
```
Never create reusable components in:
```text
Fixiy.Maui
Fixiy.Web
```
### Structure
Pages:
```text
Fixiy.Shared/Components/Pages/
```
Layouts:
```text
Fixiy.Shared/Components/Layout/
```
Reusable elements:
```text
Fixiy.Shared/Components/SingleElements/
```
### Styling
* Scoped styles must use matching `.razor.css` files.
* Keep component-specific styling inside scoped CSS whenever possible.
### Dependency Injection
Use:
```razor
@inject IService Service
```
Do not attempt constructor injection in Razor components.
### Parameters
* Prefer `[Parameter]`.
* Avoid `CascadingParameter` unless truly necessary across multiple levels.
### Code Organization
* Keep `@code` blocks small.
* Extract complex logic into:
* `.razor.cs`
* Service classes
* ViewModels
---
## Render Mode Rules
- **Always use `InteractiveRenderSettings.*` properties** (`@InteractiveServer`, `@InteractiveAuto`, `@InteractiveWebAssembly`) in shared components — never hard-coded `RenderMode.*` constants.
- `Fixiy.Maui/MauiProgram.cs` calls `ConfigureBlazorHybridRenderModes()` which sets all three properties to `null`. This is intentional — MAUI Blazor Hybrid runs components statically.
- Do not work around the null render modes in shared code. Components that need interactivity must tolerate `null` render mode in MAUI context.
Always use:
```razor
@InteractiveServer
@InteractiveAuto
@InteractiveWebAssembly
```
through:
```csharp
InteractiveRenderSettings
```
Never use:
```csharp
RenderMode.Server
RenderMode.Auto
RenderMode.WebAssembly
```
directly.
### Important
`Fixiy.Maui/MauiProgram.cs` calls:
```csharp
ConfigureBlazorHybridRenderModes()
```
which intentionally sets render modes to `null`.
This is required for MAUI Blazor Hybrid.
Do not:
* Replace null render modes
* Add workarounds
* Introduce MAUI-specific render mode hacks
All shared components must tolerate null render modes.
---
## MAUI Blazor Hybrid Rules
* Navigation must remain compatible with iOS swipe-back gestures.
* Prefer native MAUI navigation for secondary pages.
* Use PushAsync for stack navigation.
* Do not introduce JavaScript solutions when a MAUI or Blazor solution exists.
* Shared components must work identically in:
* MAUI Hybrid
* ASP.NET Core Server
* WebAssembly
* Never introduce host-specific code into shared components.
---
## MVVM Guidelines
* Business logic must not live inside Razor pages.
* Complex state management belongs in services or ViewModels.
* UI components should focus on presentation.
* Keep ViewModels platform-independent.
* Avoid code duplication between ViewModels and services.
---
## IFormFactor Platform Abstraction
- Platform-specific device info must be accessed via `IFormFactor` injection (`Fixiy.Shared/Interfaces/IFormFactor.cs`).
- **Never call `DeviceInfo`, `Connectivity`, `FileSystem`, or any `Microsoft.Maui.*` API from `Fixiy.Shared`.**
- When adding new platform capabilities: define interface in `Fixiy.Shared/Interfaces/` → implement in both `Fixiy.Maui/Services/` and `Fixiy.Web/Services/` → register in both DI roots.
Platform-specific functionality must be accessed through:
```csharp
IFormFactor
```
located in:
```text
Fixiy.Shared/Interfaces/
```
### Forbidden in Shared
Never directly access:
```csharp
DeviceInfo
Connectivity
FileSystem
Permissions
Launcher
Preferences
SecureStorage
Microsoft.Maui.*
```
from:
```text
Fixiy.Shared
```
### Adding New Platform Features
Always follow this process:
1. Create interface in:
```text
Fixiy.Shared/Interfaces/
```
2. Implement in:
```text
Fixiy.Maui/Services/
```
3. Implement in:
```text
Fixiy.Web/Services/
```
4. Register in both DI roots.
Do not skip any step.
---
## Dependency Injection
### Service Registration
Always verify registrations in both hosts.
### Lifetimes
#### MAUI
Use:
```csharp
Singleton
```
for platform services.
#### Web
Use:
```csharp
Scoped
```
for platform services.
### Interfaces
Interfaces must not assume any specific lifetime.
### Injection
Prefer:
```csharp
IService
```
over concrete implementations.
Never inject a concrete type when an abstraction exists.
---
## IntegryApiClient Registration
- Register with the same `appToken` and `useLoginAzienda: true` in both hosts.
- MAUI: `.UseIntegry(appToken, useLoginAzienda: true)` on the `MauiAppBuilder` chain.
- Web: `builder.Services.UseIntegry(appToken, useLoginAzienda: true)` in `Program.cs`.
- One registration per DI root — do not call it twice.
Use the same configuration in both hosts.
## Service Registration Lifetimes
### MAUI
- `Fixiy.Maui` registers platform services as **`Singleton`** — the MAUI app has a single long-lived process.
- `Fixiy.Web` registers platform services as **`Scoped`** — ASP.NET Core server-side per-request scope.
- Interfaces must not assume a specific lifetime; implementations may.
```csharp
.UseIntegry(appToken, useLoginAzienda: true)
```
### Web
```csharp
builder.Services.UseIntegry(
appToken,
useLoginAzienda: true)
```
### Rules
* One registration per host.
* Never register twice.
* Always keep app tokens aligned.
* Always keep versions aligned.
---
## Data Access Guidelines
### Entity Framework
* Prefer async APIs.
* Use `AsNoTracking()` for read-only queries.
* Avoid loading entire tables into memory.
* Avoid N+1 query patterns.
* Prefer projections over loading full entities when possible.
### Performance
* Minimize allocations.
* Reuse existing services.
* Avoid unnecessary LINQ enumerations.
* Prefer server-side filtering.
---
## Error Handling
* Use exceptions only for exceptional situations.
* Validate inputs early.
* Log meaningful information.
* Never swallow exceptions silently.
* Preserve stack traces.
Do not write:
```csharp
catch (Exception)
{
}
```
---
## Maintenance Matrix
| Change | Cascades to |
|--------|-------------|
| Add/modify `Fixiy.Shared/Interfaces/*.cs` | Both `Fixiy.Maui/Services/` and `Fixiy.Web/Services/` implementations + DI registration in both hosts |
| Modify `InteractiveRenderSettings.cs` | `MauiProgram.ConfigureBlazorHybridRenderModes()` — must null every new property |
| Add a new shared page | `Fixiy.Shared/Components/Pages/` → nav link in `NavMenu.razor` if user-accessible |
| Add a NuGet package | Target `.csproj` file; check private NuGet feed has it |
| Change IntegryApiClient version | All three `.csproj` files (`Fixiy.Maui`, `Fixiy.Shared`, `Fixiy.Web`) |
| Modify `_Imports.razor` | Verify no MAUI-only or web-only namespaces are introduced |
| Update app token | `Fixiy.Maui/MauiProgram.cs` `AppToken` const + `Fixiy.Web/Program.cs` `appToken` const |
| Change | Cascades To |
| ----------------------------------------- | ----------------------------------------------------------------- |
| Add/modify `Fixiy.Shared/Interfaces/*.cs` | Update MAUI implementation + Web implementation + DI registration |
| Modify `InteractiveRenderSettings.cs` | Update `ConfigureBlazorHybridRenderModes()` |
| Add shared page | Add navigation entry if user accessible |
| Add shared service | Verify registration in both hosts |
| Add platform capability | Interface + MAUI implementation + Web implementation |
| Add NuGet package | Verify target project and feed availability |
| Change IntegryApiClient version | Update all project references |
| Modify `_Imports.razor` | Ensure no host-specific namespaces are introduced |
| Update app token | Update both hosts |
## Test Conventions
---
- No test projects are currently configured. When adding tests, use **xUnit** with **bUnit** for Razor component testing.
- Test projects should reference `Fixiy.Shared` and provide mock implementations of `IFormFactor`.
- Use `Moq` or `NSubstitute` for mocking; do not create manual stubs unless the interface is trivial.
## Testing Conventions
## Code Style Notes
Current solution has no dedicated test projects.
- Omit the `private` modifier on fields — it is the default in C#.
- Constants: `PascalCase` for class-level `const`, no Hungarian notation.
- One type per file; file name matches type name.
- Keep `@code` blocks in `.razor` files focused — extract complex logic to a `*.razor.cs` code-behind or a separate service class.
When adding tests:
### Frameworks
Use:
* xUnit
* bUnit
* Moq or NSubstitute
### Requirements
* Test projects should reference `Fixiy.Shared`.
* Mock `IFormFactor`.
* Avoid manual stubs unless interfaces are trivial.
---
## Code Review Checklist
Before completing a task verify:
* Existing patterns were followed.
* No duplicate services were created.
* No duplicate DTOs were created.
* No duplicate pages were created.
* No duplicate components were created.
* Shared code contains no MAUI-specific APIs.
* DI registrations are correct.
* Both hosts were updated when required.
* Nullable reference types remain enabled.
* Async APIs are used correctly.
* Render mode rules were respected.
* Navigation compatibility remains intact.
* No unnecessary files were added.
* No working code was rewritten unnecessarily.
* The solution architecture remains consistent.