Skip to content

Conversation

@Duncan-Brain
Copy link
Collaborator

@Duncan-Brain Duncan-Brain commented May 2, 2025

Description

** REBASED - in case you pulled locally already

Waiting for LF-4767 to merge so I can delete frontend mock and add after_date param to query function.

This implements the backend endpoint to get irrigation prescriptions from esci.

It also adds tests for this endpoint.

Notes:

  • Sorry about the commits they will be hard to read, it got too messy for my liking:
    • I looked into farm local date because we don't have an accurate one for DST (everything is UTC based but should be IANA timezone code based is my understanding), thanks Joyce for pointing me in the direction of using our existing browser local pattern despite it not being quite correct for farm local. (one of these days it would be nice to get dates consistent and correct ...but not today)
    • Also got confused with the other ip route and if I should be putting this route there
    • should have reverted date commits instead of deleteing manually, it led to some back pakage-lock later on needing correcting -- sorry
  • Went ham on full model types, I have been lazy with this before now, also moved some types around as I thought they were broadly useful, let me know if its no good, but I would ask to keep it.

Jira link: LF-4765

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

  • Passes test case
  • UI components visually reviewed on desktop view
  • UI components visually reviewed on mobile view
  • Other (please explain)

Checklist:

  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • The precommit and linting ran successfully
  • I have added or updated language tags for text that's part of the UI
  • I have added "MISSING" for all new language tags to languages I don't speak
  • I have added the GNU General Public License to all new files

@Duncan-Brain Duncan-Brain self-assigned this May 6, 2025
…nd filter returned irrigation tasks by result of that query
Copy link
Collaborator

@antsgar antsgar left a comment

Choose a reason for hiding this comment

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

Sorry this took me a while to review! I had started it the other day and had to switch to the Soil breakdown. I've added a few comments, but it's overall looking good -- I'll re-review once you've addressed Joyce's comment ☺️

Comment on lines 46 to 47
// @ts-expect-error - farm_id is guaranteed here by the checkScope middleware with single argument
const farmAddonPartnerIds = await FarmAddonModel.getDistinctFarmAddonPartnerIds(farm_id);
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you know for sure farm_id won't be undefined, instead of @ts-expect-error you can use a non-null assertion operator

Suggested change
// @ts-expect-error - farm_id is guaranteed here by the checkScope middleware with single argument
const farmAddonPartnerIds = await FarmAddonModel.getDistinctFarmAddonPartnerIds(farm_id);
const farmAddonPartnerIds = await FarmAddonModel.getDistinctFarmAddonPartnerIds(farm_id!);

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I like having a comment for unclear assertions. Assertions should be used sparingly.

I have a test branch for a specific fix for this open mentioned with Joyces comment: #3755 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd say ts-expect-error should be used even more sparingly, and my understanding is that it's meant to be used temporarily. If you're absolutely sure farm_id would be present I think the non-null assertion would be okay. I did look at the other branch, and although I like the idea of adding a type guard I honestly feel it overcomplicates the code with not that much added benefit. But I'm curious to know what others think too

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this is a point we disagree on.

For code reuse and readability for devs, if I were to copy this code I would likely not notice a trailing ! present in the code vs a commented @ts-expect-error. It is a single character and assertions are dangerous because they override some typescript typings.

I am fairly certain we have been using @ts-expect-error as a stop gap when we have not found the correct typescript solution to make it work. The non-null assertion feels like a final 'correct' solution in limited circumstances. So, if I copied this controller code erroneously without a checkScope in the accompanying routes file -- the assertion could be incorrect.

In the other branch -- I don't know what type guard you are talking about -- but the explicit type assertion that overrides the express Request type is placed next to the checkScope to make it clear they go together. This is an assertion done in the routes context right next to the checkScope it relies upon... still not ideal but avoids the @ts-expect-error. In the link you provided from Typescript they also put the non-null assertion right next to some context claiming it is correctly validated:

function processEntity(e?: Entity) {
  validateEntity(e);
  let s = e!.name; // Assert that e is non-null and access name
}

