03 fragilities

The directory structure is acceptable, but file placement guarantees nothing about runtime performance. I am seeing the skeleton of a modular monolith, but I need to ensure the muscle memory—the Masala Lite doctrine—is actually binding these components together.

Here is my architectural critique of this layout and the specific implementation guardrails you must enforce immediately. 1. The "Legacy" Risk (src/TicketMasala.Web/Services/)

Critique: You note this is a "Legacy services directory." In a high-performance monolith, "legacy" folders are where performance goes to die. They usually contain Service classes that are dangerously stateful or perform blocking I/O.

Directive: Do not allow new code here.

Audit: Any service remaining here must be stateless. If a service here is holding a List<T> or a raw Dictionary, it is a memory leak waiting for a traffic spike. Move strictly to Engine/ or Repositories/.
  1. The Compilation Core (src/TicketMasala.Web/Engine/Compiler/)

This is the most critical folder in the application. If this contains code that parses YAML strings inside a foreach loop, we have failed. Shutterstock

Explore

The Requirement: This directory must contain an Expression Tree Builder.

    Input: masala_gerda.yaml (Rules).

    Output: Func<WorkItem, float> (Compiled Delegates).

The Guardrail: When the application starts, the Compiler services must convert all YAML rules into compiled .NET delegates.

    Bad: EvaluateRule(ticket, ruleString) (Runtime Interpretation).

    Good: _compiledRules[ruleId](ticket) (Native execution speed).
  1. Ingestion & Threading (src/TicketMasala.Web/Engine/Ingestion/)

I see Background/. This implies hosted services.

The Trap: Do not use Task.Run or raw Thread spawning here.

The Standard: This must house the Channel Consumer.

    Gatekeeper (API Controller): Writes to ChannelWriter<WorkItem>.

    Worker (Background Service): Reads from ChannelReader<WorkItem>.

Latency Check: Ensure your BoundedChannelOptions are configured correctly to apply backpressure to the API if the consumers fall behind. Do not let the channel grow infinitely.
  1. Data Layer Pragmatism (src/TicketMasala.Web/Data/)

You are using SQLite. The directory structure hides the complexity of how you are treating JSON.

Mandatory Configuration:

    WAL Mode: Ensure your DbContext configuration explicitly sets PRAGMA journal_mode=WAL; on connection open.

    Generated Columns: The WorkItem entity likely has a Payload (JSON) property. You must map high-traffic fields (like Status or Priority) to Generated Columns in the SQLite table so they can be indexed.

    Rejection: If I see a LINQ query performing EF.Functions.JsonExtract in a Where clause for a high-frequency query, I will block the PR. It must query the generated column.

Visualization: The Compilation Pipeline

To clarify the "Compile, Don't Interpret" mandate for the Engine/Compiler/ directory, adhere to this flow: Code snippet

sequenceDiagram participant Config as masala_gerda.yaml participant Compiler as RuleCompilerService participant Cache as CompiledRuleCache (Singleton) participant Worker as GERDA Worker

Note over Compiler: Application Startup
Config->>Compiler: Load Raw YAML
Compiler->>Compiler: Parse AST
Compiler->>Compiler: Build Expression Trees (Expression.Lambda)
Compiler->>Compiler: Compile to Func<T, bool>
Compiler->>Cache: Store Delegate in Dictionary

Note over Worker: Runtime (High Frequency)
Worker->>Cache: GetRule(RuleID)
Cache-->>Worker: Return Func delegate
Worker->>Worker: Execute Delegate(WorkItem)
Note right of Worker: Zero allocation, < 1ms execution

Immediate Next Step

The structure is shell; code is intent. I need to verify you aren't building a slow interpreter in the Compiler folder.

Would you like me to generate the skeleton code for RuleCompilerService.cs using .NET Expression Trees to demonstrate how to compile a YAML rule (e.g., priority > 10) into a native delegate?