Skip to content

Conversation

@jhodapp
Copy link
Member

@jhodapp jhodapp commented Mar 8, 2025

Description

This PR refactors all of the other entity API functions and hooks to use new pattern established with Organization.

Note: this is a big PR but I'm going to leave some comments showing where to really hone your review with much of the rest of the changes just being quite repetitive and uninteresting.

Note 2: this PR requires this small backend PR to function correctly for logout.

GitHub Issue: None

Changes

  • Refactor the coaching relationship functions to use new hook/API pattern
  • Refactor user session login/logout functions to use new hook/API pattern
  • Refactor the coaching session functions to use new hook/API pattern
  • Refactor the action functions to use new hook/API pattern
  • Refactor the agreement functions to use new hook/API pattern
  • Refactor the overarching goal functions to use new hook/API pattern
  • Update entity-api to include an optional response data parsing/transformation function parameter to useEntityList() and listFn()

Screenshots / Videos Showing UI Changes (if applicable)

Testing Strategy

  1. Run through the entire application to ensure expected behavior, including…
  2. Login/Logout
  3. Select organization, relationship and join a coaching session
  4. Create a new coaching session
  5. Create, update and delete actions and agreements on the coaching session page
  6. Set an overarching goal
  7. Update an overarching goal
  8. Change coaching sessions from the selector box on the coaching session page

Concerns

None

@jhodapp jhodapp added the enhancement Improves existing functionality or feature label Mar 8, 2025
@jhodapp jhodapp added this to the 1.0-beta1 milestone Mar 8, 2025
@jhodapp jhodapp self-assigned this Mar 8, 2025
@jhodapp jhodapp moved this to 🏗 In progress in Refactor Coaching Platform Mar 8, 2025
@jhodapp jhodapp changed the title Refactor other entity apis and hooks Refactor other entity apis and hooks to use new pattern Mar 8, 2025
@jhodapp jhodapp changed the title Refactor other entity apis and hooks to use new pattern Refactor other entity API methods and hooks to use new pattern Mar 8, 2025
@jhodapp jhodapp requested review from calebbourg, qafui and zgavin1 March 15, 2025 18:57
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an important file to check over since it's now used by all entities.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repetitious but still important to check over the use of the new entity-api hook/Api pattern.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repetitious but still important to check over the use of the new entity-api hook/Api pattern.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repetitious but still important to check over the use of the new entity-api hook/Api pattern.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repetitious but still important to check over the use of the new entity-api hook/Api pattern.

organization
),

createNested: async (id: Id, entity: Organization): Promise<Organization> => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on having the same API for all entities, but some of them currently don't (or never will make sense to) implement certain functions? This is about having a standard and predictable set of entity verbs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - because it's a means to achieve standardization this seems fine.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a comment above around making it optional but I agree with this as well. Either works for me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repetitious but still important to check over the use of the new entity-api hook/Api pattern.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repetitious but still important to check over the use of the new entity-api hook/Api pattern.

// Type-safe transformation function with runtime validation that ensures
// that raw ISO date time stamps are transformed into valid ts-luxon DateTime
// instances.
export const transformEntityDates = (data: any): any => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This transformation function is new and is used by some of the entity *List hooks/API functions. Since this is new, definitely worth checking over to see if it's easy to use and implemented well.

const sessionIds = coachingSessions?.map((session) => session.id) || [];
const goalsPromises = sessionIds.map((id) =>
fetchOverarchingGoalsByCoachingSessionId(id)
OverarchingGoalApi.list(id)
Copy link
Member Author

@jhodapp jhodapp Mar 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component and others should ideally be updated to use hooks instead of the direct function calls, but I decided it was out of the scope of this PR to refactor to this level since it would be a pretty major component code restructuring change.

The main reason being, this will give us automatic updates of list of entities when they're changed locally by the current user without having to refresh the page. For example, in the CoachingSessionList component.

@jhodapp jhodapp changed the title Refactor other entity API methods and hooks to use new pattern Refactor other entity API functions and hooks to use new pattern Mar 15, 2025
@jhodapp jhodapp marked this pull request as ready for review March 15, 2025 19:09
@jhodapp jhodapp moved this from 🏗 In progress to Review in Refactor Coaching Platform Mar 15, 2025
@jhodapp jhodapp force-pushed the refactor_other_entity_apis_and_hooks branch from fabdb1f to c74c9c7 Compare March 16, 2025 18:50
Copy link
Collaborator

@calebbourg calebbourg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jhodapp this is super cool and cleans things up a lot! Thank you for putting it together <3

I left a few thoughts and questions.
The main thing I'd just like to talk through is making config argument required vs returning an empty Array

create: async (agreement: Agreement): Promise<Agreement> =>
EntityApi.createFn<Agreement, Agreement>(AGREEMENTS_BASEURL, agreement),

createNested: async (_id: Id, _entity: Agreement): Promise<Agreement> => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious what these might be used for.

transform?: (data: T) => U
): Promise<U> => {
if (!config) {
return [] as unknown as U; // Return empty array if config is null
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to make the config argument required? I'm worried that this might start returning [] because of this and we think it's an issue on the BE and spend an unneeded amount of time troubleshooting before finding this line of code.
If we require config would the type system protect us here? I'm not 100% on how typescript works in that situation. If it's at compilation we should be protected I would think.

An alternative would be to log something to the console here so we would at least be able to get a hint at what happened.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to Caleb's idea. Definitely feels more sound to use the type system to enforce/require a config arg than an early return in the function body.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also a good catch, it was an easy change to make.

});

const rawData = response.data.data;
return transform ? transform(rawData) : (rawData as unknown as U);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this option a lot

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Me too, it works super well. There if one needs it, otherwise ignore.

baseUrl: string,
api: {
create: (entity: T) => Promise<T>;
createNested: (id: Id, entity: T) => Promise<T>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One option that I think might exist, though I don't know how to do this in typescript, would be to extract the api object into it's own type or interface and then have createNested be optional.
I don't have a strong opinion on that.

Copy link
Member Author

@jhodapp jhodapp Mar 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way useEntityMutation is set up, there's no easy way of not having the same functions across all entity types unfortunately.

organization
),

createNested: async (id: Id, entity: Organization): Promise<Organization> => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a comment above around making it optional but I agree with this as well. Either works for me.

Copy link
Collaborator

@calebbourg calebbourg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@jhodapp jhodapp merged commit 134a4d2 into main Mar 19, 2025
4 checks passed
@jhodapp jhodapp deleted the refactor_other_entity_apis_and_hooks branch March 19, 2025 23:32
@github-project-automation github-project-automation bot moved this from Review to ✅ Done in Refactor Coaching Platform Mar 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improves existing functionality or feature

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

4 participants