Skip to content
This repository was archived by the owner on Feb 4, 2025. It is now read-only.

Conversation

@atorresveiga
Copy link
Contributor

@atorresveiga atorresveiga commented Jun 1, 2022

Description

This PR adds the is_editable field to the database and uses a fallback strategy for older stores.

Testing instructions

run testMigrate15to16
run OrderDtoMapperTest
For a full set of tests check the Woo PR

metaData = this.meta_data.toString(),
paymentUrl = this.payment_url ?: ""
paymentUrl = this.payment_url ?: "",
isEditable = this.is_editable ?: this.status in EDITABLE_STATUSES
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For older stores < v6.6 we check if the status is "pending", "on-hold", "auto-draft"

@peril-wordpress-mobile
Copy link

peril-wordpress-mobile bot commented Jun 1, 2022

You can trigger optional UI/connected tests for these changes by visiting CircleCI here.

Copy link
Contributor

@wzieba wzieba left a comment

Choose a reason for hiding this comment

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

I left some comments, WDYT?

).allowMainThreadQueries()
.fallbackToDestructiveMigrationOnDowngrade()
.fallbackToDestructiveMigrationFrom(1, 2)
.fallbackToDestructiveMigrationFrom(1, 2, 15)
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, you added version 15 here to force the app to re-fetch Orders and assert that isEditable is assigned, right?

Maybe instead of recreating the whole database, we could add a migration that will remove only Orders? It should be fairly straightforward, won't remove entities that are not affected, and will document the decision better (we'll know in the future what changes exactly migration from 15 to 16 caused). WDYT?

Comment on lines 72 to 73
@ColumnInfo(name = "isEditable", defaultValue = "true")
val isEditable: Boolean = false
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you share more context why defaultValue and default constructor values differ?

"database": {
"version": 15,
"identityHash": "c1b4a5003f85e61f9427f4fa0edea3e1",
"identityHash": "c863efcff0193dc66c6a1915f5291d07",
Copy link
Contributor

Choose a reason for hiding this comment

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

❗ We shouldn't change previous (existing) database schemas. I think we have to revert changes in this file (or I'm missing something).

@wzieba
Copy link
Contributor

wzieba commented Jun 2, 2022

Oh so sorry @atorresveiga - after the review I realized that this PR is a draft 🤦 . Sorry if it wasn't meant for the review yet. I hope that my comments will be helpful either way.

Copy link
Contributor

@wzieba wzieba left a comment

Choose a reason for hiding this comment

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

Thanks for improvements @atorresveiga !

As I'm leaving AFK today, I've added a few more comments 😅 .

Comment on lines 72 to 73
@ColumnInfo(name = "isEditable", defaultValue = "true")
val isEditable: Boolean = true
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we shouldn't let our data layer provide new information about the fetched object. I know we already do this for all other fields in this entity, but I think it's incorrect (I believe we discussed about this at some point with @0nko but unfortunately I didn't prepare an issue/fix).

I'd vote to make isEditable nullable. If this value will be a null in the core, it should also be a null in our app database. I think we should interpret this in a different layer. WDYT?

Copy link
Contributor Author

@atorresveiga atorresveiga Jun 3, 2022

Choose a reason for hiding this comment

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

I think I understand your point here. However, I believe it is the data layer's responsibility to transform and prepare the data to be ready to be used by the business logic.
With that in mind, taking a closer look at our example here with the is_editable field, the only reason I see why this field could be null is that the merchant is using an older version of the API. I believe it doesn't make sense to our business to have an isEditable = null in our Order. Maybe I'm missing something, but I think that will only add an extra layer of complexity to our business logic, managing a null value that won't make any sense to have, at least for now.
I will vote to keep this value as a Boolean and keep the responsibility of preparing the data and deciding what to do when the value is null here in the data layer. That said, if the team agrees to follow the pattern you commented on above, I would be happy to change the code. WDYT?

metaData = this.meta_data.toString(),
paymentUrl = this.payment_url ?: ""
paymentUrl = this.payment_url ?: "",
isEditable = this.is_editable ?: (this.status in EDITABLE_STATUSES)
Copy link
Contributor

Choose a reason for hiding this comment

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

It'd be awesome to add unit tests for this part (it's easy to miss something like here: c43c7cc

@DeleteTable(tableName = "ProductCategories")
internal class AutoMigration14to15 : AutoMigrationSpec

@DeleteTable(tableName = "OrderEntity")
Copy link
Contributor

Choose a reason for hiding this comment

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

This will remove the whole table - I think we want to provide a migration (I'm not sure if "auto" one) that will remove only content of the orders.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, indeed. I realized this after I tested. I believed this was the same as DELETE FROM OrderEntity, but I couldn't be more wrong. Now I added a Migration to drop and recreate the table.

@atorresveiga
Copy link
Contributor Author

Thanks for the review, @wzieba, it helps me correct some issues early. I'm still adding some tests. I will let you know when the PR is ready

@atorresveiga atorresveiga marked this pull request as ready for review June 3, 2022 20:46
@atorresveiga
Copy link
Contributor Author

@wzieba thanks for your work here. This PR is ready for another round

@nbradbury
Copy link
Contributor

@atorresveiga I see @wzieba has already reviewed this so it's probably good to go, but I'm curious why an auto-migration wasn't used?

@atorresveiga
Copy link
Contributor Author

@atorresveiga I see @wzieba has already reviewed this, so it's probably good to go, but I'm curious why an auto-migration wasn't used?

Hi @nbradbury! Auto-migration will keep all the data from the OrderEntity table and add the new isEditable field with the default value. This could end on some Orders marked as editable but in a status that doesn't allow the Order to be changed. What I tried with this migration was to clear all the OrdersEntity data from the DB to force the app to request this info again from the API with the new isEditable field and use the API as the source of truth.

Copy link
Contributor

@nbradbury nbradbury left a comment

Choose a reason for hiding this comment

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

Thanks for the explanation about not using auto-migrations, makes sense! :shipit:

@nbradbury nbradbury merged commit ae5410d into trunk Jun 7, 2022
@nbradbury nbradbury deleted the issue/6649-add-is-editable-API-field branch June 7, 2022 16:48
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants