Mango.Nop.Libraries/.github/copilot-instructions.md

52 lines
6.4 KiB
Markdown

# Mango.Nop Libraries — Domain Rules
# own-dep-repos: "name: path" — paths are relative to this repo root (.github/..)
@repo {
name = "Mango.Nop Libraries"
type = "framework"
layer = 1
own-dep-repos = ["AyCode.Core: ../../../../../Aycode/Source/AyCode.Core"]
}
> This is the **single source of truth** for Mango.Nop library rules. Do not duplicate these elsewhere.
> For detailed docs see: `README.md` → `docs/`
> For core framework rules see: `.github/copilot-instructions.md` (in AyCode.Core repo)
> External repos in `own-dep-repos` are fully accessible — read their source code, docs, and `.github/copilot-instructions.md` freely when you need type definitions, base classes, or context. Do not limit yourself to the current workspace.
## nopCommerce Compatibility
1. All three libraries target **net9.0** — required by nopCommerce 4.80.9. Do NOT change TFM.
2. **NopDependencies** folder in `Mango.Nop.Core` contains **mirror copies** of nopCommerce entity classes (`BaseEntity`, `Customer`, `Order`, `Product`, `GenericAttribute`, etc.) so that `Mango.Nop.Core` can be referenced without the full nopCommerce dependency chain.
3. Do NOT modify files in `NopDependencies/` unless the nopCommerce version changes.
## Entity & DTO Patterns
4. **`BaseEntity`** (NopDependencies) = root entity base with `int Id` and `IBaseEntity` interface. All nopCommerce entities inherit from this. Namespace: `Nop.Core`.
5. **`MgEntityBase`** = custom entity base that inherits `BaseEntity` and implements `IEntityInt` (from AyCode.Interfaces). Used for domain-specific entities and complex DTOs.
6. **Two DTO base strategies exist:**
- `ModelDtoBase<TMainEntity>` — for simple DTOs (e.g. `CustomerDto`). Manual `CopyEntityValuesToDto`/`CopyDtoValuesToEntity` overrides. Uses `Activator.CreateInstance<T>()` in `CreateMainEntity()`.
- `MgEntityBase` + `IModelDtoBase<T>` — for complex DTOs with LinqToDB `[Association]` navigations (e.g. `MgOrderDto`, `MgOrderItemDto`). Uses `PropertyHelper.CopyPublicValueTypeProperties()` for automatic value-type copy.
7. **`GenericAttribute`** = polymorphic key-value store. `KeyGroup` = owner type name, `EntityId` = owner ID, `Key` = attribute name, `Value` = string value. Use `GenericAttributeExtensions.GetValueOrNull<T>()`/`GetValueOrDefault<T>()`/`TryGetValue<T>()` — never parse raw strings manually.
## Data Access Patterns
8. **`MgDbTableBase<TEntity>`** = repository base wrapping nopCommerce `EntityRepository<TEntity>`. Adds `GetAll()` (`IQueryable<T>`), automatic timestamp handling (`ITimeStampCreated`/`ITimeStampModified`), virtual CRUD hooks (`OnInsert`/`OnUpdate`/`OnDelete`).
9. **`MgDtoDbTableBase<TDtoEntity, TMainEntity>`** = DTO-aware repository. **CRITICAL: All Delete methods throw — always use `DeleteMainEntityById(int id)`.** Event bridging: DTO insert/update events → main entity events.
10. **`MgDbContextBase`** = DB context base (NOT EF Core DbContext — wraps `INopDataProvider` and `IRepository<T>` nopCommerce repos). Provides `Transaction`/`TransactionSafe`/`TransactionAsync`/`TransactionSafeAsync`. TransactionSafe variants use global `SemaphoreSlim` lock for serialized access.
## Service Patterns
11. **`MgBackgroundServiceBase`** — inherits `Microsoft.Extensions.Hosting.BackgroundService`. Loop: `Task.Delay(interval)``OnExecuteAsync()`. Pause support. Per-iteration exception handling. **Uses nopCommerce `Nop.Services.Logging.ILogger`** (not Mango logger).
12. **`MgEventConsumerBase`** — subscribes to `EntityUpdatedEvent<Product>`, `EntityInsertedEvent<Product>`, `CustomerRegisteredEvent`, `OrderPlacedEvent`, `PageRenderingEvent`, `ProductSearchEvent`. Override relevant handlers. Built-in: `CheckAndUpdateProductManageInventoryMethodToManageStock()`.
13. **`NopLogWriter`** — AyCode → nopCommerce log bridge. Log level mapping: `Detail/Trace/Debug/Info``Information`; `Suggest/Warning``Warning`; `Error``Error`. Uses `TransactionScope(Suppress)` to avoid nesting.
## Conventions
14. **`Mg` prefix** for all custom types: `MgEntityBase`, `MgOrderDto`, `MgDbTableBase`, etc.
15. **No redundant code** — before writing new logic, check whether similar methods already exist in the current context. Reuse or extract shared logic.
16. **Keep all .md files in sync** — when you modify code and you know which .md file documents it, update that .md file too. If you notice a contradiction between code and an .md file, automatically update the .md to match the code (code is the source of truth). When fixing a reference, check other .md files that may share the same broken reference. If the root cause is at a lower layer, fix it there first. During code review, if you find useful behavior or conventions not yet documented, briefly suggest what to document and where — but do not add new content without approval.
17. All AyCode references are via **DLL** (not ProjectReference) — this is intentional. **AyCode.Core** solution (`../../../../../Aycode/Source/AyCode.Core/`) contains all core framework code: interfaces, serialization, binary protocol, SignalR base classes, data sources, logging. Types not defined in this library (e.g. `IEntityInt`, `IId<T>`, `AcConst`, `ToonDescription`) likely live in AyCode.Core.
18. **Do not re-read .md files** already in your context window. They only change if you modify them yourself (new content is already in context) or if the developer tells you they changed — in that case re-read them once.
18. **Documentation layering** — write `.md` documentation at the **defining layer** (where the code lives). Higher-layer `.md` files reference AyCode.Core base docs using the form `../../../../../Aycode/Source/AyCode.Core/{Project}/docs/FILENAME.md`. Document only project-specific overrides or extensions. Never duplicate base-layer descriptions in consumer-level docs.
19. **LinqToDB associations** — use `[Association(ThisKey = nameof(FK), OtherKey = nameof(Target.Id), CanBeNull = true/false)]` for navigation properties in DTOs.
20. **Timestamp auto-management** — entities with `ITimeStampCreated` or `ITimeStampModified` get automatic UTC timestamps in `MgDbTableBase` CRUD hooks. Don't set these manually.
## Reference Modes
- **Full stack** (ProjectReference, all 3 libraries) — for nopCommerce plugins needing entity access, data layer, and services.
- **Types only** (DLL reference, `Mango.Nop.Core` only) — for projects that only need DTOs, entities, and interfaces without the nopCommerce runtime dependency.