It feels like the end best solution will be that express needs to make some sort of generic that goes along with type NextFunction or something like that but thats not our problem. Maybe the cleanest/safest way for us right now is to double up on certain type guards and put them in the controller as well as well as the middleware? Do you like that any better?

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is the type guard I'm referring to https://github.com/LiteFarmOrg/LiteFarm/pull/3772/files#diff-31ffdd44c889de461e56828613f90ff13ba191db724cda9bdb7b6e90e8937d48R45-R52.

A type assertion is as bad as a non-null assertion (arguably worse?) so my feeling is the balance between having a +185 -42 diff to end up with a solution that isn't ideal vs achieving a solution that isn't good either but just uses one character doesn't add up. I'd be totally okay with keeping the @ts-expect-error as a non-ideal solution too, that's not a blocker for me!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Great, I would like to keep the ts-expect error then since it has a comment explaining its existence and we may not know the best way to type it.

Thanks for sharing the type guard, I think the one you are pointing too has nothing to do with the farm_id, the query param type guard check has been moved to middleware in this PR but in the draft PR it is outdated.

To be fair the actual code change to assert the correct type is like ~ +20, the rest is changing a core file to typescript and adding more types which is generally useful. I am really not saying we should do it but it seems like we are striving to have mostly correct typings -- I personally think this solution is possibly the most correct we can get with express.

To continue the best practice discussion -- because I like chatting about it 😄 :

A type assertion is as bad as a non-null assertion (arguably worse?)

Its not that either asserting that is necessarily bad, it is asserting out of context or to use as a temporary solution that is bad. There are genuine cases for each but being extra careful about both is important I think. For this case I think we would be using it here as a temporary solution, out of context, that could lead to serious code reuse errors.

The farm_id type guard that already exists in checkScope is two files away from the controller. If it were right beside it and not working in context (like the TS example, and other examples on internet I can find) I would agree non-null assertion.

Type casting assertions are also useful when maybe you cannot type check like external package or endpoint.

@Duncan-Brain Duncan-Brain requested review from antsgar and kathyavini and removed request for SayakaOno May 20, 2025 18:56
@Duncan-Brain
Copy link
Collaborator Author

I think I have addressed all the comments. Just noting that when I tested the full flow including creating a task I think some parts of task flow may not be correct:

  • Wrong external_prescription_id possibly being sent to backend
  • Not able to create a irrigation task using the same external_prescription_id between farms -- should this not be farm specific? (even though it will should likely never happen)

@kathyavini
Copy link
Collaborator

kathyavini commented May 21, 2025

  • Wrong external_prescription_id possibly being sent to backend

  • Not able to create a irrigation task using the same external_prescription_id between farms -- should this not be farm specific? (even though it will should likely never happen)

@Duncan-Brain did you maybe not pull the most recent version of integration before you merged it? Those adjusts were merged in #3762 but I don't see that code on this branch.

It's going to help with my testing, so I'll just re-merge integration now if that's okay 🙏

@kathyavini
Copy link
Collaborator

kathyavini commented May 21, 2025

@Duncan-Brain actually, is your local code definitely the same as what you have pushed to this branch? Can you double-check? You have a line here:

return shouldSend ? ESciAddon : Mocks;

that controls when the mocking happens, but shouldSend is not a boolean on this branch -- it's the string 'false' -- so this is always hitting the ESci endpoint and returning a 404. The result is no IPs in the frontend, so if you are seeing them, something is not aligned... 🤔 Can you check what you have locally vs pushed, and then maybe we can investigate this tomorrow morning before/after Sprint Planning if there is still a discrepancy?

@Duncan-Brain
Copy link
Collaborator Author

@kathyavini Thanks for merging integration, yes I think you are right.

Type and conditional is updated. Must have had my frontend cache why I didn't see it 🙏 . Damned attention to detail haha

@kathyavini kathyavini added this pull request to the merge queue May 26, 2025
Merged via the queue into integration with commit 4918d95 May 26, 2025
5 checks passed
@kathyavini
Copy link
Collaborator

kathyavini commented May 26, 2025

Anto gave her verbal approval for this one (and we'll be moving to her review not blocking this week anyhow). And it looks good to me!

@Duncan-Brain
Copy link
Collaborator Author

Great thanks @kathyavini for your review and merging!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants