📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

СОБРАЛ ПРОЕКТ ЗА ТРИ ДНЯ, РЕШИЛ ПОКАЗАТЬ ВАМ! СМОТРИМ СТЕК, АРХИТЕКТУРУ, КОД

s6ptember16:57

Transcription

Недавно мне написал мой друг. У него есть небольшая команда, выполняющая на постоянной основе определённый спектр задач, из-за чего у него периодически возникала проблема с их координацией. И ко мне, как программисту, поступила просьба сделать небольшое приложение, которое позволит ему и его менеджерам размещать задачи. Эти задачи сотрудники могут брать и, соответственно, сдавать как выполнены, а он, как и его менеджеры, могут следить за временем выполнения определённых задач. Ну и вообще прикидывать, кто что сегодня делал.

Отказать в просьбе я не смог, поэтому мне удалось собрать такой проект за 3 дня. Он уже висит в продакшене, и на нём реально работают люди. Плюсом я решил запилить вам банально ролик, поэтому сегодня мы посмотрим, что это за проект вообще такой, разберём его архитектуру, как я его написал и что можно было бы в нём улучшить.

И давайте я сразу, чтобы заинтересовать вас, покажу демонстрацию работы на телефоне, как PWA приложение, что неимоверно добавляет удобство, так как мы можем сделать иконку на рабочем столе, буквально открывать наш сайт как приложение, но при этом не иметь никаких заморочек с флаттером, с котлином или на чём там пишут мобильные приложения. Поэтому продолжаем.

Кстати, весь исходный код будет, конечно же, в Telegram-канале. Заходите, скачивайте, можете деплоить себе. Возможно, кому-то тоже понадобится такой проект. И помимо этого я прикреплю инструкции по депою, что на самом деле не трудно. Просто не хочу вставлять её в ролик, потому что растянется хронометраж.

И теперь мы переходим, соответственно, к демонстрации самого проекта. Я открываю наш сайт, и в первую очередь мы видим окошечко логина. Да, тут есть логин, есть регистрация, но так как проект был рассчитан на очень узкий круг пользователя, регистрацию меня попросили закрыть. Все аккаунты делаются через админку. Но если что, вы можете код для регистрации раскомментировать, и она будет действительно доступна.

Теперь войдите в аккаунт. Давайте мы сделаем суперюзера, чтобы мы могли войти в админку и посмотреть, что там вообще происходит. Поэтому я открываю редактор кода. Здесь я уже подключён к серверу, на котором у меня задепло этот сайт. И я банально пишу make super user. Так, чуть увеличу редактор кода, да, чтобы вы видели. То есть тут настроен Makefile, поэтому, кстати, деплоить будет достаточно просто. Пишу make super user. У нас происходит экзег. Я пишу имя пользователя админ. Пускай будет админ один, потому что админ я уже создавал для теста. И пароль 1 2 3, соответственно, 1 2 3. Жму Y. Мы сделали нашего суперюзера, поэтому я возвращаюсь в браузер. И давайте войдём админ 1. Пароль админ 1 2 3. Жму войти.

И мы попадаем на главную менюшку. Почему изначально у нас была тема чёрная, а потом стала белая? Потому что лично я задумал сайт в чёрной, но мне сказали, что в тёмной нам не нравится. Мы хотим белую тему. Ну, я переделал, собственно говоря. Кстати, вот я ставлю скрин, где видно, не знаю, куда я пальцем показал, но тут видно, в общем, какая тема была изначально. Но так как у нас есть замечательная нейросеть, перевести сайт из тёмной темы в белую, это буквально, ну, один промт.

Что мы здесь видим? Во-первых, приветствие. Нет активных задач. Задачи мы ещё не создавали и наш календарь с задачами. Сайт у нас, если что, полностью динамичный. Есть разные режимы отображения. И давайте вообще протестим, как это работает.

В первую очередь, чтобы создать таску, нам нужно сделать шаблон для неё и выдать нужную роль. Давайте мы сначала дадим себе роль админа, чтобы мы могли прямо на сайте создавать таски. Либо админ, либо менеджер может это делать с помощью встроенного функционала. Поэтому я жму администратор и нужно имя какое-то вставить. Пускай это будет просто. Жму сохранить. Роль у нас есть. Замечательно. На что это влияет? Мы, если откроем сайт, мы видим кнопочку add task. Add task. И здесь есть шаблоны задач, которые, соответственно, можно использовать.

