# トランスリーダー # Transleader, Extended development task Здесь описана архитектура сайта - Структура хранения приложения на серверах - Используемые обьекты (книги/пользователи/ ...), хранимые в базах данных - Основные вебстраницы, используемые пользователем вебсайта (со ссылками на эти страницы), вместе с логикой обмена данных с сервером (какие запросы отпраляет и принимает каждая страница) - Допустимые поля для используемых объектов *本のライブラリー / 何かを翻訳したい人のためのサービス、コンペやトーストマスターズ* ## Структура системы MVP Система **_свой АЙТИ проект. И вообще._** состоит из компонентов: __*Authorization server*__ Компонент, в котором осуществляется логин, регистрация и управлением аккаунтов пользователя. *Путь к нему далее будет описан как /authpath* __*Library app*__ Приложение, в котором осуществляется навигация по страницам сайта, в том числе поиск книг и их редактирование пользователем. *Путь к нему далее будет описан как /webpath* __*Library server*__ Сервер, обращение к которому будет происходить путем вызовов API реквестов, на сервере осуществляется поиск, сохранение и выдача необходимой информации, а также обмен данными с базах данных. *Путь к нему далее будет описан как /apipath* __*Moderator server*__ Компонент, в котором осуществляются такие функции как бан пользователей, валидация новых книг и организация объединения существующих на сайте книг при допущенных ошибках пользователей в добавлении книг. *Путь к нему далее будет описан как /modpath* --- ## Структура обьектов данных Допустимые поля для каждого объекта приведены несколько дальше по документу - **User** - пользователь вебсайта - **Book** - объект книги/статьи/субтитров. В нем содержится только информация об одном издании - **Book Parent** или **Book Variant List** или - родительский объект для книги в котором содержится список всех версий/изданий/переводов для книги Следующие объекты приведены как пример для дальнейшей разработки доп функций - **BookSeries** - серия книг, в которой содержатся id всех BookParent серии книг. для отображения необходимо создать отдельный метод который принимает язык и отображает по одной книге из каждого родителя на выбранном языке - **BookCollection** - коллекция книг (н-р избранные), в которой содержатся id всех BookParent. --- ## Основной флоу системы - `Веб страницы, помеченные как ***(Только для зарегистрированных пользователей)*** перенаправляют неавторизированных пользователей на страницу входа/регистрации.` - `Каждая книга идентифицируется по ID` - **SigninPage** _(возможно можно залогиниться через Гугл или Гитхаб, может и нет)_ ![Alt text](https://www.vedamo.com/wp-content/uploads/2017/09/Login-and-Login-with-Google-options-IMG.png "/webpath/signin") **(request)** Запрос от *Library app*: POST к *`/authpath/login`* или *`/authpath/signup`*, в ответ получает свой токен, который хранит в безопасных cookies браузера. _(тип токена и способы его хранения на сервере нуждаются в дополнительном обсуждении)_ --- - **Landing page** `/webpath`, на которой имеется верхняя панель, название сайта и поле для поиска;![Alt text](https://i.imgur.com/frCfljS.jpg "/webpath") - **Landing page, search** `/webpath?search=вводимый поиск` При вводе поискового запроса пользователь получает книги, соответствующие его запросу. ***(request)*** *Library app* посылает **GET** request `/apipath/searchBooks`, С параметрами Query Parameters: `{search='вводимый поиск'}` Получает - либо массив упрощенных обьектов книг `["title":"book title", "author":"book author"];` ![Alt text](https://i.imgur.com/yxcfl3e.jpg "/webpath?some-search-query") --- - **BookPage** `/webpath/book/:bookID` При выборе книги, пользователь получает интерфейс с информацией о книге, а так же кнопкой загрузки данной книги. При этом информация о языке находится в выпадающем меню, при нажатии на которое открывается список доступных для этой книги языков ***(request)*** Запрос от *Library app*: **GET** from '`/apipath/book/:bookID`' получает обьект книги {author, description, link to text, link to parent obj, language, optionals}; ![Alt text](https://i.imgur.com/kawKidh.jpg "/webpath/book/:bookISBN") - При нажатии на выпадающее меню языков, либо при загрузке страницы после получения данных о книге (link to parent obj) отправляется запрос на получение всех доступных языков и изданий этой книги. ***(request)*** Запрос от *Library app*: **GET** from '`/apipath/bookVariants/:parentID`' получает [{language:russian,id:someid}] - массив из книг с двумя полями - При выборе одного из доступных языков, пользователи перенаправляется на страницу книги на выбранном языке. Если же книга не одна, то пользователь получает дополнительное всплывающее окно с возможностью выбрать одну из книг на выбранном языке (в том числе и переводы созданные пользователями). - **CreateBookPage, newBook** `/webpath/newbook/newbook` Пользователь может добавить новую книгу, если он не нашел её на сайте. Для этого ему необходимо нажать на предназначенную для этого кнопку на сайте (Контекстного меню сверху, и еще "я не нашел нужной мне книги" после поиска). После этого он попадает в меню, где указывает все необходимые данные, а так же добавляет файл книги (возможны разные форматы, необходимо определить и обработать каждый из них) **/здесь необходима картинка дизайна/**. ***(request)*** После окончания работы над информацией о книге пользователь сохраняет её с помощью Запроса от *Library app*: **POST** to `/webpath/newbook/` параметры отправляются как JSON файл в body получает success или error - **CreateBookPage, variant** `/webpath/newbook/variant` Пользователь может добавить существующий перевод для книги, если он не нашел его среди вариантов книги. Логика схожа с предыдущим пунктом за исключением некоторых полей 17. Каждая добавленная пользователем книга, или существующая версия должна проходить модерацию/автоматическую валидацию, способ модерации будет обсужден и добавлен в тех.задание позже, на начальных этапах модерация отсутствует. --- <br><br> --- ## Структура объектов базы данных ### **Объект книги**, допустимые поля - Основные поля - **id :** Уникальный идентификатор ***PRIMARY KEY*** - **language :** Язык книги - **title :** Название книги - Дополнительные поля - **parent** : "Идентификатор родительского обьекта" - **textURL** : "ссылка на файл с текстом книги" - **author** : Автор текста - **coverPicture** : ссылка на обложку книги - **year** : Год издания - **publisher** : Издательство, опубликовавшее книгу; либо пользователь, написавший перевод - **description** : Описание - **curentStatus** : "законченное произведение/ в процессе/ замороженное перевод" - "accessToModify": "all (Любой может проучавствовать)/ none (если книга от издательства это поле не нужно)/ author (Только пользователь, пишущий перевод может его изменять)/[][Возможно позже можно будет добавить список допустимых пользователей]" - edition – the edition of the text - city – the location of the publisher - pages – the number of pages in the text - filesize – the size of the file in bytes - extension – the extension of the file (.pdf, .epub, .mobi, etc.) - md5 – the [MD5](http://www.md5.net) hash of the file - crc32 – the file's CRC32 checksum - edonkey – the file's eDonkey hash - aich – the text's eMule file hash - sha1 – the file's SHA-1 hash - tth – the file's Tiger tree hash - **shortisbn** : the text's short - longisbn : and long International Standard Book Numbers (not necessarily in that order) - issn – the text's International Standard Serial Number - asin – the text's Amazon Standard Identification Number - udc – the text's Universal Decimal Classification number - lbc - ddc – the text's Dewey Decimal Classification number - lcc – the text's Library of Congress Classification number - doi – the file's Digital Object Identifier - googlebookid – the text's Google Books ID - openlibraryid – the text's Open Library ID - paginated – the text is paginated (1) or not (0) - scanned – the text is scanned from a physical copy (1) or not (0) - bookmarked – the text has bookmarks (1) or not (0) - searchable – the text is searchable (1) or not (0) - visible - if text shold be returned and can be displayed -> true - timeadded – the date/time when the text was added to the database, formatted as YYYY-MM-DD HH:MM:SS - timelastmodified – the date/time when the text's entry in the database was edited, formatted as YYYY-MM-DD HH:MM:SS ### **Родительский обьект книги**, *тот благодаря которому можно посмотреть другие языки/переводы той же книги* - обяз - "id":"Уникальный идентификатор, возможно можно определить его по первой добавленной в этот объект книге" ***PRIMARY KEY*** - "books/children":[{"language":"english","id":"someID"},...] //cписок книг этого объекта - - не обяз - "genre":"Потенциально добавляемая функция" - volumeinfo – the volume number, if the text is part of a multi-volume series - series – the series that the text is part of, maybe reference to BookCollection id - topic – A number corresponding to the topic of the text; for example, 130 is "Mathematics/Logic" ### **Пользователь** - { - "username":"имя пользователя" ***PRIMARY KEY*** - "еще нужен токен по которому пользователь будет получать доступ к защищенной информации, но хранить его вряд ли необходимо в бд" - } ###### Readme end --- <br/><br/><br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/><br/><br/> ИГНОРИРУЙТЕ ДАЛЬНЕЙШИЙ ТЕКСТ ОН ОСТАВЛЕН КОММЕНТАРИЯМИ --- ## ДАЛЬШЕ ДОПОЛНИТЕЛЬНЫЕ ФУНКЦИИ КОТОРЫХ ПОТЕНЦИАЛЬНО НЕ БУДЕТ - **TranslationsList** `/webpath/mytranslations` *(Только для зарегистрированных пользователей)* У каждого пользователя есть личный кабинет, в котором единственная функция: он может посмотреть те переводы которые он создал (законченные и в процессе) **/здесь необходима картинка дизайна доступа к личному кабинету/** ***(request)*** Запрос от *Library app*: GET from */apipath/usersTranslation/personal* (personal используется чтобы достать юзер айди с помощью авторизации, далее логика схожа с */apipath/usersTranslation/:userID*). - **BookPage, read** `/webpath/book/:bookISBN/read` При нажатии на кнопку "хочу прочитать" открывается доп. интерфейс чтения, со списком глав, к которым он может перейти для чтения. (Возможно глава будет открываться под плашкой, в отдельном окне неудобно, но если будет в отдельном окне тогда к каждой главе должна быть припечатана ссылка на прошлую и следующую главу.) каждая глава отмечается как `/webpath/book/:bookISBN/read/:chapterNumber`. ***(request)*** Запрос от *Library app*: GET from `/apipath/book/:bookISBN/?` где `?` - это Либо запрос на весь текст разом, Либо делать запросы по каждой главе по переходам, вообще хорошо бы сделать оба варианта и отправлять запросы основываясь на размере книги (который должен быть передан вместе с остальной информацией о книге) - **CreateBookPage, translation** `/webpath/newBook/translation` Если пользователь желает создать перевод его перенаправляют на страницу создания пустого проекта перевода где он заполняет необходимые детали. ***(request)*** Как только пользователь закончит создание проекта *Library app* отправляет POST запрос со всей информацией на `/apipath/newBook/translation` - Как только пустой проект создан и закреплен за пользователем автор может получить к нему доступ из личного кабинета а так же по ссылке `/webpath/book/:bookISBN` для чтения или `/webpath/book:bookISBN/edit` для редактирования. - **BookPage, edit** В режиме редактирования пользователь попадает на страницу, в которой он может выбрать главу/часть над которой он хочет работать. В режиме редактирования главы пользователь имеет зеркальные поля, одно из которых для ввода текста, а другое (эталонное поле) содержит оригинал переводимой книги (либо ту версию, которую выберет пользователь) ![Alt text](https://i.imgur.com/EX4Gf0U.jpg "/webpath/book/:bookID/edit") ***(request)*** После окончания работы над главой пользователь сохраняет её с помощью Запроса от *Library app*: POST to `/webpath/book/:bookID/:chapterID`