# LS1010: Repository Exposes a Query Surface

## Intent

LS1010 is a compiler check that reports a repository interface in Domain, the project that holds business rules, that exposes a query surface such as `IQueryable` or a database session. A repository loads and stores one aggregate, and a query surface would let any caller compose its own queries around the rules the aggregate protects. This page states what the rule reports, where the warning sits, and how to return business records and Domain types only.

## Reference

### What the rule enforces

LS1010 enforces [Keep repository interfaces in Domain](https://litespec.dev/2.0.0/backend/dotnet/domain.md#keep-repository-interfaces-in-domain) (`litespec/backend/dotnet/domain#keep-repository-interfaces-in-domain`). It runs in Domain only. Its category is `LiteSpec.Domain`. It reports a warning and is enabled by default, as the [Analyzers overview](https://litespec.dev/2.0.0/analyzers/README.md) describes.

### What the rule reports

The rule reports an interface whose name ends in `Repository` when it is generic over a type parameter its members use, or when a member exposes `IQueryable`, a type derived from it, a member type whose name ends in `Session`, `DbContext`, or `DbSet`, or an `Expression<Func<...>>` parameter. The diagnostic sits on the interface name for a generic surface. For any other breach it sits on the offending member type.

### Failing example

```csharp
public interface IOrderRepository
{
    IQueryable<Order> Query();
}
```

### Passing example

```csharp
public interface IOrderRepository
{
    Task<Order?> FindAsync(OrderId id, CancellationToken cancellationToken);
}
```

### How to fix

Return aggregates and Domain types only from the repository, and move query composition to a query handler that reads through `IQuerySession`.

## Notes

### What the rule ignores

The rule does not report interfaces whose names do not end in `Repository`, or members that return aggregates and Domain types such as `Task<Order?> FindAsync(OrderId id, CancellationToken cancellationToken)`. It does not run outside Domain.
