x
 
Лёха Лейберт
13 июня 2019
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Василию Половнёву.

В одном из советов Артём рассказывал о том, как придумали билинг и Бюрокассу в Издательстве бюро.

А как выглядел сам переход на новые, переписанные с нуля, сервисы в техническом плане?


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

Поэтому когда воз­никла част­ная тех­ни­че­ская задача пере­пи­сать с нуля билинг элек­трон­ных книг, мы решили начать с дизайна «поли­мор­фич­ного» про­грамм­ного интер­фейса билинга, кассы и почты, к кото­рым потом смо­гут под­клю­читься и осталь­ные про­дукты бюро:

Задача: отде­лить спи­са­ния (про­цес­синг, кассу) от билинга (тарифы, под­писки, доступ­ные книги), чтобы мини­ми­зи­ро­вать про­блемы с авто­пла­те­жами. Зало­жить фун­да­мент для буду­щих билин­гов на при­мере издательства.

Бюро­би­линг — веб‑сер­вис, отве­ча­ю­щий за про­дажу про­дук­тов и услуг: под­писки, тарифы и авто­про­дле­ние. Опре­де­ляет, когда и сколько спи­сать по ини­ци­а­тиве поку­па­теля, при авто­про­дле­нии и при дру­гих усло­виях. Под­твер­ждает поку­па­телю опе­ра­ции по почте и в интер­фейсе. Напо­ми­нает о про­сро­чен­ных пла­те­жах. У каж­дого про­дукта может быть свой билинг. Мета­фора — про­да­вец продукта.

Бюро­касса — веб‑сер­вис, отве­ча­ю­щий за спи­са­ния с поль­зо­ва­те­лей Бюро­сферы по зада­нию билинга, под­твер­ждает спи­са­ние про­давцу. Мета­фора — бух­гал­тер и кассир.

Спе­ци­фи­ка­ция задачи «Бюро­би­линг и бюро­касса в изда­тель­стве бюро»

Одно­вре­менно с напи­са­нием спе­ци­фи­ка­ции мы иссле­до­вали ста­рый билинг. В первую оче­редь нужно было понять и задо­ку­мен­ти­ро­вать, из чего состоит система, кото­рую мы соби­ра­емся заме­нить: авто­пла­тежи, отмены, письма, спи­са­ния, покупки себе и в пода­рок. Затем необ­хо­димо было опре­де­лить «линии отреза»: места в коде, где нам нужно заме­нить ста­рую систему на новую.

Ещё до начала раз­ра­ботки самих сер­ви­сов мы решили, что будем запус­кать их частями и как можно раньше: запу­стить и отла­дить 100 строк кода гораздо проще, чем 3000 строк, накоп­лен­ных за месяц.

Чтобы мини­ми­зи­ро­вать про­блемы с под­пис­ками, спи­са­ни­ями и ста­биль­но­стью, делали мик­ро­пуски каж­дый день, посте­пенно уве­ли­чи­вая коли­че­ство под­пис­чи­ков, рабо­та­ю­щих с новым кодом. Пере­ход на новые сер­висы занял две недели:

7 ноября, понедельник

Настра­и­ваем и выка­ты­ваем Бюро­кассу в про­дак­шен. Пока с ней никто не работает.

Гото­вим к пуску под­писку в пода­рок на стейджинге.

8 ноября, вторник

Пере­про­ве­ряем под­писку в пода­рок на стей­джинге: про­дле­ние, отмену, напо­ми­на­ния и покупку в подарок.

Про­ве­ряем бое­вую Бюро­кассу: как реа­ги­рует на тай­мауты, как на нагрузку?

9 ноября, среда

Мигри­руем под­писки в пода­рок, их коды и пла­тежи в новый билинг.

Под­клю­чаем новый билинг к бое­вой Бюро­кассе и бое­вому сайту: под­писки в пода­рок начи­нают рабо­тать через новый бэкенд, осталь­ные — через старый.

Вруч­ную запус­каем оче­редь авто­пла­те­жей по пода­роч­ным под­пис­кам на мини­маль­ных выбор­ках по 10 человек.

10 ноября, четверг

Чиним обна­ру­жи­ва­ю­щи­еся про­блемы с под­пис­ками в пода­рок, если есть.

Гото­вим к пуску обыч­ные под­писки на стейджинге.

11 ноября, пятница

Пере­про­ве­ряем обыч­ную под­писку на стей­джинге: про­дле­ние, отмену и покупку.