Как сделать шаблоны? Это, на самом деле, очень удобная штука. Вместо того, чтобы каждый раз прописывать задачу и подзадачу в ней. Например, если мы делаем видео, нам нужно, что кто-то сделал монтаж, кто-то там превью, кто-то сделал музыку. Каждые эти три пункта - это, соответственно, подзадача. И согласитесь, вручную каждый раз их писать абсолютно неудобно. Поэтому мы делаем шаблоны.

Как добавить шаблон? Тут всё достаточно просто. Я снова перехожу в админ, открываю, во-первых, объекты шаблонов подзадач. Добавить. Это что? Это наши подзадачи, которые мы будем вызывать. Первое, что пойдёт, давайте сделаем, ну, тестовый просто монтаж. Вот я ж ютубер, поэтому для создания ролика, например, укажу создателя объект монтаж. И теперь я создаю шаблон задачи. Задача, например, в создании видео. Так, буковку О большую давайте на маленькую поменяем. Описание можно любое натыкать. Это поле было сделано для дальнейшего развития, но пока что описание нигде не применяется. Ставлю создателя и ставлю объект под задачу. Монтаж. Всё. Нажимаю сохранить. Так, а у меня уже был объект. Да, у меня уже был объект. Ну ладно, будет у нас два монтажа. Либо давайте один поменяю монтаж на что? На превью. Вот хочу поменять монтаж на превью. Всё, у нас есть две подзадачи и один шаблон задач.

Теперь смотрите, я открываю наш сайт. У нас есть кнопочка add task. У нас как у админа и у менеджеров, которым мы дадим эту роль. Если что, обычные сотрудники, как уже вы видели, добавлять таски не могут. Они могут только их брать и задавать как выполнены. Поэтому я жму task. Я выбираю шаблон. Шаблон видео, например. Здесь сразу подтягивается название задачи, сразу подтягивается наши подзадачи. И что самое главное, их можно редактировать. Я убираю, удаляю нашу подзадачу preview, открываю и выбираю, например, и монтаж, и превью. Вот я хочу две подзадачи на данную задачу. Плюсом даты выполнения, когда это всё будет происходить, когда она была опубликована. Вы можете сами через календарь выбирать, какая дата вам нужна. А после этого вы жмёте создать, и у нас на сайте, само собой, появляется эта таска. Её видят другие сотрудники. Можете создавать на другие даты. Давайте, кстати, я ещё одну сделаю. Допустим, создание. Тут просто у нас будет preview. Ну давайте я превью поменяю на монтаж. Та старая шаблон таски, которую я брал для теста, ставлю на даты выполнения на завтра, то есть тридцатое число. Жму создать. И теперь смотрите, двадцать девятого есть наша таска, тридцатого есть наша таска, есть следующий режим отображения. Тут все у нас задачи, но распределённые по датам.

И что у нас делают сотрудники? Сотрудники у нас должны выполнять эти задачи, поэтому они жмут task. Выбирают подзадачу, которую они хотят хотят взять. Давайте я возьму сразу две. Жму взять задачу. И давайте возьму ещё и тридцатого числа задачу без проблем. Берём подзадачу. Когда задача выполняется, само собой, все пользователи, и менеджеры, и сотрудники видят, как какая подзадача, какой человек её взял. И человек, который эту подзадачу взял, он может её завершать. Я жму на галочку, мы видим завершить подзадачу. Я выбираю завершить и завершаю сразу вторую подзадачу. Всё, я как сотрудник свою задачу завершил. Здесь, соответственно, видно то, что я действительно ей занимался.

Но что видит администратор? Давайте зайдём в админку и посмотрим. Как я вам и говорил, одним из критериев была возможность контролировать и в целом наблюдать, кто что сделал за день и сколько времени на это потратил. Поэтому я открываю вкладочку действия с подзадачами. И здесь что я вижу? Так, я чуть-чуть убавлю, потому что у нас поля не влезают. Да, возможно, чуть неудобно будет смотреть. Давайте лучше полистаем. Вот наша, соответственно, последняя задача, которую мы завершили видео. Такой пользователь у нас ей занимался. Он её завершил и завершил под задачу превью, под задачу монтаж. Вот, соответственно, время, когда он её завершил, и длительность. Длительность 0 минут. Длительность 0 минут. Почему 0 минут? Потому что мы её сразу взяли и сразу завершили, конечно.

А теперь, чтобы вы убедились, то, что подсчёт времени выполнения действительно работает. Я открываю тридцатое число, завершаю задачу. Вот наша последняя задача. Длительность 1 минута. То есть оно действительно считает. И мы можем, соответственно, отслеживать, кто сколько времени потратил на определённую задачу. Ещё это есть вот этой вот вкладочке задачи. Тут мы их как видим? Вот у нас была задача видео. 29 октября мы её опубликовали. Давайте возьмём 30. 30 октября у нас была задача, она у нас уже завершена. Кто её создал? И дата создания. Соответственно, мы можем её открыть сразу, посмотреть подзадачи. Подзадача монтаж завершена, а время начала, время завершения, исполнитель и сколько времени он на это, соответственно, потратил. То есть мы без проблем можем отслеживать, кто он занимался задачей, сколько времени на это ушёл.

Опять же напоследок давайте я покажу, как создавать аккаунты пользователям. Мы открываем пользователь. Если вы не хотите, конечно, лезть в код и открывать регистрацию, вдруг она вам тоже не нужна. Поэтому мы жмём добавить пользователя, соответственно, пишем его имя, какое-то юзер. Аутентификация по паролю, ну, по дефолту оставляем, разрешена. Ставим ему какой-то пароль, подтверждение пароля. Далее полное имя. Пускай это будет имя и роль. Его роль сотрудник, менеджер, администратор. Менеджер, чтобы мог добавлять таски. Сотрудник, чтобы мог только брать таски. Жмём сохранить. И юзер у нас сохраняется. Я жму выйти. Здесь пишу user user user user. Не переключил. И пароль у меня автоматически подтянулся, потому что я использовал уже сгенерированный который у нас сохранён. И вот мы от имени юзера не видим кнопку Task, но зато видим таски и можем их брать, если они, конечно, были бы у нас открыты. Всё, нет активных задач у нас на сегодня, поэтому мы можем переходить к разбору самого кода.

Я уже открыл наш проект. Сейчас мы будем по чуть-чуть разбирать код. Но давайте сначала поговорим об архитектуре. На чём это вообще написано. Бэкенд - это у нас Django. Почему я взял Django? Потому что очень просто и быстро на нём можно собрать приложение. Я не хотел писать вручную систему ролей, там аутентификацию в том же FastAPI, либо в Hone, либо в Go. Ну зачем мне это нужно? Цель всё-таки была максимально быстро это написать. И Django тут идеально заходит.

Теперь давайте поговорим о фронтенде. Сейчас при написании приложения у вас есть два основных выбора - это серверный и клиентский рендер. Давайте скажу, почему я выбрал серверный. Стек такой: HTMX и Alpine.js. Серверный рендер. Почему? Потому что у нас очень малый круг пользователя, который будет пользоваться этим сайтом. Мы хотим дешёвый сервер, чтобы не переплачивать лишний раз. И мы хотим максимальную производительность. HTMX, Alpine.js - легковесные фреймворки, а серверный рендер позволяет работать сайту без каких-либо проблем вообще на любом калькуляторе. Хоть на мотороле зайдите, без проблем будет работать, потому что серверный рендер берёт нагрузку за отрисовку на себя. А так как у нас нет огромного потока пользователей, наш сервер не загнётся от того, что ему приходится отрисовывать шаблоны. А HTMX, Alpine.js позволили сделать наш сайт полностью динамичным. То есть все действия, как вы уже видели, происходят без перезагрузки страниц, кроме захода в админку. Это отдельно я говорю именно про само приложение, из-за чего мы спокойно можем адаптировать в PWA и пользоваться сайтом как приложение.

И теперь давайте кратко, почему в этом проекте не было никакого смысла в клиентском рендере и в полноценном JS фреймворке. Очень важна была скорость разработки. Зачем мне подрубать дополнительные фреймворки, если я могу обойтись легковесными? Во-вторых, опять же, как я уже говорил, нет такой нагрузки, которая положит серверный рендер. В-третьих, сервер за 4 доллара, ребят. Ну, один CPU, один RAM. Прикиньте, что будет, если закинуть туда ещё фронтенд полноценный, помимо Django и PostgreSQL и Nginx. Ну зачем оно нам надо?

