- Set `search_path` for all database functions, as this is recommended
by the Supabase security advisor
- Fix `items_delete` functions: The function was never working, which
caused that we saved to many items for a source, which slowed down our
performance
- Revoke execution rights for users for the `sources_delete_files` and
`items_delete` functions
- Add E2E test, to check if users can call the database functions
It is now possible to re-order sources in a column by dragging them into
a new position. To achieve this a new `position` field was added to the
`sources` column, which contains the index of the source in the column.
We also added a new `updateSourcePositions` function, which is used to
sort the sources locally and update `position` field in the database
afterwards. The dragging is handled via a `ReorderableListView` widget.
Last but not least the selection of sources from the database was
changed, so order them by the `position` column and if the column is
`null` by the `createdAt` data as it was before.
Until now it could happen that the items for a column could not be
retrieved from the database, because of the set query timeout. In this
case we received the following error:
```
PostgrestException(message: canceling statement due to statement timeout, code: 57014, details: Internal Server Error, hint: null)
```
To fix this issue we added an `items_columnId_idx` index, so that the
items for a column are retrieved fast.
We also added some other useful indexes to improve the overall
performance of our queries.
Last but not least we also added an index to the `userId` columns as it
is recommended by Supabase to improve the performance of our RLS
policies.
We have to add in-app purchases for the iOS, macOS and Android store, so
that users can also get the premium features of the app without using
Stripe for payments.
The in-app purchases are only enabled when a user uses the app with the
default Supabase environment or with the Supabase environment provided
during build time. If a user uses his own Supabase instance, he will not
be able to upgrade to the premium tier via in-app purchases.
We are using RevenueCat for in-app purchases, which automatically sends
all the events for a user to the "revenuecat-webhooks-v1" edge function.
Depending on the received event we can then upgrade / downgrade the
users profile. To be able to use RevenueCat as an additional provider to
Stripe we also had to add a new "subscriptionProvider" provider column
to the "profiles" table, which stores the information via which provider
a user upgraded his account.
Improve the media handling within the app. We do not save the media
files for items to the Supabase storage anymore. The source icons are
now only saved in the Supabase storage, the usage of an url as source
icon is not possible anymore.
The media files for items are directly retrieved from the corresponding
url or for the web version from the "image-proxy-v1" Supabase function.
If the image is retireved from the Supabase function we cache the image
in the browser via the cache control headers. If the image is directly
retrieved from it's url it's cached by the "CachedNetworkImage" widget.