Skip to content

Realtime Collaborative Annotations

Denny George edited this page Apr 28, 2020 · 10 revisions

Outline

  • Description
  • Spec
  • Implementation
  • Testing
  • Demo
  • Changelog

Description

Every post in the archive has some metadata that can be filled automatically or by a user. These metadatas are usually divided into groups called Template. Usually a set of users based on their expertise or domains might have a Template that they focus on. This document focus on Realtime collaborative aspect of viewing and editing values inside a template.

Spec

  • Developer can define the fields in a template
  • User can view the metadata
  • User can see who else is viewing the page
  • User can see other users who are editing the page
  • User can see which parts of the form are being edited by which user
  • User can see if new data is available for syncing
  • User can see new data being fetched and updated on their screen
  • User can not edit a metadata field if another user is already editing it
  • User can see their connectivity status

Implementation

System Diagram

The software is implemented using a MVC pattern.

MetadataEditorRoute

This class is responsible for exposing public endpoints for clients to interact with. It will have a mix of WebSocket endpoints for realtime data flows and a REST API to fetch all metadata at once. It is a lean class that just defines the public routes and the routes the incoming requests to the MetadataEditorController

MetadataEditorRoute
    join
    startEdit(metadataKey, currentValue)
    stopEdit(metadataKey, finalValue)
    leave
    getMetadata(postId)

MetadataEditorController

This class handles the business logic of the real time annotations. Which mainly includes accessing and reading data correctly by integrating with the Model classes.

MetadataEditorController
    createRoom
    initData
    getData
    addUser
    removeUser
    addEdit(userId, metadataKey, currentvalue)
    stopEdit(userId, metadataKey, finalValue)

MetadataEditorCacheModel

This acts as a wrapper class over the Redis and SQL models to hide the implementation details from MetadataEditorController. It wraps everything in a clean API for the controller to consume.

MetadataEditorCacheModel
   getMetadata()
   storeMetadataItem(metadataKey, value)
   initRedisStoreWithSqlData(postId, templateId)
   syncSQLWithRedisData(postId, templateId)
MetadataRedisModel
   addEditMetadataItem(postId, templateId, metadataKey, metadataValue)
   getMetadataItem(postId, templateId, metadataKey)
   getMetadata(postId, templateId)
MetadataSQLModel
   addEditMetadataItem(postId, templateId, metadataKey, metedataValue)
   addEditMetadata(postId, templateId, metadata)
   getMetadata(postId, templateId)

Testing

unit tests

  • Testing the controller classes integration test
  • controller and sql
  • controller and redis
  • controller and socket integration test
  • socket client connecting to the server and controller, redis, sql

run npm test to run the test suite. If it fails something's up.

Demo

add a video of the feature

Changelog