codesydney / marketplace-app-for-good

1 stars 1 forks source link

MA6 - In-App Chat #7

Open davidtaing opened 5 months ago

davidtaing commented 5 months ago

Introduction

Problem statement

We want to allow Customers and Service Providers to communicate with each other in app. The main benefits is to make it easier for us to learn how our app is being used. In addition, in-house communication will make it easier to moderate abuse between the different parties.

Goals

Non-goals

*Non-goals marked with Not Now can be considered for further tickets.

Prerequisites

This will require the tasks, quotations and jobs features to be completed.

Features built on top of Stripe such as Customer / Provider Onboarding and Payments are not required.

davidtaing commented 5 months ago

Proposed solution

DRAFT

High Level Design

This solution relies on a Websocket server to push updates to the client.

Message Send Untitled-2023-07-05-2108(37)

Message Update / Receive mermaid-diagram-2024-03-21-072446

Notes:

Database Schema

TODO

TODO - Messages Table

TODO - Threads Table

Sending Messages

Sending messages can be handled by the Supabase client & PostgREST so no additional API endpoints are required.

This can be achieved with the following code snippet.

const message = {
  content: "Hi, I can do this for $300.",
  recipient_id: <recipient_id>,
  sender_id: <sender_id>,
  sent_at: new Date().toISOString(),
  thread_id: <thread_id>,
 };

await supabase.from("messages").insert([message]);

Getting New Messages

The query for getting new messages can be represented by the following SQL snippet.

SELECT * from Messages
WHERE thread_id = :thread_id
AND id > :last_message_id

This relies on the message.id field being some sort of ordered ID.

Getting Updates via Supabase Realtime (Websockets)

Pros & Cons

Pluses

Minuses

Chat UI

For the new Chat UI, we'll use the chatscope/chat-ui-kit to bootstrap our UI.

To get an idea of what it looks like, check out their demo at https://chatscope.io/demo/chat-friends.

In the future, we can look into migrating the UI to Radix UI Themes. The value is debatable but this could make sense as a collection of onboarding tasks.

State Management in React

TODO

Thinking about using converting arrays to objects as hashmaps (todo: reword).

const state = {
  messages: {
    // convert the messages array to an object
    messages_id_1: {...},
    messages_id_2: {...},
    messages_id_3: {...},
  },
  threads: {
   // convert the threads array to an object.
    thread_id_1: {...},
    thread_id_2: {...},
    thread_id_3: {...},
  },
}

// This will make it easier to apply updates.
const newMessages = {
    messages_id_2: {...updated message 2...},
    messages_id_4: {...},
    messages_id_5: {...},
}

const newState = {
   messages: {
     ...messages.
     ...newMessages
   },
   threads: state.threads,
}

Some care will need to be taken to prevent re-renders due to recreating the root state object. Not a fan of slapping useMemo on everything. We'll look around.

davidtaing commented 5 months ago

Alternative solutions

DRAFT

Discussion on alternative solutions will be focused on how we get updates from the server. Message Send, Chat UI & Chat State Management will remain the same across the different solutions.

High Level Design

Message Send Untitled-2023-07-05-2108(39)

Getting Updates mermaid-diagram-2024-03-21-065754

Getting Updates via Polling

Write up about polling.

Pros & Cons to Polling

Pluses

Minuses

Notes

davidtaing commented 5 months ago

Implementation and rollout plan

1. Tech Spike / Proof of Concept

The original proof of concept will be implemented in this pull request / branch

A simplified database schema was used for tasks, quotations and jobs, so this pull request will not be compatible with the current implementation.

2. Wait for Prerequisites to be Completed

See original post for more information.

3. Setup Dependencies

Setup dependencies as a separate pull request since PR #12's package.json file contains a 1500 line diff.

4. Setup Database

Similar to the previous, we'll setup database migrations and generated database types as a separate pull request.

5. Implement Chat

Finally, we'll implement chat using PR #12 as inspiration.

Note: Since we don't have any users, we can be more flexible with deleting database migrations.

davidtaing commented 5 months ago

Glossary

Application