diff --git a/backend-services/feed-service/.gitignore b/backend-services/feed-service/.gitignore
index dce73038415f7e68f232c49cefe21ad58a9056e7..28bb3ff68c708d613d3eab78cb7eee780612f77c 100644
--- a/backend-services/feed-service/.gitignore
+++ b/backend-services/feed-service/.gitignore
@@ -7,3 +7,11 @@ target
 /.project
 /.settings
 /RUNNING_PID
+
+# VSCode
+.vscode
+
+# Metals (Scala extension)
+.metals
+.bloop
+metals.sbt
diff --git a/backend-services/feed-service/app/controllers/DailyController.scala b/backend-services/feed-service/app/controllers/DailyController.scala
new file mode 100644
index 0000000000000000000000000000000000000000..a63fcf3a1d107f8d99c6abda5a07586094311108
--- /dev/null
+++ b/backend-services/feed-service/app/controllers/DailyController.scala
@@ -0,0 +1,206 @@
+package controllers
+
+import javax.inject._
+import play.api.mvc._
+import play.api.libs.json.{JsValue, JsLookupResult}
+
+import models.{Daily}
+import models.actions.{AuthenticatedUserAction, AuthenticationRequest}
+import models.exceptions.{ConflictException, NotFoundException, InvalidRequestBodyException, InvalidQueryParameterException}
+
+import scala.concurrent.TimeoutException
+import org.bson.types.ObjectId
+
+/**
+ * This controller handles all the Daily endpoints.
+ */
+@Singleton
+class DailyController @Inject()(val controllerComponents: ControllerComponents, authenticatedUserAction: AuthenticatedUserAction) 
+  extends BaseController {
+
+  /**
+   * Create an Action to fetch all the Dailies in the DB.
+   */
+  def getAll() = authenticatedUserAction {
+    println("DailyController:getAll")
+
+    try {
+        val result: Seq[Daily] = Daily.getAllDailiesAsync()
+        val jsonResult: JsValue = Daily.toJson(result)
+        Ok(jsonResult)
+    } catch {
+        case _: TimeoutException => BadRequest("Request timed out")
+        case _: Throwable => BadRequest("Exception raised")
+    }
+  }
+
+  /**
+   * Create an Action to fetch the user's Dailies in the DB.
+   * 
+   * @param userId The ID of the user to get the dailies for.
+   */
+  def getUserDailies(userId: String) = authenticatedUserAction {
+    println("DailyController:getUserDailies")
+
+    try {
+        if (!ObjectId.isValid(userId)) throw new InvalidQueryParameterException("Invalid query parameter ID format: userId")
+
+        val result: Seq[Daily] = Daily.getUserDailiesAsync(new ObjectId(userId))
+        val jsonResult: JsValue = Daily.toJson(result)
+        Ok(jsonResult)
+    } catch {
+        case _: TimeoutException => BadRequest("Request timed out")
+        case ex: InvalidQueryParameterException => BadRequest(ex.getMessage())
+        case _: Throwable => BadRequest("Exception raised")
+    }
+  }
+
+  /**
+   * Create an Action to fetch the user's Feed.
+   * 
+   * @param userId The ID of the user to get the feed for.
+   */
+  def getUserFeed(userId: String) = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] =>
+    println("DailyController:getUserFeed")
+
+    try {
+        if (!ObjectId.isValid(userId)) throw new InvalidRequestBodyException("Invalid query parameter ID format: userId")
+
+        val result: Seq[Daily] = Daily.getUserFeedAsync(new ObjectId(userId), request.jwt)
+        val jsonResult: JsValue = Daily.toJson(result)
+        Ok(jsonResult)
+    } catch {
+        case _: TimeoutException => BadRequest("Request timed out")
+        case ex: InvalidQueryParameterException => BadRequest(ex.getMessage())
+        case _: Throwable => BadRequest("Exception raised")
+    }
+  }
+
+  /**
+   * Create an Action to create a Daily.
+   */
+  def create() = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] =>
+    println("DailyController:create")
+
+    try {
+        val (userId, questionId, content) = fetchCreateRequestBody(request.body)
+
+        val result: Daily = Daily.createDailyAsync(userId, questionId, content)
+        val jsonResult: JsValue = Daily.toJson(result)
+        Ok(jsonResult)
+    } catch {
+        case _: TimeoutException => BadRequest("Request timed out")
+        case ex: InvalidRequestBodyException => BadRequest(ex.getMessage())
+        case _: Throwable => BadRequest("Exception raised")
+    }
+  }
+
+  /**
+   * Create an Action to like a Daily.
+   */
+  def like() = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] =>
+    println("DailyController:like")
+
+    try {
+        val (dailyId, likerId) = fetchLikeRequestBody(request.body)
+        
+        Daily.likeAsync(dailyId, likerId, request.jwt)
+        Ok("Daily liked.")
+    } catch {
+        case _: TimeoutException => BadRequest("Request timed out")
+        case ex: InvalidRequestBodyException => BadRequest(ex.getMessage())
+        case ex: ConflictException => BadRequest(ex.getMessage())
+        case ex: NotFoundException => BadRequest(ex.getMessage())
+        case _: Throwable => BadRequest("Exception raised")
+    }
+  }
+
+   /**
+   * Create an Action to unlike a Daily.
+   */
+  def unlike() = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] =>
+    println("DailyController:unlike")
+
+    try {
+        val (dailyId, likerId) = fetchLikeRequestBody(request.body)
+
+        Daily.unlikeAsync(dailyId, likerId, request.jwt)
+        Ok("Daily unliked.")
+    } catch {
+        case _: TimeoutException => BadRequest("Request timed out")
+        case ex: InvalidRequestBodyException => BadRequest(ex.getMessage())
+        case ex: ConflictException => BadRequest(ex.getMessage())
+        case ex: NotFoundException => BadRequest(ex.getMessage())
+        case _: Throwable => BadRequest("Exception raised")
+    }
+  }
+
+  /**
+   * Fetch the needed values from the request body for the creating a Daily endpoint.
+   * 
+   * @param requestBody The request's body.
+   */
+  def fetchCreateRequestBody(requestBody: AnyContent): (ObjectId, ObjectId, String) = {
+    if (!requestBody.asJson.isDefined) throw new InvalidRequestBodyException("Request body must be in JSON format.")
+
+    val bodyJson = requestBody.asJson.get
+
+    val userId: ObjectId = fetchJsonBodyObjectId(bodyJson, "userId")
+    val questionId: ObjectId = fetchJsonBodyObjectId(bodyJson, "questionId")
+    val content: String = fetchJsonBodyString(bodyJson, "content")
+
+    (userId, questionId, content)
+  }
+
+  /**
+   * Fetch the needed values from the request body for the liking/unliking a Daily endpoint.
+   * 
+   * @param requestBody The request's body.
+   */
+  def fetchLikeRequestBody(requestBody: AnyContent): (ObjectId, ObjectId) = {
+    if (!requestBody.asJson.isDefined) throw new InvalidRequestBodyException("Request body must be in JSON format.")
+
+    val bodyJson = requestBody.asJson.get
+
+    val dailyId: ObjectId  = fetchJsonBodyObjectId(bodyJson, "dailyId")
+    val likerId: ObjectId  = fetchJsonBodyObjectId(bodyJson, "likerId")
+
+    (dailyId, likerId)
+  }
+
+  /**
+   * Fetch the value of the given field name from the JSON.
+   * 
+   * @param bodyJson The JSON.
+   * @param fieldName The field name.
+   */
+  def fetchJsonBodyValue(bodyJson: JsValue, fieldName: String): JsValue = {
+    val value: JsLookupResult = (bodyJson \ fieldName)
+    if (!value.isDefined) throw new InvalidRequestBodyException("Missing parameter: " + fieldName)
+    value.get
+  }
+
+  /**
+   * Fetch the String value of the field name from the JSON.
+   * 
+   * @param bodyJson The JSON.
+   * @param fieldName The field name.
+   */
+  def fetchJsonBodyString(bodyJson: JsValue, fieldName: String): String = {
+    fetchJsonBodyValue(bodyJson, fieldName).as[String]
+  }
+
+  /**
+   * Fetch the ObjectId value of the field name from the JSON.
+   * 
+   * @param bodyJson The JSON.
+   * @param fieldName The field name.
+   * 
+   * @throws InvalidRequestBodyException if the value is not a valid ID.
+   */
+  def fetchJsonBodyObjectId(bodyJson: JsValue, fieldName: String): ObjectId = {
+    val value: String = fetchJsonBodyValue(bodyJson, fieldName).as[String]
+    if (!ObjectId.isValid(value)) throw new InvalidRequestBodyException("Invalid ID format: " + fieldName)
+    new ObjectId(value)
+  }
+}
diff --git a/backend-services/feed-service/app/controllers/HomeController.scala b/backend-services/feed-service/app/controllers/HomeController.scala
index 60a6e853619c672b573c0e1b974e44f16f86bf5d..690b3253a378e05dc38d82e2db65a68318237947 100644
--- a/backend-services/feed-service/app/controllers/HomeController.scala
+++ b/backend-services/feed-service/app/controllers/HomeController.scala
@@ -1,7 +1,6 @@
 package controllers
 
 import javax.inject._
