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

14 KiB

Mango.Nop Libraries — Domain Rules

🛑 AI AGENT CORE PROTOCOL (CRITICAL ENFORCEMENT)

You are operating in a multi-repo, documentation-first architecture. You MUST STRICTLY follow this protocol for every response. Failure to do so will break the workspace rules.

  1. MANDATORY OUTPUT PREFIX: Your response MUST begin on the very first line with this format: [LOADED_DOCS: N files (+K this turn: <comma-separated basenames>)]

    • N = total count of .md files currently in your context (across all loaded docs in this conversation)
    • K = count of .md files newly loaded during THIS response (may be 0)
    • If K > 0: list the newly loaded basenames only (no paths) after :
    • If K = 0: write [LOADED_DOCS: N files, no new loads]
    • If N = 0: write [LOADED_DOCS: NONE]

    Examples:

    • [LOADED_DOCS: NONE] — nothing loaded yet
    • [LOADED_DOCS: 1 files, no new loads] — only copilot-instructions.md loaded earlier, nothing new this turn
    • [LOADED_DOCS: 4 files (+3 this turn: LOGGING.md, LOGGING_ISSUES.md, LOGGING_TODO.md)] — 3 new this turn

    This prefix is MANDATORY on EVERY response (not just the first, not just when loading happens). It serves two purposes: (a) user-visible compliance signal, and (b) self-commitment for the no-re-read rule — in subsequent turns you read your own prior prefix from the conversation to enforce Rule #3. Dropping the prefix breaks both.

  2. HARD-GATE DELAY (DOCS BEFORE CODE) & TOOL EXECUTION BLOCK:

    • If [LOADED_DOCS: NONE] applies, you MUST STOP and you are STRICTLY FORBIDDEN to use the following tools: code_search, get_symbols_by_name, find_symbol, or get_file (for non-markdown files).
    • Your VERY FIRST AND ONLY allowed tool calls must be file_search or get_file targeting the .md documentation in the relevant docs/ folders or README.md.
    • Do not answer the user's core question until the [LOADED_DOCS] list is populated with the base architecture files.
    • CRITICAL EXCEPTION: Do NOT re-read .md files that are already mapped in your context or LOADED_DOCS list (strictly maintain rule 3).
    • CROSS-REPO HARD-GATE: When navigating to an external repo (via own-dep-repos paths), read that repo's docs/ and README.md BEFORE searching its source code. The hard-gate applies to EVERY repo you enter, not just your own.
    • PER-QUESTION DOC-FIRST: Before searching source code for any user question, check whether there is a relevant .md file (folder README.md, other repo docs/, etc.) that has NOT yet been loaded. Read it first — it tells you where to look in the code, saving searches and tokens. Only after loading relevant docs should you search/read source files.
  3. STRICT NO-RE-READ POLICY (ANTI-LOOP): You are PHYSICALLY FORBIDDEN from calling get_file or file_search on any .md file that is already listed in your [LOADED_DOCS] prefix.

    • Definition: A doc is "in your context" ONLY if you have read its actual file content via a tool call in THIS conversation. Prior session summaries, compacted messages, and memory entries do NOT count — they are lossy compressions.
    • Once an .md file is in your context, it STAYS in your context.
    • Re-reading them wastes tokens and breaks the protocol.
    • ONLY re-read an .md file if the user EXPLICITLY states "the file has changed on disk, read it again".
    • If the user simply mentions a glossary term or requests info found in a loaded doc, answer directly from memory. DO NOT search for it again.
  4. CONTEXT RECOVERY (SMART READ): If the user asks a domain/architecture specific question and you realize the essential .md files are NO LONGER in your current context (they dropped out of memory), you MUST automatically re-read the necessary documentation before answering. Do NOT wait for the user to explicitly tell you to re-read them. Prioritize scanning the docs/ folders to recover the lost context.

    Auto-detection triggers (MUST treat ALL docs as NOT loaded):

    • Session starts with a summary of a previous conversation (context recovery/compaction)
    • Message compaction or context compression occurred mid-session
    • You cannot quote the exact content of a doc you claim to know When any trigger fires → reset [LOADED_DOCS: NONE] and re-read per Rule #2.

    Directories to read (when recovering context):

    • docs/ (in this repository root)
  5. EXPLICIT CONSENT FOR MODIFICATIONS: NEVER rewrite, create, or delete any file (code, documentation, configuration, memory, or otherwise) without the user's explicit permission. If the user does not specifically request a code modification (e.g., using phrases like "we are just thinking," "what do you think," "let's plan"), you MUST ONLY provide text-based analysis and planning. You are FORBIDDEN from using file-modifying tools (replace_string_in_file, edit_file, create_file, etc.) until the user explicitly says "ok", "go ahead", "implement", or a similar unambiguous approval.

