diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 11552aad..c4b0fbb1 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,6 +2,9 @@ > This is the **single source of truth** for domain rules. Do not duplicate these elsewhere. > For detailed docs see: `README.md` → `docs/` +> For core framework rules see: `../../../Aycode/Source/AyCode.Core/.github/copilot-instructions.md` +> For UI framework rules see: `../../../Aycode/Source/AyCode.Blazor/.github/copilot-instructions.md` +> For nopCommerce library rules see: `../NopCommerce.Common/4.70/Libraries/.github/copilot-instructions.md` ## Business Domain 1. **FruitBank** = fruit & vegetable wholesaler. This is a **nopCommerce plugin** — Customer, Order, Product, GenericAttribute are nopCommerce entities. @@ -27,3 +30,8 @@ 12. All AyCode references are via **DLL** (not ProjectReference) — this is intentional. nopCommerce 4.80.9 requirement. 13. **No redundant code** — before writing new logic, search for existing methods. Reuse or extract shared logic into smaller methods rather than duplicating. 14. **Keep all .md files in sync** — when you modify code, update any affected .md file (README.md, docs/, GLOSSARY, ARCHITECTURE, CONVENTIONS, SCHEMA, etc.). If you notice any .md content does not match the current code, fix it automatically. +15. **MgGridBase** (AyCode.Blazor) is the canonical grid base for all data screens. New grids inherit `FruitBankGridBase`, set CRUD tags in the constructor, and use `MgGridWithInfoPanel` for layout. See `AyCode.Blazor/docs/MGGRID.md` for the full technical reference. Do NOT create parallel grid base classes. +16. **AyCode.Core** solution (`../../../Aycode/Source/AyCode.Core/`) contains all core framework code: SignalR base classes, serialization, binary protocol, data sources, logging. When a type is referenced but not defined in this solution, look it up in AyCode.Core source and docs. +17. **AyCode.Blazor** solution (`../../../Aycode/Source/AyCode.Blazor/`) contains all UI framework code: MgGridBase, MgGridWithInfoPanel, toolbar, layout persistence, Blazor component infrastructure. When a UI base class or component is not found here, look it up in AyCode.Blazor source and docs. +18. **Mango.Nop Libraries** (`../NopCommerce.Common/4.70/Libraries/`) — independent shared library with its own `.github/copilot-instructions.md` and `docs/`. Contains DTOs, entities, data access, and service base classes. When a DTO or entity base class is not found in this solution, look it up in the Libraries source and docs. +19. **FruitBank nopCommerce Plugin** (`../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/`) is the server-side plugin running inside nopCommerce 4.80.9. Contains SignalR hubs/endpoints, measurement services, data access (DbTable classes), admin controllers, and AI services. When a server-side endpoint or service is referenced, look it up here. diff --git a/CLAUDE.md b/CLAUDE.md index e6d5c9f5..c40404e6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,6 +6,27 @@ Before writing any code, read these files: 3. `docs/SCHEMA.md` — Full domain model in Toon format 4. The relevant project's `README.md` for folder-specific context -This solution depends on **AyCode.Core** and **AyCode.Blazor** frameworks. +## External Repos + +This solution depends on external code in sibling directories. Their **full source code** is available — browse them freely for type definitions, base classes, patterns, and docs: + +| Repo | Path (relative to this repo root) | Contains | +|---|---|---| +| **AyCode.Core** | `../../../Aycode/Source/AyCode.Core/` | SignalR base classes, serialization, binary protocol, data sources, logging | +| **AyCode.Blazor** | `../../../Aycode/Source/AyCode.Blazor/` | MgGridBase, MgGridWithInfoPanel, toolbar, layout persistence, Blazor components | +| **Mango.Nop Libraries** | `../NopCommerce.Common/4.70/Libraries/` | Independent shared library with own `.github/copilot-instructions.md` and `docs/`. DTOs, entities, data access, service base classes | +| **FruitBank Plugin** | `../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/` | nopCommerce 4.80.9 server-side plugin: SignalR hubs, measurement services, DbTable classes, admin controllers, AI services | + +Key docs in those repos: +- `../../../Aycode/Source/AyCode.Core/.github/copilot-instructions.md` — core framework rules +- `../../../Aycode/Source/AyCode.Core/docs/ARCHITECTURE.md` — core architecture +- `../../../Aycode/Source/AyCode.Blazor/.github/copilot-instructions.md` — UI framework rules +- `../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md` — MgGrid technical reference +- `../../../Aycode/Source/AyCode.Blazor/docs/ARCHITECTURE.md` — UI architecture +- `../NopCommerce.Common/4.70/Libraries/.github/copilot-instructions.md` — Mango.Nop library rules +- `../NopCommerce.Common/4.70/Libraries/docs/ARCHITECTURE.md` — library architecture + NopDependencies pattern +- `../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/README.md` — FruitBank plugin overview + +When a type is referenced but not defined in this solution, look it up in AyCode.Core, AyCode.Blazor, or the Mango.Nop Libraries. When a server-side endpoint or service is referenced, look it up in the FruitBank Plugin. When modifying code, update the corresponding README.md if it becomes out of sync with the code. diff --git a/README.md b/README.md index a9d46a2f..6e9ae6b4 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,14 @@ Detailed docs: [`docs/`](docs/) — GLOSSARY.md, ARCHITECTURE.md, CONVENTIONS.md | Project | TFM | Purpose | README | |---|---|---|---| | [`FruitBankHybrid.Shared.Tests`](FruitBankHybrid.Shared.Tests/README.md) | net10.0 | Integration + serialization tests (SignalR, JSON, Toon, bunit) | [README](FruitBankHybrid.Shared.Tests/README.md) | + +### External Dependencies + +All projects reference these via **DLL** (not ProjectReference). Full source is available in sibling directories: + +| Repo | Path | Key Docs | +|---|---|---| +| **AyCode.Core** (net9.0) | `../../../Aycode/Source/AyCode.Core/` | [copilot-instructions](../../../Aycode/Source/AyCode.Core/.github/copilot-instructions.md), [ARCHITECTURE](../../../Aycode/Source/AyCode.Core/docs/ARCHITECTURE.md) | +| **AyCode.Blazor** (net10.0) | `../../../Aycode/Source/AyCode.Blazor/` | [copilot-instructions](../../../Aycode/Source/AyCode.Blazor/.github/copilot-instructions.md), [MGGRID](../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md) | +| **Mango.Nop Libraries** (net9.0) | `../NopCommerce.Common/4.70/Libraries/` | [copilot-instructions](../NopCommerce.Common/4.70/Libraries/.github/copilot-instructions.md), [ARCHITECTURE](../NopCommerce.Common/4.70/Libraries/docs/ARCHITECTURE.md) | +| **FruitBank Plugin** (net9.0) | `../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/` | [README](../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/README.md) | diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index d6237b3f..6a7ba11e 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -17,6 +17,12 @@ FruitBankHybrid FruitBankHybrid.Web FruitBankHybrid.Web.Client All projects also reference **AyCode.Core** (net9.0) and **AyCode.Blazor** (net10.0) via DLL references (not ProjectReference). +> **Context:** When a type or base class is not found in this solution, browse the external repos: +> - **AyCode.Core**: `../../../Aycode/Source/AyCode.Core/` — SignalR, serialization, binary protocol, data sources +> - **AyCode.Blazor**: `../../../Aycode/Source/AyCode.Blazor/` — MgGridBase, UI components, layout persistence +> - **Mango.Nop Libraries**: `../NopCommerce.Common/4.70/Libraries/` — independent library with own [copilot-instructions](../NopCommerce.Common/4.70/Libraries/.github/copilot-instructions.md) and [docs/](../NopCommerce.Common/4.70/Libraries/docs/) +> - **FruitBank Plugin**: `../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/` — server-side SignalR hubs, measurement services, DbTable classes + ## Target Frameworks nopCommerce 4.80.9 requires .NET 9 @@ -59,11 +65,84 @@ User → DevExpress Grid → AcSignalRDataSource → SignalR (AcBinary) → DevA nopCommerce Database ``` +## MgGrid — Grid System + +All data screens use **MgGridBase** from AyCode.Blazor (see [AyCode.Blazor/docs/MGGRID.md](../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md) for full technical docs). + +### FruitBank Grid Hierarchy + +``` +MgGridBase (AyCode.Blazor) + └── FruitBankGridBase (FruitBankHybrid.Shared) + ├── GridShippingBase → Shipping + ├── GridShippingDocumentBase → ShippingDocument (detail of Shipping) + ├── GridPartnerBase → Partner + ├── GridGenericAttributeBase → GenericAttributeDto + └── GridStockTakingItemBase → StockTakingItem +``` + +### FruitBankGridBase + +Project-level adapter that fixes 3 of 4 generic parameters: + +```csharp +public class FruitBankGridBase + : MgGridBase, TDataItem, int, LoggerClient> +``` + +Adds FruitBank-specific defaults: +- `GetLayoutUserId()` → `LoggedInModel.CustomerDto?.Id ?? 0` (per-user layout) +- Master grid: filter row, group panel, search box, `PageSize=20`, `EditMode=EditRow` +- Detail grid: no filter/group/search, `PageSize=10` +- Alternating row style (`.alt-item`), header background (`#E6E6E6`) +- Detail rows hidden for non-admin users (`hideDetailButton` CSS) + +### SignalR Tag Mapping + +Each concrete grid sets CRUD tags in its constructor: + +```csharp +public GridShippingBase() +{ + GetAllMessageTag = SignalRTags.GetShippings; // e.g. 300 + AddMessageTag = SignalRTags.AddShipping; // e.g. 302 + UpdateMessageTag = SignalRTags.UpdateShipping; // e.g. 303 +} +``` + +Tags are defined in `FruitBank.Common/SignalRs/SignalRTags.cs` with numeric ranges per domain area. + +### Grid Usage Pattern (Razor) + +```razor + + + + + + + ... + + + @{ var shipping = (Shipping)context.DataItem; } + + + + + +``` + ## Key Architectural Decisions - **nopCommerce plugin** — Customer, Order, Product are nopCommerce entities extended via GenericAttributes and DTOs - **SignalR over REST** — all data flows through SignalR with AcBinary protocol - **DevExpress Blazor 25.1.3** — exclusive UI component library +- **MgGridBase** — canonical grid base from AyCode.Blazor for all data screens (SignalR CRUD, layout persistence, master-detail) - **Three measurement hierarchies** — Shipping/Order/StockTaking share same base but have different audit rules - **Client-side database** — `DatabaseClient` caches entities in ConcurrentDictionary for offline/fast access - **Platform-specific credential storage** — MAUI uses SecureStorage, Web uses obfuscated localStorage, Server uses no-op diff --git a/docs/CONVENTIONS.md b/docs/CONVENTIONS.md index c91ee220..0f7a1781 100644 --- a/docs/CONVENTIONS.md +++ b/docs/CONVENTIONS.md @@ -1,11 +1,17 @@ # Conventions +> For core framework conventions see: `../../../Aycode/Source/AyCode.Core/docs/CONVENTIONS.md` +> For UI framework conventions see: `../../../Aycode/Source/AyCode.Blazor/docs/CONVENTIONS.md` + ## Naming - **fb prefix** on database tables: `fbPallet`, `fbShipping`, `fbShippingItem`, etc. - **Dto suffix** for DTOs wrapping nopCommerce entities: `OrderDto`, `OrderItemDto`, `ProductDto`. - **XxxItemPallet** for measurement records: `ShippingItemPallet`, `OrderItemPallet`, `StockTakingItemPallet`. - **Grid prefix** for Blazor grid components: `GridPartnerBase`, `GridShippingBase`, etc. +- **GridXxxBase** = C# code-behind class inheriting `FruitBankGridBase`. +- **GridXxx.razor** = Razor markup using `` with `` and ``. +- **OnGrid prefix** for MgGridBase event parameters: `OnGridItemDeleting`, `OnGridEditModelSaving`, `OnGridFocusedRowChanged`, etc. (avoids collision with DxGrid base events). - **SignalRTags** constants use numeric ranges by domain (see `FruitBank.Common/SignalRs/`). ## Patterns @@ -14,10 +20,27 @@ - **GenericAttributes** for extending nopCommerce entities with custom data (IsMeasurable, Tare, AverageWeight). - **Composition interfaces** for measurement traits: IMeasuringValues = IMeasuringWeights + IMeasuringQuantity. - **DevExpress DxGrid** with `AcSignalRDataSource` for real-time grid data. -- **MgGridBase** for grid layout persistence via localStorage. +- **MgGridBase** — canonical grid base from AyCode.Blazor (see [MGGRID.md](../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md)). Provides SignalR CRUD, layout persistence, master-detail, InfoPanel, fullscreen. +- **FruitBankGridBase** — project adapter that fixes `TId=int`, `TLoggerClient=LoggerClient`, adds per-user layout and master/detail defaults. - **FruitBankSignalRClient** as single hub client for all server communication. - **DatabaseClient** for client-side caching with ConcurrentDictionary tables. +### Grid Creation Checklist + +1. Create `GridXxxBase.cs` inheriting `FruitBankGridBase`. +2. Set CRUD tags in constructor: `GetAllMessageTag`, `AddMessageTag`, `UpdateMessageTag`, `RemoveMessageTag`. +3. Create `GridXxx.razor` with ``, ``, optional ``. +4. Wrap in `` if InfoPanel is needed. +5. For detail grids: set `ParentDataItem`, `KeyFieldNameToParentId`, `ContextIds`. + +### Grid Layout Storage Keys + +``` +{AutoSaveLayoutName}_{Master|ParentTypeName}_{AutoSave|UserSave}_{UserId} +``` + +Example: `GridShipping_Master_AutoSave_42` — auto-saved layout for shipping master grid, user #42. + ## Code Reuse - Before writing new code, search the codebase for existing implementations. diff --git a/docs/GLOSSARY.md b/docs/GLOSSARY.md index bb8b2981..2505f027 100644 --- a/docs/GLOSSARY.md +++ b/docs/GLOSSARY.md @@ -1,5 +1,8 @@ # Glossary / Fogalomtár +> For core framework glossary see: `../../../Aycode/Source/AyCode.Core/docs/GLOSSARY.md` +> For UI framework glossary see: `../../../Aycode/Source/AyCode.Blazor/docs/GLOSSARY.md` + Domain terminology for the FruitBank system. **Read this before making changes.** ## Business Domain @@ -58,3 +61,19 @@ FruitBank extends them via: | IsMeasurable=false means no Pallet | ❌ Pallet is always created, weights just = 0.0 | | NetWeight is stored | ❌ It's calculated: GrossWeight − PalletWeight − (TrayQuantity × TareWeight) | | GenericAttribute is simple | ❌ It's polymorphic: KeyGroup determines which entity type owns the record | + +## UI / Grid Components + +| Term | Definition | +|---|---| +| **MgGridBase** | Abstract generic grid component from AyCode.Blazor. Extends DevExpress `DxGrid` with SignalR CRUD, layout persistence, master-detail, InfoPanel. See [AyCode.Blazor/docs/MGGRID.md](../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md). | +| **FruitBankGridBase** | Project-level adapter: fixes `TSignalRDataSource=SignalRDataSourceObservable`, `TId=int`, `TLoggerClient=LoggerClient`. Adds per-user layout, master/detail defaults. | +| **MgGridWithInfoPanel** | `DxSplitter` wrapper: grid (left pane) + InfoPanel (right pane), fullscreen overlay, splitter size persistence. | +| **MgGridToolbarBase** | `DxToolbar` base with `Grid` (IMgGridBase) reference and `RefreshClick` callback. | +| **MgGridDataColumn** | Extended `DxGridDataColumn` with URL template support (`{PropertyName}` placeholders in links). | +| **MgGridInfoPanel** | Default InfoPanel showing column-value pairs for the focused row, supports edit mode. | +| **IMgGridBase** | Public interface for grid: `IsSyncing`, `GridEditState`, `ParentGrid`, `StepPrevRow/NextRow`, layout persistence methods. | +| **MgGridEditState** | Enum: `None` (no edit), `New` (adding item), `Edit` (modifying item). | +| **AutoSaveLayoutName** | Base name for localStorage layout keys. Default: `"Grid{TDataItem.Name}"`. | +| **SignalRCrudTags** | Bundle of 5 integer message tags (GetAll, GetItem, Add, Update, Remove) for one entity type. | +| **IsMasterGrid** | `true` when `ParentDataItem == null` — the grid is a top-level (not detail) grid. |