-import play.api._
 import play.api.mvc._
 
 /**
@@ -18,7 +17,7 @@ class HomeController @Inject()(val controllerComponents: ControllerComponents) e
    * will be called when the application receives a `GET` request with
    * a path of `/`.
    */
-  def index() = Action { implicit request: Request[AnyContent] =>
+  def index() = Action {
     Ok("OK")
   }
 }
diff --git a/backend-services/feed-service/app/controllers/MongoTestController.scala b/backend-services/feed-service/app/controllers/MongoTestController.scala
deleted file mode 100644
index c086129a767005645bf5a1b040cb5375a3f0914e..0000000000000000000000000000000000000000
--- a/backend-services/feed-service/app/controllers/MongoTestController.scala
+++ /dev/null
@@ -1,49 +0,0 @@
-package controllers
-
-import javax.inject._
-import play.api._
-import play.api.mvc._
-
-import models.MongoDBClient
-import org.mongodb.scala.{Document}
-import scala.concurrent.ExecutionContext.Implicits.global
-import scala.concurrent.{Future, Await, TimeoutException}
-import scala.concurrent.duration._
-
-/**
- * This controller creates an `Action` to handle HTTP MongoDB requests.
- */
-@Singleton
-class MongoTestController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
-
-    /**
-    * Create an Action to test the Mongo Client.
-    */
-    def index() = Action { implicit request: Request[AnyContent] =>
-        println("MongoController")
-
-        var database_name = "{DATABASE_NAME}"
-        var collection_name = "{COLLECTION_NAME}"
-
-        var mongo = new MongoDBClient()
-
-        // Sequentially waits for Future objects to complete before calling next method
-        val result: Future[Seq[Document]] = for {
-            db <- mongo.getDatabase(database_name)
-            collection <- mongo.getCollection(db, collection_name)
-            findResult <- mongo.find(collection)
-        } yield findResult
-
-
-        try {
-            // Wait for 10 seconds for the Future to complete
-            val resultCompleted = Await.result(result, 4.seconds)
-
-            val jsonResult: Seq[String] = resultCompleted.map(doc => doc.toJson())
-            Ok(jsonResult.toString())
-        } catch {
-            case e: TimeoutException =>
-                BadRequest("Request timed out")
-        }
-    }
-}
diff --git a/backend-services/feed-service/app/controllers/TestController.scala b/backend-services/feed-service/app/controllers/TestController.scala
new file mode 100644
index 0000000000000000000000000000000000000000..123a9d0ebcd253ce5edbce811c69a9d8cc6e3b9d
--- /dev/null
+++ b/backend-services/feed-service/app/controllers/TestController.scala
@@ -0,0 +1,39 @@
+package controllers
+
+import models.actions.AuthenticatedUserAction
+
+import javax.inject._
+import play.api.mvc._
+import play.api.libs.json.{JsString, JsArray}
+import play.api.libs.json.JsBoolean
+
+/**
+ * This controller creates an `Action` to handle HTTP requests to the
+ * application's test page.
+ */
+@Singleton
+class TestController @Inject()(val controllerComponents: ControllerComponents, authenticatedUserAction: AuthenticatedUserAction)
+    extends BaseController {
+
+    def getFriends(userId: String) = authenticatedUserAction {
+        println("TestController:getFriends")
+        println(s"Fetching friends for User with ID {$userId}")
+
+        val response = JsArray(
+            Seq(
+                JsString("641128f7e80bcd1ba39d04ae"), 
+                JsString("641128f7e80bcd1ba39d04af"), 
+                JsString("641128f7e80bcd1ba39d04aa")
+            )
+        )
+        
+        Ok(response)
+    }
+
+    def verifyUser(userId: String) = authenticatedUserAction {
+        println("TestController:verifyUser")
+        println(s"Verifying User with ID {$userId}")
+        
+        Ok(JsBoolean(true))
+    }
+}
diff --git a/backend-services/feed-service/app/models/Daily.scala b/backend-services/feed-service/app/models/Daily.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b4eda23e7fdcc1ffeb790a951e133087066f2f9d
--- /dev/null
+++ b/backend-services/feed-service/app/models/Daily.scala
@@ -0,0 +1,200 @@
+package models
+
+import repositories.{DailyRepository}
+import models.exceptions.{ConflictException, NotFoundException}
+
+import scala.concurrent.ExecutionContext.Implicits.global
+import scala.concurrent.{Future, Await}
+import scala.concurrent.duration._
+
+import org.bson.types.ObjectId
+import java.util.Date
+import java.time.Instant
+import java.text.SimpleDateFormat
+
+import play.api.libs.json.{Json, JsValue, JsString, JsObject, JsArray}
+
+import org.bson.{BsonWriter, BsonReader, BsonType}
+import org.bson.codecs.{Codec, EncoderContext, DecoderContext}
+import org.bson.conversions.Bson
+import org.mongodb.scala.model.Updates
+
+case class Daily(
+    id: Option[ObjectId],
+    userId: ObjectId,
+    questionId: ObjectId,
+    content: String,
+    usersLiked: Seq[ObjectId],
+    createdAt: Date,
+    updatedAt: Date
+)
+
+object Daily {
+    val dailyRepo = new DailyRepository()
+
+    def createDailyAsync(
+        userId: ObjectId,
+        questionId: ObjectId,
+        content: String,
+        timeout: Int = 4
+    ): Daily = {
+        val now: Date = Date.from(Instant.now())
+        val daily: Daily = Daily(None, userId, questionId, content, Seq.empty[ObjectId], now, now)
+        val future: Future[Daily] = dailyRepo.insertDaily(daily)
+        Await.result[Daily](future, timeout.seconds)
+    }
+
+    def getAllDailiesAsync(timeout: Int = 4): Seq[Daily] = {
+        val future: Future[Seq[Daily]] = dailyRepo.getAll()
+        Await.result[Seq[Daily]](future, timeout.seconds)
+    }
+
+    def getUserDailiesAsync(userId: ObjectId, timeout: Int = 4): Seq[Daily] = {
+        val future: Future[Seq[Daily]] = dailyRepo.getByValue("user_id", userId)
+        Await.result[Seq[Daily]](future, timeout.seconds)
+    }
+
+    def getUserFeedAsync(userId: ObjectId, jwt: String, timeout: Int = 4): Seq[Daily] = {
+        // Sequentially waits for Future objects to complete before calling next method
+        val result: Future[Seq[Daily]] = for {
+            friends: Seq[ObjectId] <- User.getUserFriends(userId, jwt)
+            feed: Seq[Daily] <- dailyRepo.getByValues[ObjectId]("user_id", friends)
+        } yield feed
+
+        Await.result[Seq[Daily]](result, timeout.seconds)
+    }
+
+    def likeAsync(dailyId: ObjectId, likerId: ObjectId, jwt: String, timeout: Int = 4): Unit = {
+        val result: Future[Unit] = for {
+            // Fetch Daily from given ID
+            daily: Daily  <- {
+                dailyRepo.getById(dailyId).map((oDaily: Option[Daily]) => {
+                    if (oDaily.isEmpty) 
+                        throw new NotFoundException("No daily with given ID.") 
+                    else 
+                        oDaily.get
+                })
+            }
+
+            // Check user has not already liked the Daily
+            _ = if (daily.usersLiked.contains(likerId)) throw new ConflictException("User has already liked this Daily.")
+
+            // Check user with given ID exists
+            _ <- User.userExists(likerId, jwt).map((exists: Boolean) => if (!exists) throw new NotFoundException("No user with given ID."))
+
+            like: Unit <- {
+                val updatedUsersLiked: Seq[ObjectId] = daily.usersLiked :+ likerId
+                val update: Bson = Updates.set("usersLiked", updatedUsersLiked)
+
+                dailyRepo.updateOne(dailyId, Seq(update))
+            }
+        } yield like
+
+        Await.result[Unit](result, timeout.seconds)
+    }
+
+    def unlikeAsync(dailyId: ObjectId, likerId: ObjectId, jwt: String, timeout: Int = 4): Unit = {
+        val result: Future[Unit] = for {
+            // Fetch Daily from given ID
+            daily: Daily  <- {
+                dailyRepo.getById(dailyId).map((oDaily: Option[Daily]) => {
+                    if (oDaily.isEmpty) 
+                        throw new NotFoundException("No daily with given ID.") 
+                    else 
+                        oDaily.get
+                })
+            }
+
+            // Check user with given ID exists
+            _ <- User.userExists(likerId, jwt).map((exists: Boolean) => if (!exists) throw new NotFoundException("No user with given ID."))
+
+            // Check user has liked the Daily
+            _ = if (!daily.usersLiked.contains(likerId)) throw new ConflictException("User has not liked this Daily.")
+
+            unlike: Unit <- {
+                val updatedUsersLiked: Seq[ObjectId] = daily.usersLiked.filterNot(_ == likerId)
+                val update: Bson = Updates.set("usersLiked", updatedUsersLiked)
+
+                dailyRepo.updateOne(dailyId, Seq(update))
+            }
+        } yield unlike
+
+        Await.result[Unit](result, timeout.seconds)
+    }
+
+    // Convert from Daily object to JSON (serializing to JSON)
+    def toJson(daily: Daily): JsValue = {
+        val usersLikedAsJsStrings: Seq[JsString] = daily.usersLiked.map[JsString](id => JsString(id.toString()))
+
+        val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+        val formattedCreatedAt: String = dateFormat.format(daily.createdAt)
+        val formattedUpdatedAt: String = dateFormat.format(daily.updatedAt)
+
+        val dailyJson = Seq(
+            "id" -> JsString(daily.id.getOrElse("").toString()),
+            "userId" -> JsString(daily.userId.toString()),
+            "questionId" -> JsString(daily.questionId.toString()),
+            "content" -> JsString(daily.content),
+            "usersLiked" -> JsArray(usersLikedAsJsStrings),
+            "createdAt" -> JsString(formattedCreatedAt),
+            "updatedAt" -> JsString(formattedUpdatedAt)
+        )
+        
+        Json.toJson[JsObject](JsObject(dailyJson))
+    }
+
+    // Convert from Daily set to JSON (serializing to JSON)
+    def toJson(dailies: Seq[Daily]): JsValue = {
+        val dailiesJson: Seq[JsValue] = dailies.map(daily => Daily.toJson(daily))
+
+        Json.toJson[JsArray](JsArray(dailiesJson))
+    }
+
+    def toString(daily: Daily): String =
+        return s"Daily(${daily.id.toString()}, ${daily.userId.toString()}, ${daily.questionId.toString()}, ${daily.content}, ${daily.usersLiked.toString()})"
+
+    // Codec instance for serialising/deserialising type User to or from BSON.
+    // Implicit keyword lets Scala compiler automatically insert this into the code where it's needed.
+    implicit val codec: Codec[Daily] = new Codec[Daily] {
+        override def encode(writer: BsonWriter, value: Daily, encoderContext: EncoderContext): Unit = {
+            writer.writeStartDocument()
+            writer.writeObjectId("user_id", value.userId)
+            writer.writeObjectId("question_id", value.questionId)
+            writer.writeString("content", value.content)
+            writer.writeStartArray("usersLiked")
+            value.usersLiked.foreach(writer.writeObjectId)
+            writer.writeEndArray()
+            writer.writeDateTime("createdAt", value.createdAt.getTime())
+            writer.writeDateTime("updatedAt", value.updatedAt.getTime())
+            writer.writeEndDocument()
+        }
+
+        override def decode(reader: BsonReader, decoderContext: DecoderContext): Daily = {
+            reader.readStartDocument()
+            val id = reader.readObjectId("_id")
+            val userId = reader.readObjectId("user_id")
+            val questionId = reader.readObjectId("question_id")
+            val content = reader.readString("content")
+            val usersLiked = {
+                reader.readName("usersLiked")
+                reader.readStartArray()
+                val buffer = collection.mutable.Buffer.empty[ObjectId]
+                while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
+                    buffer += reader.readObjectId()
+                }
+                reader.readEndArray()
+                buffer.toSeq
+            }
+            val createdAt = reader.readDateTime("createdAt")
+            val updatedAt = reader.readDateTime("updatedAt")
+            reader.readEndDocument()
+
+            val createdAtDate: Date = Date.from(Instant.ofEpochMilli(createdAt))
+            val updatedAtDate: Date = Date.from(Instant.ofEpochMilli(updatedAt))
+
+            Daily(Some(id), userId, questionId, content, usersLiked, createdAtDate, updatedAtDate)
+        }
+
+        override def getEncoderClass: Class[Daily] = classOf[Daily]
+    }
+}
diff --git a/backend-services/feed-service/app/models/HttpCall.scala b/backend-services/feed-service/app/models/HttpCall.scala
new file mode 100644
index 0000000000000000000000000000000000000000..cef4e4294d427aa8fe5e0b3f9937fae214ebbc69
--- /dev/null
+++ b/backend-services/feed-service/app/models/HttpCall.scala
@@ -0,0 +1,59 @@
+package models
+
+import akka.actor.ActorSystem
+import akka.stream.{Materializer, SystemMaterializer}
+import play.api.libs.ws.ahc.{StandaloneAhcWSClient}
+import play.api.libs.ws.StandaloneWSRequest
+import play.api.libs.json.JsValue
+
+import scala.concurrent.Future
+import scala.concurrent.ExecutionContext.Implicits.global
+
+
+object HttpCall {
+
+    /**
+     * Fetches the response of a GET request to the given URL.
+     * 
+     * @param url The URL of the request.
+     * 
+     * @return a Future containing the response body as a JSON.
+     */
+    def get(
+          url: String, 
+          queryStringParameters: Seq[(String, String)] = Seq.empty[(String, String)], 
+          jwt: String = ""
+      ): Future[JsValue] = {
+        // Create ActorSystem for thread and streaming management
+        implicit val system: ActorSystem = ActorSystem()
+
+        // Materializer ensures streams are executed correctly and resources are managed efficiently
+        implicit val materializer: Materializer = SystemMaterializer(system).materializer
+
+        // Create the standalone WS client
+        val wsClient: StandaloneAhcWSClient = StandaloneAhcWSClient()
+
+        // Create base request
+        var request: StandaloneWSRequest = wsClient.url(url)
+
+        // Add query parameters to request
+        request = request.addQueryStringParameters(queryStringParameters: _*)
+
+        // Add JWT header to request, if supplied
+        request = if (!jwt.isEmpty()) request.addHttpHeaders(("Authorization", s"Bearer $jwt")) else request
+
+        // Call API and fetch response
+        val response: Future[JsValue] = request.get().map(response => {
+            if (response.status > 399) throw new RuntimeException()
+
+            val statusText: String = response.statusText
+            println(s"Got a response: $statusText")
+            response.body[JsValue]
+        })
+
+        // Close WSClient and terminate ActorSystem
+        response
+            .andThen { case _ => wsClient.close() }
+            .andThen { case _ => system.terminate() }
+    }
+}
diff --git a/backend-services/feed-service/app/models/MongoDBClient.scala b/backend-services/feed-service/app/models/MongoDBClient.scala
deleted file mode 100644
index 96c5dd630909f964630b16097b7fb77cb7820711..0000000000000000000000000000000000000000
--- a/backend-services/feed-service/app/models/MongoDBClient.scala
+++ /dev/null
@@ -1,96 +0,0 @@
-package models
-
-import utils.ConfigHelper
-
-import org.mongodb.scala.{MongoClient, MongoDatabase, MongoCollection, Document, FindObservable, Observer, Observable}
-import org.mongodb.scala.model.{Filters, Projections, Sorts}
-import org.bson.conversions.Bson
-
-import scala.concurrent.ExecutionContext.Implicits.global
-import scala.concurrent.Future
-import scala.util.{Success, Failure, Try}
-
-
-/**
- * A MongoDB client for connecting to and interacting with a MongoDB database.
- * 
- * @constructor Creates a new instance of the MongoDBClient class.
- */
-class MongoDBClient {
-    private val mongoUri = ConfigHelper.getString("mongodb.uri")
-
-    // Connects to a MongoDB Client when class is constructed
-    private var client: MongoClient = this.connect()
-
-    /**
-     * Connects to a MongoDB database using the default MongoDB connection string.
-     * 
-     * @return A MongoClient instance.
-     */
-    def connect(): MongoClient = {
-        MongoClient(mongoUri)
-    }
-
-    /**
-     * Gets a reference to a MongoDB database.
-     * 
-     * @param database The name of the database to retrieve.
-     * @return A Future containing a MongoDatabase instance.
-     */
-    def getDatabase(database: String): Future[MongoDatabase] = Future {
-        client.getDatabase(database)
-    }
-
-    /**
-     * Gets a reference to a MongoDB collection within a database.
-     * 
-     * @param database The MongoDatabase instance containing the desired collection.
-     * @param collection The name of the collection to retrieve.
-     * @return A Future containing a MongoCollection instance.
-     */
-    def getCollection(database: MongoDatabase, collection: String): Future[MongoCollection[Document]] = Future {
-        database.getCollection(collection)
-    }
-
-    /**
-     * Finds documents in a MongoDB collection.
-     * 
-     * @param collection The MongoCollection instance to search.
-     * @param filter A Bson filter to apply to the search.
-     * @param projection A Bson projection to apply to the search.
-     * @param sort A Bson sort to apply to the search.
-     * @return A Future containing a sequence of matching documents as Documents.
-     */
-    def find(
-        collection: MongoCollection[Document], 
-        filter: Bson = Filters.empty(), 
-        projection: Bson = Projections.excludeId(),
-        sort: Bson = Sorts.ascending("_id")
-    ): Future[Seq[Document]] = {
-        collection.find(filter)
-        .projection(projection)
-        .sort(sort)
-        .toFuture()
-    }
-
-    /**
-     * Inserts a document into a MongoDB collection.
-     * 
-     * @param collection The MongoCollection instance to insert into.
-     * @param document The document to insert.
-     * @return A Future containing the ID of the inserted document.
-     * @throws RuntimeException if the insertion was not acknowledged by the database.
-     */
-    def insertOne(collection: MongoCollection[Document], document: Document): Future[String] = {
-        val futureResult = collection.insertOne(document).toFuture()
-        
-        futureResult.map(result => {
-            if (result.wasAcknowledged()) {
-                // Grab the generated ID of the inserted document
-                result.getInsertedId().asObjectId.getValue().toString()
-            } else {
-                throw new RuntimeException("Insertion was not acknowledged")
-            }
-        })
-    }
-}
diff --git a/backend-services/feed-service/app/models/User.scala b/backend-services/feed-service/app/models/User.scala
new file mode 100644
index 0000000000000000000000000000000000000000..8556770ce2776d6ad9ca035ecba745f325d51bb7
--- /dev/null
+++ b/backend-services/feed-service/app/models/User.scala
@@ -0,0 +1,28 @@
+package models
+
+import models.HttpCall
+
+import play.api.libs.json.JsValue
+import org.bson.types.ObjectId
+import scala.concurrent.Future
+import scala.concurrent.ExecutionContext.Implicits.global
+
+
+object User {
+    def getUserFriends(userId: ObjectId, jwt: String): Future[Seq[ObjectId]] = {
+        val url: String = "http://localhost:9000/test/getFriends"
+        val queryStringParameters: Seq[(String, String)] = Seq(("userId", userId.toString()))
+        
+        HttpCall.get(url, queryStringParameters, jwt).map[Seq[ObjectId]]((json: JsValue) => {
+            val sequence: Seq[String] = json.as[Seq[String]]
+            sequence.map[ObjectId](new ObjectId(_))
+        })
+    }
+
+    def userExists(userId: ObjectId, jwt: String): Future[Boolean] = {
+        val url: String = "http://localhost:9000/test/verifyUser"
+        val queryStringParameters: Seq[(String, String)] = Seq(("userId", userId.toString()))
+        
+        HttpCall.get(url, queryStringParameters, jwt).map[Boolean](_.as[Boolean])
+    }
+}
diff --git a/backend-services/feed-service/app/models/actions/AuthenticatedUserAction.scala b/backend-services/feed-service/app/models/actions/AuthenticatedUserAction.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b4351c78237b548275f97be4d85dd3d923479ea4
--- /dev/null
+++ b/backend-services/feed-service/app/models/actions/AuthenticatedUserAction.scala
@@ -0,0 +1,35 @@
+package models.actions
+
+import models.actions.AuthenticationRequest
+
+import play.api.mvc.{ActionBuilder, BodyParsers, Request, Result, AnyContent, Cookie}
+import play.filters.csrf.CSRF
+
+import javax.inject.Inject
+import scala.concurrent.{Future, ExecutionContext}
+
+
+/**
+ * The authentication action builder that combines the request transformation and filtering.
+ */
+class AuthenticatedUserAction @Inject()(authenticationTransformer: AuthenticationTransformer, authenticationFilter: AuthenticationFilter)
+                                       (implicit val parser: BodyParsers.Default, val executionContext: ExecutionContext)
+    extends ActionBuilder[AuthenticationRequest, AnyContent] {
+
+    /**
+     * Invoke the main controller block, with the transformations and filtering middleware, and the CSRF token injection.
+     *
+     * @param request The incoming request.
+     * @param block The block of code to invoke.
+     * @return A future of the result.
+     */
+    override def invokeBlock[A](request: Request[A], block: AuthenticationRequest[A] => Future[Result]): Future[Result] = {
+        val result: Future[Result] = (authenticationTransformer andThen authenticationFilter).invokeBlock(request, block)
+
+        (result).map(_result => {
+            // Add CSRF token to response
+            val token = CSRF.getToken(request).map(_.value).getOrElse("")
+            _result.withHeaders("Csrf-Token" -> token).withCookies(Cookie(name = "PLAY_CSRF_TOKEN", value = token))
+        })
+    }
+}
diff --git a/backend-services/feed-service/app/models/actions/AuthenticationFilter.scala b/backend-services/feed-service/app/models/actions/AuthenticationFilter.scala
new file mode 100644
index 0000000000000000000000000000000000000000..8b7b752ae310c539ac8beaaddeb1db6f38ba1074
--- /dev/null
+++ b/backend-services/feed-service/app/models/actions/AuthenticationFilter.scala
@@ -0,0 +1,29 @@
+package models.actions
+
+import models.actions.AuthenticationRequest
+import play.api.mvc.{ActionFilter, Result, Results}
+
+import scala.concurrent.{Future, ExecutionContext}
+
+import javax.inject.Inject
+
+
+/**
+ * The authentication action filter that verifies the request contains a user ID.
+ */
+class AuthenticationFilter @Inject() (implicit val executionContext: ExecutionContext) extends ActionFilter[AuthenticationRequest] {
+    
+    /**
+     * Determines whether to process a request.
+     * Decides whether to immediately intercept the request or continue processing the request.
+     *
+     * @param request The incoming request.
+     * @return An optional Forbidden Result with which to abort the request.
+     */
+    override def filter[A](request: AuthenticationRequest[A]): Future[Option[Result]] = Future.successful {
+        if (!request.requesterId.isDefined) 
+            Some(Results.Forbidden("Invalid JWT Token"))
+        else
+            None
+    }
+}
diff --git a/backend-services/feed-service/app/models/actions/AuthenticationRequest.scala b/backend-services/feed-service/app/models/actions/AuthenticationRequest.scala
new file mode 100644
index 0000000000000000000000000000000000000000..6573cd1596c44d8778c4bdf9ceae0c4389d8a42b
--- /dev/null
+++ b/backend-services/feed-service/app/models/actions/AuthenticationRequest.scala
@@ -0,0 +1,66 @@
+package models.actions
+
+import com.typesafe.config.ConfigFactory
+
+import play.api.mvc.{ActionTransformer, Request, WrappedRequest}
+
+import scala.concurrent.{Future, ExecutionContext}
+import scala.util.Try
+import org.bson.types.ObjectId
+
+import pdi.jwt.{JwtJson, JwtAlgorithm, JwtClaim}
+import play.api.libs.json.Json
+
+import javax.inject.Inject
+
+
+class AuthenticationRequest[A](val jwt: String, val requesterId: Option[ObjectId], request: Request[A]) 
+    extends WrappedRequest[A](request)
+
+
+/**
+ * The authentication action transformer that transforms the incoming base request to a user request.
+ */
+class AuthenticationTransformer @Inject() (implicit val executionContext: ExecutionContext) extends ActionTransformer[Request, AuthenticationRequest] {
+
+    /**
+     * Transforms the existing request from a Request to UserRequest.
+     *
+     * @param request The incoming request.
+     * @return The new parameter to pass to the Action block.
+     */
+    override def transform[A](request: Request[A]) = Future.successful {
+        val (jwt: String, requesterId: Option[ObjectId]) = processJWT(request)
+        new AuthenticationRequest(jwt, requesterId, request)
+    }
+
+    /**
+     * Processes the JWT token by decoding and validating it.
+     *
+     * @param request The incoming request.
+     * @return The user ID specified in the JWT's payload.
+     */
+    def processJWT[A](request: Request[A]): (String, Option[ObjectId]) = {
+        val privateKey = ConfigFactory.load().getString("jwt.privateKey")
+
+        try {
+            val authHeader = request.headers.get("Authorization").get
+            val token = authHeader.substring(7)
+            println(s"JWT Token Received: $token")
+
+            val payload: Try[JwtClaim] = JwtJson.decode(token, privateKey, Seq(JwtAlgorithm.HS256))
+
+            val content = payload.get.content
+            val jsonContent = Json.parse(content)
+            val requesterId = (jsonContent \ "userId").as[String]
+            
+            (token, Some(new ObjectId(requesterId)))
+        }
+        catch {
+            case ex: Throwable => {
+                println(s"JWT Error: $ex")
+                ("", None)
+            }
+        }
+    }
+}
diff --git a/backend-services/feed-service/app/models/exceptions/ConflictException.scala b/backend-services/feed-service/app/models/exceptions/ConflictException.scala
new file mode 100644
index 0000000000000000000000000000000000000000..bf99cc11e61694842f0f160c76a889a78aab8507
--- /dev/null
+++ b/backend-services/feed-service/app/models/exceptions/ConflictException.scala
@@ -0,0 +1,3 @@
+package models.exceptions
+
+case class ConflictException(message: String) extends Exception(message)
diff --git a/backend-services/feed-service/app/models/exceptions/InvalidObjectIdValueException.scala b/backend-services/feed-service/app/models/exceptions/InvalidObjectIdValueException.scala
new file mode 100644
index 0000000000000000000000000000000000000000..582699b04c3ba49a911bd3ba544071d98b87afd2
--- /dev/null
+++ b/backend-services/feed-service/app/models/exceptions/InvalidObjectIdValueException.scala
@@ -0,0 +1,3 @@
+package models.exceptions
+
+case class InvalidObjectIdValueException(message: String) extends Exception(message)
diff --git a/backend-services/feed-service/app/models/exceptions/InvalidQueryParameterException.scala b/backend-services/feed-service/app/models/exceptions/InvalidQueryParameterException.scala
new file mode 100644
index 0000000000000000000000000000000000000000..7acff65ebbbea9e3a2b960db92535a160a270826
--- /dev/null
+++ b/backend-services/feed-service/app/models/exceptions/InvalidQueryParameterException.scala
@@ -0,0 +1,3 @@
+package models.exceptions
+
+case class InvalidQueryParameterException(message: String) extends Exception(message)
diff --git a/backend-services/feed-service/app/models/exceptions/InvalidRequestBodyException.scala b/backend-services/feed-service/app/models/exceptions/InvalidRequestBodyException.scala
new file mode 100644
index 0000000000000000000000000000000000000000..744142c69e270ad8edff0ecdad6880502552fd7e
--- /dev/null
+++ b/backend-services/feed-service/app/models/exceptions/InvalidRequestBodyException.scala
@@ -0,0 +1,3 @@
+package models.exceptions
+
+case class InvalidRequestBodyException(message: String) extends Exception(message)
diff --git a/backend-services/feed-service/app/models/exceptions/NotFoundException.scala b/backend-services/feed-service/app/models/exceptions/NotFoundException.scala
new file mode 100644
index 0000000000000000000000000000000000000000..edd62c3f6713f21512da8db56d2c2f543f233a43
--- /dev/null
+++ b/backend-services/feed-service/app/models/exceptions/NotFoundException.scala
@@ -0,0 +1,3 @@
+package models.exceptions
+
+case class NotFoundException(message: String) extends Exception(message)
diff --git a/backend-services/feed-service/app/repositories/DailyRepository.scala b/backend-services/feed-service/app/repositories/DailyRepository.scala
new file mode 100644
index 0000000000000000000000000000000000000000..514860f212551d4ba8f6a6cbd670a19707dcfa2d
--- /dev/null
+++ b/backend-services/feed-service/app/repositories/DailyRepository.scala
@@ -0,0 +1,31 @@
+package repositories
+
+import models.Daily
+import utils.MongoConnection
+
+import com.typesafe.config.ConfigFactory
+import org.bson.types.ObjectId
+
+import scala.concurrent.ExecutionContext.Implicits.global
+import scala.concurrent.Future
+
+
+class DailyRepository extends Repository[Daily] (
+    ConfigFactory.load().getString("mongo.feedService.db"),
+    ConfigFactory.load().getString("mongo.dailies.collection")
+) {
+    /**
+     * Inserts a Daily record into the database.
+     * 
+     * @return A Future containing the inserted Daily object with the generated ID.
+     */
+    def insertDaily(daily: Daily): Future[Daily] = {
+        val result: Future[String] = MongoConnection.insertOne[Daily](collection, daily)
+
+        // Return a Daily entity with the generated ID
+        result.flatMap[Daily](id => {
+            val updatedDaily: Daily = daily.copy(id = Some(new ObjectId(id)))
+            Future.successful(updatedDaily)
+        })
+    }
+}
diff --git a/backend-services/feed-service/app/repositories/Repository.scala b/backend-services/feed-service/app/repositories/Repository.scala
new file mode 100644
index 0000000000000000000000000000000000000000..4cb446e36575e453b3b100ed5d77b54e9ef9ac90
--- /dev/null
+++ b/backend-services/feed-service/app/repositories/Repository.scala
@@ -0,0 +1,102 @@
+package repositories
+
+import utils.ConfigHelper
+
+import utils.MongoConnection
+
+import org.mongodb.scala.{MongoClient, MongoDatabase, MongoCollection}
+import org.mongodb.scala.model.Filters
+import org.bson.types.ObjectId
+import org.bson.conversions.Bson
+
+import scala.concurrent.ExecutionContext.Implicits.global
+import scala.concurrent.{Future, Await}
+import scala.concurrent.duration._
+import scala.reflect.ClassTag
+
+
+/**
+ * The base repository class that provides basic CRUD operations for a MongoDB collection.
+ *
+ * @tparam T The type of objects stored in the collection.
+ * @param databaseName The name of the MongoDB database to use.
+ * @param collectionName The name of the MongoDB collection to use.
+ */
+class Repository[T: ClassTag](databaseName: String, collectionName: String) {
+
+    /**
+    * Returns a reference to a MongoDB collection within a database.
+    * Once Future completes, collection reference is returned. 
+    *
+    * @return a MongoCollection[T] object representing the collection.
+    * @throws TimeoutException if the Future doesn't complete within the 3 second timeout.
+    */
+    protected val collection: MongoCollection[T] = {
+        val mongoUri: String = ConfigHelper.getString("mongodb.uri")
+
+        val futureCollection: Future[MongoCollection[T]] = for {
+            client: MongoClient <- MongoConnection.getClient(mongoUri)
+            database: MongoDatabase <- MongoConnection.getDatabase(client, databaseName)
+            collection: MongoCollection[T] <- MongoConnection.getCollection[T](database, collectionName)
+        } yield collection: MongoCollection[T]
+
+        Await.result[MongoCollection[T]](futureCollection, 3.seconds)
+    }
+
+    /**
+     * Gets all the records in the collection.
+     * 
+     * @return A Future containing a sequence of the collection's records.
+     */
+    def getAll(): Future[Seq[T]] = {
+        MongoConnection.find[T](collection)
+    }
+
+    /**
+     * Gets a record with the given ID in the collection.
+     * 
+     * @return A Future containing an optional matching document.
+     */
+    def getById(id: ObjectId): Future[Option[T]] = {
+        val filter: Bson = Filters.equal[ObjectId]("_id", id)
+        MongoConnection.find[T](collection, filter).map(_.headOption)
+    }
+
+    /**
+     * Retrieves records from the collection that have the specified value for the given field name.
+     *
+     * @tparam V The type of the query value.
+     * @param field_name The name of the field to search for.
+     * @param value The value to search for.
+     * 
+     * @return A Future containing a sequence of matching documents.
+     */
+    def getByValue[V](field_name: String, value: V): Future[Seq[T]] = {
+        val filter: Bson = Filters.equal[V](field_name, value)
+        MongoConnection.find[T](collection, filter)
+    }
+
+    /**
+     * Retrieves records from the collection that contain any of the specified values for the given field name.
+     *
+     * @tparam V The type of the query values.
+     * @param field_name The name of the field to search for.
+     * @param value A sequence of values to search for.
+     * 
+     * @return A Future containing a sequence of matching documents.
+     */
+    def getByValues[V](field_name: String, values: Seq[V]): Future[Seq[T]] = {
+        val filter: Bson = Filters.in[V](field_name, values: _*)
+        MongoConnection.find[T](collection, filter)
+    }
+
+    /**
+     * Updates a document in the collection.
+     * 
+     * @param documentId The ID of the document to update.
+     * @param updates A sequence of Bson documents defining the updates.
+     */
+    def updateOne(documentId: ObjectId, updates: Seq[Bson]): Future[Unit] = {
+        MongoConnection.updateOne[T](collection, documentId, updates)
+    }
+}
diff --git a/backend-services/feed-service/app/utils/MongoCodecs.scala b/backend-services/feed-service/app/utils/MongoCodecs.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f755d934f1c9b77a513fd8f0bf4d0664ec74a984
--- /dev/null
+++ b/backend-services/feed-service/app/utils/MongoCodecs.scala
@@ -0,0 +1,26 @@
+package utils
+
+import models.Daily
+import org.bson.codecs.Codec
+import org.bson.codecs.configuration.{CodecProvider, CodecRegistry, CodecRegistries}
+
+import org.mongodb.scala.MongoClient
+
+object MongoCodecs {
+    // Define a custom CodecProvider that returns a Codec for the case classes
+    val customCodecProvider = new CodecProvider {
+        override def get[T](clazz: Class[T], registry: CodecRegistry): Codec[T] = {
+            if (clazz == classOf[Daily]) {
+                // If the class is the Daily case class, return the Daily codec
+                Daily.codec.asInstanceOf[Codec[T]]
+            }
+            else {
+                // If the class is not the User case class, return null
+                null
+            }
+        }
+    }
+
+    // Create a CodecRegistry that includes the custom CodecProvider and the default codecs
+    val codecRegistry: CodecRegistry = CodecRegistries.fromProviders(customCodecProvider, MongoClient.DEFAULT_CODEC_REGISTRY)
+}
diff --git a/backend-services/feed-service/app/utils/MongoConnection.scala b/backend-services/feed-service/app/utils/MongoConnection.scala
new file mode 100644
index 0000000000000000000000000000000000000000..04ca348a8010d87e0ee83621819b28d8a6b3b3ab
--- /dev/null
+++ b/backend-services/feed-service/app/utils/MongoConnection.scala
@@ -0,0 +1,118 @@
+package utils
+
+import org.mongodb.scala.{MongoClient, MongoDatabase, MongoCollection}
+import org.mongodb.scala.model.{Filters, Sorts}
+import com.mongodb.client.result.{InsertOneResult, UpdateResult}
+
+import org.bson.conversions.Bson
+import org.bson.types.ObjectId
+
+import scala.concurrent.ExecutionContext.Implicits.global
+import scala.concurrent.Future
+import scala.reflect.ClassTag
+
+import utils.MongoCodecs
+
+
+/**
+ * Mongo helper functions for connecting to and interacting with MongoDB clients, databases, and collections.
+ * 
+ * All functions return a Future.
+ */
+object MongoConnection {
+    /**
+     * Connects to and gets a reference to a MongoDB client.
+     * 
+     * @param mongoUri The connection string.
+     * @return A Future containing the MongoClient instance.
+     */
+    def getClient(mongoUri: String): Future[MongoClient] = Future {
+        MongoClient(mongoUri)
+    }
+
+    /**
+     * Gets a reference to a MongoDB database.
+     * 
+     * @param database The name of the database to retrieve.
+     * @return A Future containing a MongoDatabase instance.
+     */
+    def getDatabase(client: MongoClient, database: String): Future[MongoDatabase] = Future {
+        client.getDatabase(database).withCodecRegistry(MongoCodecs.codecRegistry)
+    }
+
+    /**
+     * Gets a reference to a MongoDB collection within a database.
+     * 
+     * @param database The MongoDatabase instance containing the desired collection.
+     * @param collection The name of the collection to retrieve.
+     * @return A Future containing a MongoCollection instance.
+     */
+    def getCollection[T: ClassTag](database: MongoDatabase, collection: String): Future[MongoCollection[T]] = Future {
+        database.getCollection[T](collection)
+    }
+
+    /**
+     * Finds documents in a MongoDB collection.
+     * 
+     * @param collection The MongoCollection instance to search.
+     * @param filter A Bson filter to apply to the search.
+     * @param projection A Bson projection to apply to the search.
+     * @param sort A Bson sort to apply to the search.
+     * @return A Future containing a sequence of matching documents as Documents.
+     */
+    def find[T: ClassTag](
+        collection: MongoCollection[T], 
+        filter: Bson = Filters.empty(), 
+        sort: Bson = Sorts.ascending("_id"),
+        projection: Option[Bson] = None
+    ): Future[Seq[T]] = {
+        var result = collection.find[T](filter).sort(sort)
+
+        result = if (projection.isDefined == true)
+            result.projection(projection.get)
+        else
+            result
+        
+        result.toFuture()
+    }
+
+    /**
+     * Inserts a document into a MongoDB collection.
+     * 
+     * @param collection The MongoCollection instance to insert into.
+     * @param document The document to insert.
+     * @return A Future containing the ID of the inserted document.
+     * @throws RuntimeException if the insertion was not acknowledged by the database.
+     */
+    def insertOne[T](collection: MongoCollection[T], document: T): Future[String] = {
+        val futureResult: Future[InsertOneResult] = collection.insertOne(document).toFuture()
+        
+        futureResult.map[String]((result: InsertOneResult) => {
+            if (result.wasAcknowledged()) {
+                // Grab the generated ID of the inserted document
+                result.getInsertedId().asObjectId.getValue().toString()
+            } else {
+                throw new RuntimeException("Insertion was not acknowledged")
+            }
+        })
+    }
+
+    /**
+     * Updates a document in a MongoDB collection.
+     * 
+     * @param collection The MongoCollection instance the document is in.
+     * @param documentId The ID of the document to update.
+     * @param updates A sequence of Bson documents defining the updates.
+     * @throws RuntimeException if the update was not acknowledged by the database.
+     */
+    def updateOne[T](collection: MongoCollection[T], documentId: ObjectId, updates: Seq[Bson]): Future[Unit] = {
+        val filter: Bson = Filters.equal[ObjectId]("_id", documentId)
+        val futureResult: Future[UpdateResult] =  collection.updateOne(filter, updates).toFuture()
+        
+        futureResult.map[Unit]((result: UpdateResult) => {
+            if (!result.wasAcknowledged()) {
+                throw new RuntimeException("Update was not acknowledged")
+            }
+        })
+    }
+}
diff --git a/backend-services/feed-service/build.sbt b/backend-services/feed-service/build.sbt
index ad929924b648464b550c0b595083d5984381e964..8ac4696d90efd925ef9357082303b144d876854b 100644
--- a/backend-services/feed-service/build.sbt
+++ b/backend-services/feed-service/build.sbt
@@ -6,6 +6,8 @@ version := "1.0.0"
 lazy val root = (project in file(".")).enablePlugins(PlayScala)
 
 scalaVersion := "2.13.10"
