diff --git a/README.md b/README.md
index 767ca9a..30adc4e 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,69 @@
## How to launch
+First of all, you need to launch PostgreSQL and Redis:
+
```bash
docker compose start
-```
+```
+
+Then, start the REST-api:
```bash
-sbt "project stub" run
+sbt "project service" run
+```
+
+And finally, run the telegram bot:
+
+```bash
+sbt "project bot" run
+```
+
+## Internals
+
+### Actual database schema
+
+```postgresql
+create table offers
+(
+ id uuid primary key,
+ name text not null,
+ price integer not null,
+ description text not null,
+ status text not null
+);
+
+create table users
+(
+ id uuid primary key,
+ name text not null,
+ login text not null unique,
+ status text not null,
+ password_hash text not null,
+ password_salt text not null
+);
+
+create table user_offers
+(
+ offer_id uuid primary key,
+ user_id uuid not null references users(id)
+);
```
+
+### Authorization
+
+Each user has login (telegram @login) and password, and, in order to use the service, he should get a session and then attach it to each request
+
+Creating a session:
+
+
+
+Use session in some request:
+
+
+
+### Telegram-bot
+
+State machine diagram:
+
+
diff --git a/docs/bot-state-machine.png b/docs/bot-state-machine.png
new file mode 100644
index 0000000..78c1061
Binary files /dev/null and b/docs/bot-state-machine.png differ
diff --git a/docs/create-session.png b/docs/create-session.png
new file mode 100644
index 0000000..f68b4b0
Binary files /dev/null and b/docs/create-session.png differ
diff --git a/docs/use-session.png b/docs/use-session.png
new file mode 100644
index 0000000..144968a
Binary files /dev/null and b/docs/use-session.png differ
diff --git a/service/src/main/scala/com/github/mmvpm/service/api/AuthHandler.scala b/service/src/main/scala/com/github/mmvpm/service/api/AuthHandler.scala
index 755a804..ff1b1ef 100644
--- a/service/src/main/scala/com/github/mmvpm/service/api/AuthHandler.scala
+++ b/service/src/main/scala/com/github/mmvpm/service/api/AuthHandler.scala
@@ -20,7 +20,7 @@ class AuthHandler[F[_]: Monad](override val authService: AuthService[F], userSer
private val signUp: ServerEndpoint[Any, F] =
endpoint.withApiErrors.post
- .summary("Зарегистрировать нового пользователя")
+ .summary("Register a new user")
.in("api" / "v1" / "auth" / "sign-up")
.in(jsonBody[SignUpRequest])
.out(jsonBody[UserResponse])
@@ -28,14 +28,14 @@ class AuthHandler[F[_]: Monad](override val authService: AuthService[F], userSer
private val signIn: ServerEndpoint[Any, F] =
endpoint.withApiErrors.withLoginPassword.post
- .summary("Обменять логин и пароль на сессию")
+ .summary("Get session by login and password")
.in("api" / "v1" / "auth" / "sign-in")
.out(jsonBody[SessionResponse])
.serverLogic(userId => _ => authService.getSession(userId).value)
private val whoAmI: ServerEndpoint[Any, F] =
endpoint.withApiErrors.get
- .summary("Получить ID пользователя по сессии")
+ .summary("Get user ID by their session")
.in("api" / "v1" / "auth" / "whoami" / path[Session]("session"))
.out(jsonBody[UserIdResponse])
.serverLogic(authService.whoami(_).value)
diff --git a/service/src/main/scala/com/github/mmvpm/service/api/OfferHandler.scala b/service/src/main/scala/com/github/mmvpm/service/api/OfferHandler.scala
index a417003..c4ec304 100644
--- a/service/src/main/scala/com/github/mmvpm/service/api/OfferHandler.scala
+++ b/service/src/main/scala/com/github/mmvpm/service/api/OfferHandler.scala
@@ -20,21 +20,21 @@ class OfferHandler[F[_]: Applicative](offerService: OfferService[F], override va
private val getOffer: ServerEndpoint[Any, F] =
endpoint.withApiErrors.get
- .summary("Получить объявление по его id")
+ .summary("Get the offer by its ID")
.in("api" / "v1" / "offer" / path[OfferID]("offer-id"))
.out(jsonBody[OfferResponse])
.serverLogic(offerService.getOffer(_).value)
private val getOffers: ServerEndpoint[Any, F] =
endpoint.withApiErrors.get
- .summary("Получить все объявления данного пользователя")
+ .summary("Get all offers of the specified user")
.in("api" / "v1" / "offer" / "user" / path[UserID]("user-id"))
.out(jsonBody[OffersResponse])
.serverLogic(offerService.getOffers(_).value)
private val createOffer: ServerEndpoint[Any, F] =
endpoint.withApiErrors.withSession.post
- .summary("Создать объявление")
+ .summary("Create an offer")
.in("api" / "v1" / "offer")
.in(jsonBody[CreateOfferRequest])
.out(jsonBody[OfferResponse])
@@ -42,7 +42,7 @@ class OfferHandler[F[_]: Applicative](offerService: OfferService[F], override va
private val updateOffer: ServerEndpoint[Any, F] =
endpoint.withApiErrors.withSession.put
- .summary("Изменить объявление")
+ .summary("Update the offer")
.in("api" / "v1" / "offer" / path[OfferID]("offer-id"))
.in(jsonBody[UpdateOfferRequest])
.out(jsonBody[OfferResponse])
@@ -52,7 +52,7 @@ class OfferHandler[F[_]: Applicative](offerService: OfferService[F], override va
private val deleteOffer: ServerEndpoint[Any, F] =
endpoint.withApiErrors.withSession.delete
- .summary("Удалить объявление")
+ .summary("Delete the offer")
.in("api" / "v1" / "offer" / path[OfferID]("offer-id"))
.out(jsonBody[OkResponse])
.serverLogic(userId => offerId => offerService.deleteOffer(userId, offerId).value)
diff --git a/service/src/main/scala/com/github/mmvpm/service/api/UserHandler.scala b/service/src/main/scala/com/github/mmvpm/service/api/UserHandler.scala
index 98c1cae..a324c43 100644
--- a/service/src/main/scala/com/github/mmvpm/service/api/UserHandler.scala
+++ b/service/src/main/scala/com/github/mmvpm/service/api/UserHandler.scala
@@ -19,14 +19,14 @@ class UserHandler[F[_]: Functor](userService: UserService[F], override val authS
private val getUser: ServerEndpoint[Any, F] =
endpoint.withApiErrors.get
- .summary("Получить пользователя по его id")
+ .summary("Get the user by their ID")
.in("api" / "v1" / "user" / path[UserID]("user-id"))
.out(jsonBody[UserResponse])
.serverLogic(userService.getUser(_).value)
private val deleteUser: ServerEndpoint[Any, F] =
endpoint.withApiErrors.withSession.delete
- .summary("Удалить свой профиль")
+ .summary("Delete own profile")
.in("api" / "v1" / "user")
.out(jsonBody[OkResponse])
.serverLogic(userId => _ => userService.deleteUser(userId).value)
diff --git a/service/src/main/scala/com/github/mmvpm/service/api/util/SchemaInstances.scala b/service/src/main/scala/com/github/mmvpm/service/api/util/SchemaInstances.scala
index 56956b5..c1564b0 100644
--- a/service/src/main/scala/com/github/mmvpm/service/api/util/SchemaInstances.scala
+++ b/service/src/main/scala/com/github/mmvpm/service/api/util/SchemaInstances.scala
@@ -12,48 +12,48 @@ object SchemaInstances {
// model
implicit val schemaOfferStatus: Schema[OfferStatus] =
- Schema.derivedEnumerationValue.description("Статус объявления")
+ Schema.derivedEnumerationValue.description("Offer status")
implicit val schemaOfferDescription: Schema[OfferDescription] =
- Schema.derived.description("Задаваемые пользователем поля объявления")
+ Schema.derived.description("User-defined offer fields")
implicit val schemaOffer: Schema[Offer] =
- Schema.derived.description("Объявление")
+ Schema.derived.description("Offer")
implicit val schemaUserStatus: Schema[UserStatus] =
- Schema.derivedEnumerationValue.description("Статус пользователя")
+ Schema.derivedEnumerationValue.description("User status")
implicit val schemaUser: Schema[User] =
- Schema.derived.description("Пользователь")
+ Schema.derived.description("User")
// requests
implicit val schemaSignUpRequest: Schema[SignUpRequest] =
- Schema.derived.description("Запрос на регистрацию пользователя")
+ Schema.derived.description("Request to register a new user")
implicit val schemaUpdateOfferRequest: Schema[UpdateOfferRequest] =
- Schema.derived.description("Запрос на изменение объявления")
+ Schema.derived.description("Request to update the offer")
implicit val schemaCreateOfferRequest: Schema[CreateOfferRequest] =
- Schema.derived.description("Запрос на создание объявления")
+ Schema.derived.description("Request to create an offer")
// responses
implicit val schemaOkResponse: Schema[OkResponse] =
- Schema.derived.description("Успех")
+ Schema.derived.description("Success")
implicit val schemaSessionResponse: Schema[SessionResponse] =
- Schema.derived.description("Сессия пользователя")
+ Schema.derived.description("User session")
implicit val schemaUserResponse: Schema[UserResponse] =
- Schema.derived.description("Пользователь")
+ Schema.derived.description("User")
implicit val schemaUserIdResponse: Schema[UserIdResponse] =
- Schema.derived.description("ID пользователя")
+ Schema.derived.description("User ID")
implicit val schemaOfferResponse: Schema[OfferResponse] =
- Schema.derived.description("Объявление")
+ Schema.derived.description("Offer")
implicit val schemaOffersResponse: Schema[OffersResponse] =
- Schema.derived.description("Список объявлений")
+ Schema.derived.description("List of offers")
}