IT-инфраструктура для бизнеса и творчества
Разработка
Maksim Belyakov

Как мы создавали единый портал управления коммерческой недвижимостью для BI Group

Привет, меня зовут Максим, я глава студии разработки Sailet, мы создаем полезные IT-решения для государственного и корпоративного сектора. За годы работы накопилось множество интересных кейсов, которыми хочется поделиться с широкой аудиторией.

Заказчик

BI Group — крупнейший инвестиционно-строительный холдинг Казахстана. Компания занимает 164-е место в рейтинге крупнейших строительных компаний мира. Наш непосредственный заказчик одна из семи компаний холдинга — BI Property, специализируется на управлении объектами коммерческой недвижимости.

У директора, Айдына Рахимбаева положительный имидж продвинутого и открытого бизнесмена.

Задача и предыстория

Заказчик обратился к нам по рекомендации, старое незаменимое «сарафанное радио».

У BI Group изначально было несколько сайтов и порталов, не соединенных базами друг с другом. Так делают, когда хотят протестировать новую идею или направление. Например был сайт-сервис по обслуживанию коммерческой недвижимости и отдельный сервис по поиску, сдаче и продаже недвижимости. Они находились на облачных сервисах и ежемесячно оплачивались.

Со временем такой подход стал невыгодным и неудобным. Сотрудникам приходилось сверять базы друг с другом, запрашивать доступы, это приводило к задержкам в рабочих процессах.

Поэтому перед нами встала задача создания портала, соединяющего в себе все базы и сервисы. Кроме этого, сайт должен быть комфортным, интуитивно понятным, с удобным пользовательским интерфейсом для размещения и просмотра информации о компании, ее объектах, поиска недвижимости и офисов по всем регионам Казахстана, где у BI есть строительство.

Как было

Сервис ODIN
Сервис Prorent
Предыдущий публичный сайт

Как стало

Одна из многих страниц дизайна Sailet
property.bi.group Sailet
Внутрянка Sailet

Приложение

Структура сайта

Роли в системе

В системе есть два вида пользователей: авторизованный и неавторизованный. Неавторизованный посетитель видит основную информацию сайта и мобильного приложения: каталог недвижимости, списки услуг, команду и предложение о регистрации. Авторизованный пользователь видит информацию о своем профиле, читает документы, получает заявки и уведомления.

Систему поддерживает сервисная компания, которая выполняет четыре основные роли:

  1. Администратор — управляет ролями, сотрудниками и справочниками. Также администратор может выгружать данные в Excel из баз по каждому разделу и отображать в интерфейсе все функции без права редактирования.
  2. Инженер — отвечает за планово-предупредительные работы (ППР), распределение сотрудников по объектам, обходы, чек-листы и профиль пользователя. Инженер имеет права на удаление и создание ролей для исполнителей.
  3. Диспетчер — перераспределяет заявки, сотрудников и обслуживаемые объекты.
  4. Исполнитель — осуществляет исполнение заявок, обходов, ППР.

Со стороны заказчика также есть три роли:

  1. Администратор — курирует работоспособность системы и имеет права на модерацию пользователей, доступ к документам и управление ролями.
  2. Отдел продаж — имеет доступ к разделам: контрагентов, документов, статистики, баз данных в Excel, управление каталогом недвижимости.
  3. Администратор БЦ — имеет доступ к отчетам, заявкам, документам, а также получает уведомления и имеет свой профиль пользователя.

Эта система охватывает все стороны процесса, начиная с неавторизованного пользователя и заканчивая администраторами.

Роли Sailet

Программирование и запуск первой версии

На реализацию первой версии проекта отводилось три месяца. По плану, после сдачи, технический отдел компании презентовал портал маркетинговому отделу.

В отличие от кейса про автоматизацию управления электричками КТЖ (ссылочка на прошлый кейс) у нас теперь были ответственные лица, с которыми решались вопросы. Мы работали с компетентными технарями и все запросы обрабатывались быстро. Это одно из самых приятных отличий частной компании от госкорпорации. Такой подход ускоряет процесс разработки.

Мы уложились в два месяца. Была произведена первичная презентация руководству. Все одобрили и началась подготовка знакомства сотрудников с системой.

На разработку потратили 1350 человеко-часов супер команды:

  • 2 frontend разработчика;

  • 2 backend разработчика;
  • Дизайнер;
  • React Native разработчик;
  • PM;
  • DevOps.

Стек технологий:

  • Phalcon;
  • VueJS;
  • React Native;
  • MongoDB;
  • Git;
  • Kebernetes;
Процесс работы глазами заказчика Sailet

Фишки и выгоды для компании

Изначально, в ТЗ от компании были прописаны стандартные справочники. Мы сделали динамические справочники в едином интерфейсе с фильтрацией, которая позволяет сотрудникам самим вносить необходимые изменения и удобно ориентироваться при поиске информации. Также их можно масштабировать бесконечно, сколько потребуется пользователю-администратору.