14 ноября, понедельник

Мигри­руем обыч­ные под­писки и пла­тежи по ним в новый билинг.

Под­клю­чаем обыч­ные под­писки к новому билингу.

Запус­каем оче­редь авто­пла­те­жей в руч­ном режиме: при каж­дом запуске обра­ба­ты­ваем 10 под­пи­сок, про­ве­ряем схему работы.

15 ноября, вторник

Запус­каем оче­редь авто­пла­те­жей в руч­ном режиме: обра­ба­ты­ваем по 20 под­пи­сок, кон­тро­ли­руем вручную.

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

16 ноября, среда

Запус­каем инстру­менты аудита.

Запус­каем оче­редь авто­пла­та­жей в руч­ном режиме: обра­ба­ты­ваем по 40 под­пи­сок, кон­тро­ли­руем вручную.

17 ноября, четверг

Запус­каем оче­редь авто­пла­те­жей в авто­ма­ти­че­ском режиме.

Самым слож­ным в пуске ока­за­лись мигра­ции дан­ных из ста­рого билинга в новый: билинги исполь­зо­вали раз­ные базы дан­ных и раз­ные под­ходы к име­но­ва­нию коло­нок в них, дан­ные в ста­ром билинге были доступны только через SSH. Чтобы решить эти про­блемы, под­клю­чили ста­рую базу дан­ных через SSH‑тун­нель и стан­дарт­ный АПИ ActiveRecord:

require "net/ssh/gateway"
require "mysql2"
​
# Модель, кото­рая даёт доступ к дан­ным в ста­рой БД
# через стан­дарт­ный АПИ ActiveRecord
class LegacySubscription < ApplicationRecord
  self.table_name = "book_subscription"
  ​
  scope :regular, -> { where(type: 1) }
  scope :gifts, -> { where(type: 5) }
  ​
  # Кон­вер­ти­руем инфор­ма­цию о ста­тусе под­писки
  # из ста­рого чис­ло­вого фор­мата в новый
  def status_text
    return "active" if status == 1
    return "inactive" if status.zero?
    return "cancelled" if status == 2
  end
end
​
def open_gateway
  gateway = Net::SSH::Gateway.new("olddb.ssh.masterhost.ru", "olddb")
  gateway.open("olddb.mysql.masterhost.ru", 3306, 3307)
  ​
  gateway
end
​
def within_ssh_tunnel_to_legacy_subscriptions
  # Откры­ваем ssh-тун­нель до ста­рой БД
  gateway = open_gateway
  ​
  connection_params = {
    adapter: "mysql2",
    database: "olddb",
    port: 3307
    password: ENV["DB_IMPORT_PASS"]
  }
  ​
  fork do
    # Соеди­няем LegacySubscription со ста­рой БД
    # и пере­даем управ­ле­ние импорту
    LegacySubscription.establish_connection(connection_params)
  ​
    yield
  end
  ​
  Process.wait
  gateway.shutdown!
end

Импорт офор­мили рейк‑тасками:

namespace :import do
  desc "Import regular subscriptions from artgorbunov.ru"
  task self_subscriptions: :environment do
    within_ssh_tunnel_to_legacy_subscriptions do
      scope = LegacySubscription.regular
      ​
      scope.find_each do |legacy_subscription|
        subscription = Subscription.find_or_initialize_by(
          legacy_subscription_id: legacy_subscription.id
        )
        ​
        subscription.subscription_type = "self"
        subscription.owner_uid = legacy_subscription.ownerId
        subscription.user_uid = subscription.owner_uid
        ​
        subscription.valid_until = legacy_subscription.validUntil
        subscription.issued_at = legacy_subscription.createdDate
        ​
        subscription.status = legacy_subscription.status_text
        subscription.auto_renew = legacy_subscription.autorenew
        ​
        subscription.data = legacy_subscription.data
        ​
        subscription.save
      end
    end
  end
end
Вёрстка и прототипирование — дисциплина Школы дизайнеров. Набор открыт до 12 августа или пока есть свободные места.
 

Поделиться
Отправить

Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

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

Вот такой веб 2.0.

Как менеджеру ставить задачи, чтобы ротация в команде не заставляла пережёвывать все задачи устно по 100 раз? Режимы наложения в ЦСС 2 Есть ли смысл учить Ruby on Rails в 2019 году? 3 Где провести границу MVP? 1




Недавно всплыло

Как найти себе замену 1 2 2 2