Skip to content

Commit dda6fd9

Browse files
committed
Implement listNested pattern for entity-api
1 parent 6649e10 commit dda6fd9

File tree

2 files changed

+70
-4
lines changed

2 files changed

+70
-4
lines changed

src/lib/api/coaching-sessions.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,28 @@ export const CoachingSessionApi = {
130130
throw new Error("Delete nested operation not implemented");
131131
},
132132

133+
/**
134+
* Lists coaching sessions nested under a user (follows the createNested pattern).
135+
*
136+
* This uses the /users/{user_id}/coaching_sessions endpoint with support for
137+
* query parameters like date filtering and related resource inclusion.
138+
*
139+
* @param userId The ID of the user (coach or coachee)
140+
* @param params Query parameters for filtering, sorting, and including related data
141+
* @returns Promise resolving to array of EnrichedCoachingSession objects
142+
*/
143+
listNested: async (
144+
userId: Id,
145+
params?: any
146+
): Promise<EnrichedCoachingSession[]> => {
147+
return EntityApi.listNestedFn<EnrichedCoachingSession>(
148+
USERS_BASEURL,
149+
userId,
150+
'coaching_sessions',
151+
params
152+
);
153+
},
154+
133155
/**
134156
* Fetches coaching sessions for a specific user with optional related data.
135157
*
@@ -168,10 +190,7 @@ export const CoachingSessionApi = {
168190
params.sort_order = sortOrder;
169191
}
170192

171-
return EntityApi.listFn<EnrichedCoachingSession>(
172-
`${USERS_BASEURL}/${userId}/coaching_sessions`,
173-
{ params }
174-
);
193+
return CoachingSessionApi.listNested(userId, { params });
175194
},
176195
};
177196

src/lib/api/entity-api.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export namespace EntityApi {
2626
interface ApiOperations<T, U> {
2727
create?: (entity: T) => Promise<U>;
2828
createNested?: (id: Id, entity: T) => Promise<U>;
29+
listNested?: (id: Id, params?: any) => Promise<U[]>;
2930
update?: (id: Id, entity: T) => Promise<U>;
3031
delete?: (id: Id) => Promise<U>;
3132
deleteNested?: (entityId: Id, nestedEntityId: Id) => Promise<U>;
@@ -161,6 +162,43 @@ export namespace EntityApi {
161162
);
162163
};
163164

165+
/**
166+
* Fetches a list of entities nested under a parent entity.
167+
* Constructs the URL using the parent entity's ID and base URL pattern.
168+
*
169+
* @template R The raw entity type returned by the API
170+
* @template U The transformed entity type (defaults to R if no transform provided)
171+
* @param baseUrl The base URL pattern (e.g., "/users")
172+
* @param id The parent entity's ID
173+
* @param resourcePath The nested resource path (e.g., "coaching_sessions")
174+
* @param params Optional query parameters to include in the request
175+
* @param transform Optional transformation function applied to each entity in the response
176+
* @returns A Promise resolving to an array of entities of type U
177+
*
178+
* @remarks This function:
179+
* - Builds URLs for nested resources following RESTful patterns
180+
* - Follows the same pattern as createNested for consistency
181+
* - Handles both raw and transformed data workflows
182+
* - Maintains type safety through generic parameters
183+
*/
184+
export const listNestedFn = async <R, U = R>(
185+
baseUrl: string,
186+
id: Id,
187+
resourcePath: string,
188+
params: any,
189+
transform?: (item: R) => U
190+
): Promise<U[]> => {
191+
if (!params) {
192+
return []; // Return empty array if params are null
193+
}
194+
195+
return fetcher<R[], U[]>(
196+
`${baseUrl}/${id}/${resourcePath}`,
197+
params,
198+
transform ? (data) => data.map(transform) : undefined
199+
);
200+
};
201+
164202
/**
165203
* Fetches a single entity from the specified URL.
166204
*
@@ -452,6 +490,15 @@ export namespace EntityApi {
452490
*/
453491
createNested: (id: Id, entity: T) =>
454492
executeWithState(() => api.createNested!(id, entity)),
493+
/**
494+
* Lists entities nested under a parent entity (foreign key relationship).
495+
*
496+
* @param id The parent entity's id under which to list entities
497+
* @param params Optional query parameters for filtering and sorting
498+
* @returns Promise resolving to an array of entities
499+
*/
500+
listNested: (id: Id, params?: any) =>
501+
executeWithState(() => api.listNested!(id, params)),
455502
/**
456503
* Updates an existing entity.
457504
*

0 commit comments

Comments
 (0)