Благодаря несложным подсчетам, система окупит себя через полтора года.

Прототип роль "Инженер" Sailet

Итоги

Мы создали первую, рабочую версию портала в рекордно сжатые сроки. Он решает вопросы заказчика, заменяет арендованные сервисы своим функционалом и приносит клиентов.

Немного благодарностей от технического отдела BI Property:

Sailet является для нас надежным, клиентоориентированным партнером. Всегда оперативно реагирует на наши запросы, мы довольны качеством оказываемых услуг. Рекомендуем Sailet, как разработчиков

Елдар
Менеджер проекта со стороны Заказчика

Такой промежуточный итог сотрудничества с компанией. Надеюсь кейс будет полезен. Задавайте вопросы в комментариях, буду рад на них ответить.

(function () { let cdnUrl = `https://specialsf378ef5-a.akamaihd.net/SelectelBranding/images/` let previousArticleNumber = null let currentArticleNumber = 0 let platform = 'Desktop' let articles = [ { name: 'camera', url: `${cdnUrl}CameraCat`, text: 'умную камеру для\u00A0наблюдения за\u00A0котиками', link: 'https://vc.ru/selectel/306690', num: 3 }, { name: 'chill', url: `${cdnUrl}ChillCat`, text: 'трекер, который подскажет, когда пора отдохнуть', link: 'https://vc.ru/promo/288561-eye-tracker', num: 1 }, { name: 'cloud', url: `${cdnUrl}CloudCat`, text: 'котика: даёшь ему «пять», а\u00A0он делает бэкап в облако', link: 'https://vc.ru/dev/294799-maneki-neko', num: 2 } ] let buttonCycle = document.querySelector('.button--cycle') let buttonChoose = document.querySelector('.button--choose') let buttonMobile = document.querySelector('.button--mobile') let textField = document.querySelector('.selectel-footer-subtitle') let imageAgent = document.querySelector('.image--agent') let banner = document.querySelector('.selectel-footer') buttonCycle.addEventListener('click', cycleClick) buttonChoose.addEventListener('click', () => sendEvent(`Promo ${articles[currentArticleNumber].num} Left`, 'Click')) buttonMobile.addEventListener('click', () => sendEvent(`Promo ${articles[currentArticleNumber].num} Left`, 'Click')) let media = window.matchMedia("(max-width: 570px)") media.addEventListener('change', matchMedia) function matchMedia() { if (media.matches) { platform = 'Mobile' } else { platform = 'Desktop' } update() } matchMedia() function cycleClick(event) { sendEvent(`Promo ${articles[currentArticleNumber].num} Right`, 'Click') if (event) { event.preventDefault() event.stopPropagation() } window.open('https://vc.ru/tag/selectelDIY', '_blank') //cycle(event) } function cycle(event) { // incrementArticleNumber() textField.innerHTML = generatedText() imageAgent.src = articles[currentArticleNumber].url + platform + '.svg?3' imageAgent.setAttribute("class", "") imageAgent.classList.add('image--agent', articles[currentArticleNumber].name) banner.href = articles[currentArticleNumber].link } function update() { banner.href = articles[currentArticleNumber].link imageAgent.src = articles[currentArticleNumber].url + platform + '.svg' textField.innerHTML = generatedText() } function incrementArticleNumber() { previousArticleNumber = currentArticleNumber if (currentArticleNumber >= articles.length - 1) { currentArticleNumber = 0 } else { currentArticleNumber++ } } const sendEvent = (label, action = 'Click') => { const value = `SelectelDIY — loc: Footer — ${label} — ${action}`; if (window.dataLayer !== undefined) { window.dataLayer.push({ event: 'data_event', data_description: value, }); } }; function generatedText() { let defaultText if (platform === 'Desktop') { defaultText = `Мы тут собрали %text%. Хотите научим?` } else { defaultText = `Мы тут собрали %text%.` } return defaultText.replace('%text%', articles[currentArticleNumber].text) } function getRandom(min, max) { min = Math.ceil(min) max = Math.floor(max) return Math.floor(Math.random() * (max - min + 1)) + min } (function create() { currentArticleNumber = getRandom(0, articles.length - 1) cycle() let page = document.querySelector('.page--entry') if (page) { function insertAfter() { let parents = page.querySelectorAll('[data-id="7"]') let referenceNode = parents[0] referenceNode.parentNode.insertBefore(banner, referenceNode.nextSibling); loaded() } setTimeout(() => insertAfter(), 0) } }()) function loaded() { banner.classList.add('loaded') } loadImages([ `${cdnUrl}CameraCatDesktop.svg`, `${cdnUrl}ChillCatDesktop.svg`, `${cdnUrl}CloudCatDesktop.svg`, `${cdnUrl}CameraCatMobile.svg`, `${cdnUrl}ChillCatMobile.svg`, `${cdnUrl}CloudCatMobile.svg?3`, ]) function loadImages(urls) { return Promise.all(urls.map(function (url) { return new Promise(function (resolve) { var img = document.createElement('img'); img.onload = resolve; img.onerror = resolve; img.src = url; }); })); } }())
0
4 комментария
Популярные
По порядку

По команде, не очень понятно по тестированию? Тестировщиков в команде не указано. Аутсорс? TDD?
По времени было б прикольно если б расписали на что времени ушло больше, бэк или фронт.
Использовали только свои наработки или готовые ui решения, например.
Чем обусловлен выбор react native? Арр-ом занимались отдельные разрабы или фронты?
Если выбрали react native зачем на вебе vue? Почему отказались от полной инфраструктуры react.
В разделе про разработку, мало инфы про разработку. Больше инфа для PM)

1

В целом закидывали в личный опыт, vc перекинул в разработку)

По тестировщикам - аутсорс, не стали указывать.

По времени, больше всего бэк занял. С точки зрения бизнес-логики было много вопросов, что от кого зависит и куда передается. Фронт и мобилка естественно все берут по Api.

Использовали только свои наработки.

По поводу стека в целом, вопрос во времени стоял в первую очередь. Все, что расписано в статье - некое MVP, которое нужно было быстро запустить и презентовать бизнесу (в корп. структуре заказчика, технари презентуют бизнесу разработки и дальше принимается решение развивать ли его). Поэтому и react native, и vue. 

1

Понятно, спасибо за ответ

1

Огонь, шикарная работа!

1
Читать все 4 комментария
«Как иронично, что фирме в сфере психического здоровья плевать на психическое здоровье собственных работников» Статьи редакции

Сотрудники Spring Health жалуются на соучредительницу Эйприл Го: она запугивает их, увольняет при всех, вынуждает работать по 70 часов в неделю и не нанимает тех, кто спрашивает про переработки. Го объясняет: «Мы носимся как безголовые цыплята, потому что на кону человеческие жизни».

Эйприл Го — на ноябрь 2021 года самая молодая женщина-директор компании с оценкой более $1 млрд Slush
Помощь друга: какие новые программы психологической поддержки внедряют компании

Опыт Технологического Центра Дойче Банка, Skyeng и MediaСom

Зимний набор на оплачиваемую стажировку в Тинькофф Старт: какие задачи решают стажеры

С 1 декабря 2021 года начинается зимний набор в Тинькофф Старт — программу оплачиваемых стажировок от Тинькофф.

IKEA начала сдавать в Токио квартиры в 10 м² за $0,86 в месяц, чтобы показать, что в них тоже можно жить Статьи редакции

Внутри есть мини-спальня, рабочая зона, диван, стиральная машина и другое.

Юбилей кешбэка: как в 130 лет выглядеть «на все сто»

Кешбэк — возврат определенного процента наличных на карточный счет клиента после покупок в магазинах-партнерах банка или полетах на самолетах авиакомпаний-партнеров-банка или вообще за любые покупки в конкретный период времени — очень популярен в народе. Он выглядит как современная модная финансовая фишка

В «Чёрную пятницу» объем трафика Yota на сайты ритейлеров вырос более, чем на треть

По данным Yota, в «Чёрную пятницу» объем трафика и число переходов на сайты различных ритейлеров среди пользователей оператора выросли более чем на 30% по сравнению с 29 октября, последней пятницей прошлого месяца.

«Вы говорите, а мы слушаем»: айдентика для онлайн-сервиса психологической помощи YouTalk

Привет, на связи команда Логомашины. Забота о ментальном здоровье — это важный тренд последних лет. В этой статье рассказываем, как мы разработали айдентику для YouTalk — сервиса, который уже три года помогает людям из более чем 50 стран справляться с психологическими проблемами.

Время входа

Управляющий активами Дмитрий Космодемьянский — о том, что происходит с рынком облигаций.

Кейс «АнтиШколы»: мы впустую потратили два года на разработку своей платформы и выжили в пандемию благодаря Edvibe

После вуза мы с партнером запустили неформальную АнтиШколу по английскому — с кофе, печеньками, играми и атмосферой антикафе. Но столкнулись с проблемой в онлайне: два года разрабатывали приложение для студентов и потратили порядка $40 тысяч в никуда. Рассказываю, как это было.

Так мы занимаемся английским на крыше! Никаких унылых парт

Факап на 45 млн рублей, выгорание и новый стартап

Это история моего прошлого проекта: ошибок, выводов и опыта, который я применил при создании нового стартапа.

Это я (слева) и Саша (аккаунт менеджер), гуляем по Москве, ждем встречи с партнерами
Можно ли прожить неделю на 1000 рублей, нормально и сбалансировано питаясь?

Мой ответ — да. Рассказываю о своём эксперименте и ощущениях от него.

null