Workspace Dependencies

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.mddocs/ 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.

Shared Agent Skills

Skills defined in other repos that can be referenced from here:

  • protocol-audit — Cross-repo consistency audit for .github/copilot-instructions.md across all 5 repos. Location: AyCode.Core/.github/skills/protocol-audit/SKILL.md Activate from an AyCode.Core session, or read the SKILL.md directly and follow its steps.

  • docs-discovery — Load relevant .md documentation (main + _ISSUES + _TODO paired sets) BEFORE source-code search or modifications. Saves tokens vs. grep-based rediscovery. Location: AyCode.Core/.github/skills/docs-discovery/SKILL.md (see own-dep-repos above for the relative path to AyCode.Core) Invoke proactively before any domain-related coding task (see "Documentation-first coding" below). Honours the active repo's no-re-read rule.

Protocol History

Cumulative log of LLM-protocol decisions (rule changes, new skills, structural shifts):

  • AyCode.Core/.github/LLM_PROTOCOL_DECISIONS.md

Read this file when you need to understand why a rule is the way it is, or before proposing a protocol change — it may save a debate about something already resolved.

Documentation-first coding

Before running any source-code Grep / get_file / code_search in response to a domain-related request, invoke the docs-discovery skill (path above). Scans docs/ folders in THIS repo AND in referenced repos (via own-dep-repos) via Glob, loads paired .md sets as a unit. Rule-number-agnostic — refers to rule NAMES (no-re-read, folder-navigation, explicit-consent) which are stable across repos.

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

  1. BaseEntity (NopDependencies) = root entity base with int Id and IBaseEntity interface. All nopCommerce entities inherit from this. Namespace: Nop.Core.
  2. MgEntityBase = custom entity base that inherits BaseEntity and implements IEntityInt (from AyCode.Interfaces). Used for domain-specific entities and complex DTOs.
  3. 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.
  4. 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

  1. MgDbTableBase<TEntity> = repository base wrapping nopCommerce EntityRepository<TEntity>. Adds GetAll() (IQueryable<T>), automatic timestamp handling (ITimeStampCreated/ITimeStampModified), virtual CRUD hooks (OnInsert/OnUpdate/OnDelete).
  2. 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.
  3. 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

  1. 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).
  2. MgEventConsumerBase — subscribes to EntityUpdatedEvent<Product>, EntityInsertedEvent<Product>, CustomerRegisteredEvent, OrderPlacedEvent, PageRenderingEvent, ProductSearchEvent. Override relevant handlers. Built-in: CheckAndUpdateProductManageInventoryMethodToManageStock().
  3. NopLogWriter — AyCode → nopCommerce log bridge. Log level mapping: Detail/Trace/Debug/InfoInformation; Suggest/WarningWarning; ErrorError. Uses TransactionScope(Suppress) to avoid nesting.

Conventions

  1. Mg prefix for all custom types: MgEntityBase, MgOrderDto, MgDbTableBase, etc.
  2. No redundant code — before writing new logic, check whether similar methods already exist in the current context. Reuse or extract shared logic.
  3. Keep all .md documentation in sync (PASSIVE DETECTION & ASK FIRST) — If you notice any contradiction, error, or missing information between the code and your currently loaded .md files, briefly notify the user and ask for permission before making changes. Do NOT automatically update .md files or trigger new searches yet. Once the user approves, you may actively search, read, and update the necessary docs in the correct layer. Identify missing documentation: If you notice during your task that a frequently used pattern, underlying logic, or important behavior is missing from the docs, and adding it would improve future LLM context-efficiency (saving searches/tokens), briefly notify the user to get approval. Topic-based separation: When creating or expanding documentation, keep logically distinct features or domains in separate .md files (e.g., architecture, data model, billing) and only reference them in the main/index documents. Do not cram everything into a single monolithic file. Keep in mind: these .md files are primarily for LLM grounding and context providing. Keep them concise, structured, and focused on rules/patterns rather than human-readable prose. ENFORCEMENT: At the end of EVERY code-modifying response, append a [DOCUMENTATION CHECK] section. Evaluate ONLY the .md files already in your context. State in 1-2 sentences if you found discrepancies or missing concepts, and ask if they should be documented. DO NOT trigger searches or tool calls for this initial check.
  4. 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.
  5. 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.
  6. Folder navigation — start from the root README.md for solution-level navigation. When you need to understand a folder's contents or find a type/class, read the README.md in that folder first — it indexes the local files and sub-folders. Follow this before grepping or reading source files.
  7. 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.
  8. LinqToDB associations — use [Association(ThisKey = nameof(FK), OtherKey = nameof(Target.Id), CanBeNull = true/false)] for navigation properties in DTOs.
  9. 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.