+scalacOptions ++= Seq("-Ywarn-unused")
+
 
 libraryDependencies += guice
 libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test
@@ -16,3 +18,6 @@ libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0
 // Adds additional packages into conf/routes
 // play.sbt.routes.RoutesKeys.routesImport += "com.daily.binders._"
 libraryDependencies += "org.mongodb.scala" %% "mongo-scala-driver" % "4.3.0"
+libraryDependencies += "com.typesafe.play" %% "play-ws" % "2.8.10"
+libraryDependencies += "com.typesafe.play" %% "play-ahc-ws-standalone" % "2.1.10"
+libraryDependencies += "com.github.jwt-scala" %% "jwt-play-json" % "9.2.0"
diff --git a/backend-services/feed-service/conf/application.conf b/backend-services/feed-service/conf/application.conf
index 852c11d6e6d10588b23cae3f2b3e8131c4827c11..cd190de63d1862ce68daa1d58dbd3993bc1c4e13 100644
--- a/backend-services/feed-service/conf/application.conf
+++ b/backend-services/feed-service/conf/application.conf
@@ -1,4 +1,7 @@
-# Default Configuration File
-
 # MongoDB Connection Strings
-mongodb.uri = "mongodb://localhost:27017/"
+mongodb.uri="mongodb://localhost:27017/"
+mongo.feedService.db = "feed-service"
+mongo.dailies.collection = "dailies"
+
+# JWT Authenticationn
+jwt.privateKey = ""
diff --git a/backend-services/feed-service/conf/routes b/backend-services/feed-service/conf/routes
index c987e3139a94547944c6f45cb7398242a2986f69..c858105f24e817c9cc22bec4ddfeb0d8348e6e95 100644
--- a/backend-services/feed-service/conf/routes
+++ b/backend-services/feed-service/conf/routes
@@ -7,6 +7,19 @@
 GET     /                           controllers.HomeController.index()
 
 # Map static resources from the /public folder to the /assets URL path
-GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)
+GET     /assets/*file           controllers.Assets.versioned(path="/public", file: Asset)
 
-GET     /mongo_test                 controllers.MongoTestController.index()
+POST     /daily/create          controllers.DailyController.create()
+
+GET     /user/dailies           controllers.DailyController.getUserDailies(userId: String)
+
+GET     /feed                   controllers.DailyController.getUserFeed(userId: String)
+
+PUT     /daily/like             controllers.DailyController.like()
+
+PUT     /daily/unlike           controllers.DailyController.unlike()
+
+
+GET     /test/getFriends        controllers.TestController.getFriends(userId: String)
+
+GET     /test/verifyUser        controllers.TestController.verifyUser(userId: String)