# 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.