Common-SenseMakers / sensemakers

Sensemakers infrastructure for developing AI-based tools for semantic annotations of social posts. Cross-poster app to publish your semantic posts on different networks.
GNU General Public License v3.0
1 stars 2 forks source link

[APP] Frontend Architecture Outline #58

Closed weswalla closed 4 months ago

weswalla commented 4 months ago

Initial outline from figma: image

Current PR: https://github.com/Common-SenseMakers/sensemakers/pull/57

You will notice I opted for a redux pattern using useReducer. I was initially grappling with a per post context approach but found this way feels more intuitive, and using the snapshot.docChanges() on a query snapshot makes it quite easy to dispatch the respective change type to a reducer action in an efficient manner (see: https://github.com/Common-SenseMakers/sensemakers/pull/57/commits/fb03d56460d7c9e1903e77a60f473ea421674127#diff-53a071de04be9fe66350a1551871f5b56a51a6c6eab93cddc18a6ba71fdf72d3R20). Setting up a document listener for each post, especially if the list of posts gets quite long, will likely hit some performance limitations.

Since we have a separate collection for AppPosts and PlatformPosts, depending on how we want the platform post to affect state we could either fetch for it directly in the onSnapshot() query listener with the platform post ids. Otherwise, this could be fetched for as needed inside a Post Component. One situation I could see it being useful as part of the reactive state is if we want some kind of indicator on an AppPost showing which platforms it has been mirrored to, which we can't know from the id alone.

Regarding Firestore usage in the frontend, we can use firestore queries directly in the frontend for the Posts collection, and use Firebase Security Rules to restrict query results to only show documents where the authorId matches the current userId. Something like:

service cloud.firestore {
  match /databases/{database}/documents {
    match /posts/{postId} {
      allow read: if request.auth != null && request.auth.uid == resource.data.authorId;
    }
  }
}

However, with the User collection, since we are storing sensitive information, we will need to use a cloud function as a proxy (as has been the case with the old auth/me endpoint).

I'm not clear on where useQuery might fit into the picture with the use of firestore collection query listeners (onSnapshot()).

We still need to create the firestore getters and api client objects.

pepoospina commented 4 months ago

Lets talk about this in person when you are available @weswalla

weswalla commented 4 months ago

@pepoospina an important question we need to answer is how real time do we want the list of posts to be?

If we avoid using query listeners then we need to manually requery for all posts by that user whenever a new post is added and when a post is removed. Handling the removing of a post is easy because that is a user triggered action and we can requery as a result of that action, but new posts coming in happens outside of our UI.

Though, it might be fair to assume that a user won't be logged in long enough during a session for new posts to come in from their other platforms and simply fetching all new posts right at log in / page refresh is enough to keep that list up-to-date.

pepoospina commented 4 months ago

Imo it's not the most important reactivity. We can have a pull down to reload experience triggered by the user.

The reactivity we do want is to see the status of a post, when semantics are added, and when it is published to the network.