# 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 * Use C# 12+. * Always keep: ```xml enable enable ``` * 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 ### 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: ```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 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 Use the same configuration in both hosts. ### MAUI ```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` | 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 | --- ## Testing Conventions Current solution has no dedicated test projects. 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.