@@ -32,7 +32,7 @@ public EndpointRepository(WebhookDbContext dbContext)
3232 . FirstOrDefaultAsync ( e => e . AppId == appId && e . Id == id , ct ) ;
3333 }
3434
35- public async Task < List < Endpoint > > ListByAppIdAsync (
35+ public async Task < List < EndpointListItem > > ListByAppIdAsync (
3636 Guid appId ,
3737 EndpointStatus ? status ,
3838 int page ,
@@ -41,8 +41,6 @@ public async Task<List<Endpoint>> ListByAppIdAsync(
4141 {
4242 var query = _dbContext . Endpoints
4343 . AsNoTracking ( )
44- . Include ( e => e . Health )
45- . Include ( e => e . EventTypes )
4644 . Where ( e => e . AppId == appId )
4745 . AsQueryable ( ) ;
4846
@@ -52,6 +50,23 @@ public async Task<List<Endpoint>> ListByAppIdAsync(
5250 }
5351
5452 return await query
53+ . Select ( e => new EndpointListItem
54+ {
55+ Id = e . Id ,
56+ AppId = e . AppId ,
57+ AppName = e . Application != null ? e . Application . Name : null ,
58+ Url = e . Url ,
59+ Description = e . Description ,
60+ Status = e . Status ,
61+ CircuitState = e . Health != null ? e . Health . CircuitState . ToString ( ) : null ,
62+ CustomHeadersJson = e . CustomHeadersJson ,
63+ SecretOverride = e . SecretOverride ,
64+ MetadataJson = e . MetadataJson ,
65+ EventTypeNames = e . EventTypes . Select ( et => et . Name ) . ToList ( ) ,
66+ EventTypeIds = e . EventTypes . Select ( et => et . Id ) . ToList ( ) ,
67+ CreatedAt = e . CreatedAt ,
68+ UpdatedAt = e . UpdatedAt
69+ } )
5570 . OrderByDescending ( e => e . CreatedAt )
5671 . Skip ( ( page - 1 ) * pageSize )
5772 . Take ( pageSize )
@@ -110,9 +125,10 @@ await _dbContext.Endpoints
110125 }
111126
112127 /// <summary>
113- /// Cross-app list for dashboard admin — returns endpoints across all applications.
128+ /// Cross-app list for dashboard admin — returns endpoints across all applications
129+ /// using Select projection to avoid N+1 on EventTypes.
114130 /// </summary>
115- public async Task < List < Endpoint > > ListAllAsync (
131+ public async Task < List < EndpointListItem > > ListAllAsync (
116132 Guid ? appId ,
117133 EndpointStatus ? status ,
118134 int page ,
@@ -121,9 +137,6 @@ public async Task<List<Endpoint>> ListAllAsync(
121137 {
122138 var query = _dbContext . Endpoints
123139 . AsNoTracking ( )
124- . Include ( e => e . Application )
125- . Include ( e => e . Health )
126- . Include ( e => e . EventTypes )
127140 . AsQueryable ( ) ;
128141
129142 if ( appId . HasValue )
@@ -133,6 +146,23 @@ public async Task<List<Endpoint>> ListAllAsync(
133146 query = query . Where ( e => e . Status == status . Value ) ;
134147
135148 return await query
149+ . Select ( e => new EndpointListItem
150+ {
151+ Id = e . Id ,
152+ AppId = e . AppId ,
153+ AppName = e . Application != null ? e . Application . Name : null ,
154+ Url = e . Url ,
155+ Description = e . Description ,
156+ Status = e . Status ,
157+ CircuitState = e . Health != null ? e . Health . CircuitState . ToString ( ) : null ,
158+ CustomHeadersJson = e . CustomHeadersJson ,
159+ SecretOverride = e . SecretOverride ,
160+ MetadataJson = e . MetadataJson ,
161+ EventTypeNames = e . EventTypes . Select ( et => et . Name ) . ToList ( ) ,
162+ EventTypeIds = e . EventTypes . Select ( et => et . Id ) . ToList ( ) ,
163+ CreatedAt = e . CreatedAt ,
164+ UpdatedAt = e . UpdatedAt
165+ } )
136166 . OrderByDescending ( e => e . CreatedAt )
137167 . Skip ( ( page - 1 ) * pageSize )
138168 . Take ( pageSize )
@@ -152,3 +182,21 @@ public async Task<int> CountAllAsync(Guid? appId, EndpointStatus? status, Cancel
152182 return await query . CountAsync ( ct ) ;
153183 }
154184}
185+
186+ public record EndpointListItem
187+ {
188+ public Guid Id { get ; init ; }
189+ public Guid AppId { get ; init ; }
190+ public string ? AppName { get ; init ; }
191+ public string Url { get ; init ; } = string . Empty ;
192+ public string ? Description { get ; init ; }
193+ public EndpointStatus Status { get ; init ; }
194+ public string ? CircuitState { get ; init ; }
195+ public string CustomHeadersJson { get ; init ; } = "{}" ;
196+ public string ? SecretOverride { get ; init ; }
197+ public string MetadataJson { get ; init ; } = "{}" ;
198+ public List < string > EventTypeNames { get ; init ; } = [ ] ;
199+ public List < Guid > EventTypeIds { get ; init ; } = [ ] ;
200+ public DateTime CreatedAt { get ; init ; }
201+ public DateTime UpdatedAt { get ; init ; }
202+ }
0 commit comments