Давайте кратенько посмотрим код. Что у нас тут есть? Во-первых, папочка `src`. Именно здесь находится наше Django приложение. Главный файлик `config`. Все приложения находятся тут. Приложение `task` - тут взаимодействие с задачами, `template` для создания шаблонов задач, `users` для логина, регистрации профилей и так далее. `settings.py` у нас настроен с ENV. Всё по красоте вообще сделано. Заходите, смотрите, кому интересно. Далее `static`. В статике у нас скомпилирован Tailwind, который используется для стилизации. Скомпилирован у нас и HTMX, наш Alpine.js. Есть файлики для регистрации PWA. Как раз-таки с помощью него, кстати, это происходит. Для того, чтобы PWA у нас работал, нам нужен манифест и SVGs. Ну а `pwaregistration.js` - это просто, чтобы окошко вылетало. Хотите добавить PWA или нет, но, к сожалению, оно работает только на Android, на iOS. Такой возможности нет добавлять PWA в одну кнопку. Всё компилируется в статику, в `static files`. Ну, когда вы прописываете `collectstatic`, конечно, при деплое.

Далее `templates`. В шаблонах как раз-таки подгружается наш Tailwind. Давайте сначала скажу про манифест. Наш манифест. Вслед за этим Tailwind CSS, HTMX, Alpine, JS, PWA регистрация. След за этим следует `example.env`. Тут поменяйте домены на свои. В целом этого хватит. Далее `gitignore`, `dockerignore` - это понятно. Это база, сама Docker конфигурация. У нас есть `docker-compose.yml`, `Dockerfile` и `nginx`. Где у нас вот в папочке настроено под работу HTTPS с сертификатами, то есть без проблем всё у вас запустится. Кстати, напоминаю, что для работы с PWA вам обязательно нужно установить HTTPS соединения. PWA по-другому не работает, поэтому такая архитектура, такой репозиторий.

И давайте чуть затронем, что можно было бы улучшить, если бы я занимался выпуском этот проект прямо для массовых пользователей продакшн. Что бы я добавил? Во-первых, кэширование на Redis. Почему его сейчас нет? Потому что, напоминаю, сервак 1 CPU, 1 RAM. И я просто побоялся, что кэширование лишний контейнер с Redis может его убить. Сейчас-то у нас есть какие контейнеры? DB на PostgreSQL, `web` - это наше Django приложение и вслед за этим я бы само собой настроил мониторинг, также детальное логирование, чтоб можно было отслеживать ошибки, если вдруг они возникают. Всё-таки, опять же, мы рассматриваем ситуацию, если бы я выпускал этот сайт в продакшн для вообще на всеобщее обозрение, чтобы любой человек мог им пользоваться и делать свои заметки, открыл бы регистрацию, накинул там приветственные письма, подтверждение email и так далее. Для этого бы понадобился уже Celery для синхронной обработки некоторых задач. Плюсом потребовалось бы изменение вообще принципа работы заметок. Если бы я открывал проект в продакшн для общего круга, то люди хотели бы знать, что я не могу читать их задачи, которые они себе пишут. Сейчас-то я могу зайти в админку и посмотреть вообще про каждого пользователя, кто что делал. Это в одном месте у меня буквально. Но если бы я опять же выпускал продакшн для всех людей, я бы сделал систему, которая всё это кэшировала. Ой, не кэшировала, а шифровала. То есть все задачи, они были бы зашифрованы, а расшифровать их можно только с помощью ключа, а ключ, само собой, будет привязан к каждому пользователю. Поэтому я бы построил такую систему, в которой я не имею доступа и не могу смотреть таски, которые люди ставят себе в личном кабинете, ну и своим сотрудникам, соответственно, оно было бы всё у меня зашифровано. Расшифровать могут только сами люди. И это обеспечило бы гарантию того, что я не могу просто опять же посмотреть, что они там делают, либо как-то повлиять на их таски. У меня просто не было бы такого функционала в админке. А так как это Open source проект, то любой человек мог бы зайти и убедиться в том, что действительно создатель, который сделал этот сайт, он не может зайти, посмотреть, что я тут пишу. Поэтому оно анонимно всё работает.

И если этот ролик наберёт большой актив, то я вам предлагаю следующее: взять и запустить этот проект реально в продакшн. Я вам покажу, как это сделать. Мы напишем эту систему шифрования всех тасок, выпустим в продакшн, всё по красоте. И любой из вас может зайти, зарегистрироваться и пользоваться этим приложением без каких-либо проблем. Оно будет в открытом доступе. Это будет полноценный сервис. Но самое главное, опять же, что я сделаю, это на всеобщем обозрении вы научитесь, как поднимать приложение в продакшн.

Я закончил. Всем спасибо за просмотр и всем до свидания.