/cloudtalk-assignment

Primary LanguageTypeScriptMIT LicenseMIT

I considered this architecture:

./diagrams/considered-architecture.png

But than found a way where I could eliminate one database and improve "caching" of average ratings:

./diagrams/implemented-architecture.png

Reasoning/explanation:

  • All data are stored in single database, so that it is easier to join them

  • Redis here is used as MQ (pub/sub mode) to send review calculation messages from product-service to review-calculation-service

  • For average rating calculation, there is no need to have all the review present. These fields of CalculationMessage are enough:

    • averageRating;
    • originalCount;
    • countChange;
    • ratingChange;
  • Final average rating is:

    newAverageRating = (averageRating * originalCount + ratingChange) / (originalCount + countChange)  
    
  • review-calculation-service informs product service about new average rating via private REST endpoint

  • Average rating is stored in products table

  • I know there was this sentence "Product reviews and average product ratings should be cached."

    • To me storing those values in single database is far better "caching" storing them is separate in separate redis instance
    • I believe it is worth to avoid caching if possible
    • This would be faster, because I don't need to combine response from database and cache, single select is needed here
  • I did not have time to figure out enum for review.rating, Nest.js stack is new to me, so I had to learn a lot on the way

  • Typescript and ESLint configs were generated by Nest.js, didn't touch them

Further steps:

  • Create authorization for private updateAverageRating endpoint, so that only review-calculation-service is able to call it
  • Use more black box testing, that would cover also controller mappings
  • Test also review-calculation-service
  • Add authentication
  • Tidy up URLs and env variables
  • Secure postgres and redis much more
  • Create Terraform orchestration, plug the project into CI/CD