# GitHub Copilot Instructions — Fixiy ## Language and Style - **C# 12+** with `enable` and `enable` 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. ## 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. ## 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. ## 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. ## 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. ## Service Registration Lifetimes - `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. ## 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 | ## 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. ## Code Style Notes - 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.