# Conventions ## Naming - **Prefix:** All framework types use `Ac` prefix (e.g., `AcDalBase`, `AcBinarySerializer`, `AcLoggerBase`). - **Interfaces:** Standard `I` prefix + `Ac` (e.g., `IAcDbContextBase`, `IAcUserDbSetBase`). - **Extensions:** `{Domain}Extensions.cs` (e.g., `StringExtensions`, `CollectionExtensions`, `AcDbSessionExtension`). - **Test bases:** `Ac{Domain}TestBase` or `AcBase_{TestName}` for inherited test methods. ## Patterns - **Extension methods over instance methods** for CRUD operations. Keeps interfaces clean, implementations composable. - **Session/Transaction pattern** in DataLayers: `Session()` for reads, `Transaction()` for writes. Both are mutex-protected. - **Generic interface hierarchy** for entities: Interface → Abstract Entity → Concrete (in consuming project). - **Partial classes** for large serializers (AcBinarySerializer, AcToonSerializer split across 10+ files). - **Source generation** for hot-path serialization. Runtime reflection only as fallback. ## Serialization Conventions - Binary serializer properties are written in **alphabetical order** (matches source generator output). - String interning is opt-in via `[AcStringIntern]` attribute or `enableInternString` flag. - Chain API for multi-type deserialization with cross-reference resolution. - Feature flags on `[AcBinarySerializable]` eliminate dead code from generated output. ## SignalR Conventions See [`SIGNALR_ARCHITECTURE.md`](SIGNALR_ARCHITECTURE.md) for full architecture documentation. - **Single dispatch method** — all communication goes through `OnReceiveMessage(int messageTag, byte[] messageBytes, int? requestId)`. Do not add new hub methods. - **Tag-based routing** — associate methods with integer tags via `[SignalR(tag)]` (server) or `[SignalRSendToClient(tag)]` (client). Tags must be unique across the entire system. - **CRUD bundles** — entities use `SignalRCrudTags(baseTag)` which allocates 5 sequential tags (GetAll, GetItem, Add, Update, Remove). Reserve non-overlapping base tags. - **Binary protocol** — `AcBinaryHubProtocol` is the transport protocol. Responses use pure Binary serialization. ### ⚠️ Temporary: JSON-in-Binary Request Parameters Client→server request parameters currently use a JSON→Binary→JSON round-trip: 1. `SignalPostJsonDataMessage` serializes `PostData` to JSON string (`PostDataJson`) 2. The JSON-containing message is wrapped in a Binary envelope 3. Server deserializes Binary → extracts JSON string → parses JSON per parameter This is **planned for replacement** with direct Binary parameter serialization (matching how responses already work). Do not attempt to fix this as a side-effect of other work — it requires coordinated client+server+consuming-project changes. ## Testing - **MSTest** framework across all test projects. - **Abstract test bases** with `AcBase_` prefixed methods for reusable test logic. - **TestDataFactory** for centralized test data creation with ID sequencing. - **Testable infrastructure** for SignalR: `TestableSignalRClient2`, `TestableSignalRHub2` bypass real connections. ## Code Reuse - Before writing new code, search the codebase for existing implementations. - If a method does most of what you need, extract the shared part into a smaller reusable method rather than copying and modifying. - Prefer composing existing helpers over creating parallel implementations. - When adding a variation of existing logic, refactor the original into composable pieces that both call sites can use. ## Critical Rules - **Never modify PasswordHasher salt/iteration logic** — breaks existing password verification. - **Never renumber LogLevel enum values** — synchronized with database. - **Never fix "Finnished" spelling** — intentional legacy typo in consuming projects. - **Never suggest removal as a solution** — find a fix instead.