Skip to main content

Tech ans

Как добавить событие на кнопку на сайте?​

Как добавить событие на кнопку на сайте с использованием Google Analytics (формат Universal Analytics 2018 года) и Яндекс.Метрики через Google Tag Manager​

Вот пошаговая инструкция, как это сделать с использованием JavaScript, Google Tag Manager, Google Analytics (старый формат) и Яндекс.Метрики.

1. Создание кнопки на странице​

Сначала создаем кнопку на HTML-странице:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Button Event Example</title>
</head>
<body>

<!-- Кнопка -->
<button id="myButton">Click Me!</button>

<!-- Скрипт -->
<script>
// Найти кнопку по ID
const button = document.getElementById('myButton');

// Добавить событие клика
button.addEventListener('click', function() {
// Действие, которое нужно выполнить при нажатии
alert('Button was clicked!');

// Отправка события в Google Analytics (Universal Analytics)
ga('send', 'event', {
eventCategory: 'Button',
eventAction: 'Click',
eventLabel: 'My Button'
});

// Отправка события в Яндекс.Метрику
if (typeof ym !== 'undefined') {
ym(YOUR_METRICA_ID, 'reachGoal', 'buttonClick');
}
});
</script>

</body>
</html>

2. Установка Google Tag Manager (GTM)​

  1. Зарегистрируйтесь или войдите в Google Tag Manager (GTM): Google Tag Manager.
  2. Создайте контейнер для своего сайта.
  3. Установите код GTM на все страницы сайта:

Код для вставки в <head> вашего сайта:​

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->

Код для вставки сразу после открытия тега <body>:​

<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->

Замените GTM-XXXXXXX на ваш ID GTM.

3. Настройка Google Analytics через GTM (Universal Analytics)​

  1. Войдите в Google Tag Manager.
  2. Создайте новый Тег.
    • Тип тега: Google Analytics: Universal Analytics.
    • Тип отслеживания: Событие.
    • Категория: Button
    • Действие: Click
    • Ярлык: My Button
  3. Создайте триггер:
    • Тип триггера: Click - All Elements.
    • Настройте, чтобы триггер срабатывал только при нажатии на кнопку с определенным ID (например, #myButton).
  4. Сохраните изменения и опубликуйте контейнер.

4. Настройка Яндекс.Метрики через GTM​

  1. В Яндекс.Метрике создайте счетчик для вашего сайта: Яндекс.Метрика.
  2. Войдите в Google Tag Manager.
  3. Создайте новый Тег.
    • Тип тега: Пользовательский HTML.
    • Вставьте следующий код:
<script type="text/javascript">
ym(YOUR_METRICA_ID, 'reachGoal', 'buttonClick');
</script>

Замените YOUR_METRICA_ID на ваш идентификатор счетчика Яндекс.Метрики.

  1. Создайте триггер для отслеживания кликов по кнопке:
    • Тип триггера: Click - All Elements.
    • Настройте, чтобы триггер срабатывал только на кнопке с ID #myButton.
  2. Сохраните изменения и опубликуйте контейнер.

5. Проверка работы​

  1. Откройте ваш сайт и откройте Google Tag Manager Debug Mode.
  2. Нажмите на кнопку и проверьте, отправляются ли события в Google Analytics и Яндекс.Метрику.
  3. В Google Analytics в разделе Отчет по событиям и в Яндекс.Метрике в разделе Цели можно отслеживать, были ли получены данные.

1. Почему через id, а не через class?​

Использование id:​

  • Плюсы:

    • Уникальность: В HTML элемент с id уникален на странице. Это упрощает доступ к конкретному элементу, так как он всегда будет один.
    • Быстродействие: Поиск элемента по id с помощью document.getElementById работает быстрее, чем по class, поскольку браузеру не нужно проверять множество элементов.
    • Точность: Если у вас есть только один элемент, который должен вызывать событие, id гарантирует, что вы работаете именно с этим элементом.
  • Минусы:

    • Ограничение на один элемент: Если вам нужно применить событие к нескольким элементам, вам придется использовать другие методы, так как id может быть только один на странице.

Использование class:​

  • Плюсы:

    • Гибкость: Вы можете применять класс к нескольким элементам и легко привязывать события ко всем этим элементам.
    • Повторное использование: Одним и тем же классом можно обозначить несколько элементов на разных страницах, и таким образом легко привязывать события ко множеству кнопок сразу.
  • Минусы:

    • Сложнее работать с уникальными элементами: Если вам нужно привязаться только к одному конкретному элементу, использование класса может создать сложности, если на странице несколько элементов с этим классом.
    • Меньшая производительность: Поиск элементов с помощью document.querySelectorAll('.class') может быть медленнее, особенно если элементов много.

2. Почему я отправлял события в GA и Метрику напрямую из кода?​

Я сделал это для демонстрации того, как можно добавить отправку событий в коде. Однако, если вы все делаете через GTM (что является лучшей практикой), то этот код не нужен. В идеальной ситуации:

  • GTM берет на себя отправку всех событий в Google Analytics и Яндекс.Метрику.
  • В коде сайта вы просто устанавливаете триггеры на события, такие как клик по кнопке, а GTM уже решает, куда и какие данные отправлять.

3. Правильная настройка через GTM:​

  • Что нужно сделать через GTM:
    1. Установка триггера для кнопки. Можно использовать либо id, либо class, в зависимости от того, сколько кнопок вам нужно отслеживать. Если одна кнопка — id, если несколько — class.
    2. Отправка событий:
      • В Google Analytics с помощью соответствующего тега события.
      • В Яндекс.Метрику через тег "Пользовательский HTML" или встроенные теги, если таковые доступны.

4. Когда использовать id или class в GTM?​

  • Использование id: Лучше подходит, если на странице одна кнопка или если нужно отслеживать конкретную кнопку. Это также ускоряет процесс поиска и исключает случайное срабатывание на других элементах.
  • Использование class: Полезно, если у вас много кнопок, и все они должны вызывать одно и то же событие. В таком случае можно отслеживать все кнопки с определенным классом, чтобы не привязываться к уникальным id.

Заключение:​

  • id удобен для уникальных элементов.
  • class лучше подходит для массовых событий, когда несколько элементов должны вызывать одно и то же событие.
  • GTM — это лучший инструмент для отправки данных в Google Analytics и Яндекс.Метрику, избавляющий от необходимости писать код для отправки событий вручную.

У вас все настроено через GTM, и это правильный подход.

Таблица​

ПроектUser Flow (Пользовательский сценарий)Технологии
RBAC Система - CRM (2024)Аутентификация пользователей, назначение ролей, проверка правJWT токены, React, Node.js, MongoDB, реляционная БД
Бухгалтерская программа SFH (2018)Отслеживание платежей в реальном времени, валидация, генерация отчетовAWS EC2, Amazon RDS, MySQL/PostgreSQL, REST API
Система отчетности SFH (2018)Сбор данных, генерация отчетов, уведомленияAPI Google Ads, API Facebook Ads, Amazon RDS, Power BI
Программа Rules (2018-2022)Управление ставками, планирование кампаний, генерация отчетовReact.js, Node.js, MongoDB, Yandex API, Docker
Система доставки - COVID (2020)Обновления меню, управление заказами в реальном времени, обработка платежейReact.js, Node.js, MySQL, Redis, WebSockets, Stripe
Сегменты для видео на Яндексе (2019)Сегментация видео по пользователям, связывание сценариев, интеграция APIReact.js, Node.js, DynamoDB, AWS Lambda, Yandex API
Система A/B тестирования (2018)Настройка тестов, сегментация трафика, агрегация результатовReact.js, Node.js, Yandex.Cloud, Google Analytics
Парсер цен конкурентов (2017)Парсинг цен конкурентов, управление парсерами для различных сайтовASP.NET, C#, Multiton Singleton, HTML Agility Pack
Платформа для обучения SFH (2019)Персонализированные учебные пути, результаты тестов, доставка контентаReact.js, Node.js, MongoDB, Google OAuth, YouTube API
Ресторан Turandot (2019)Групповые бронирования, локализованная страница для китайских туристовHTML5, CSS3, jQuery, Google Analytics, MySQL/PHP
Инвентарная система для игры (2022)Перетаскивание предметов в инвентаре, управление предметамиUnity, C#, Event System, ScriptableObjects, Colliders
Платежная система LMR (2021)Отслеживание покупок на разных платформах, защита аккаунта, обработка платежей в реальном времениC#, AES шифрование, REST API, SQL Server/PostgreSQL, OAuth 2.0
Тренинговая платформа SFH (2019)Персонализированные учебные пути, результаты тестов, доставка учебного контентаReact.js, Node.js, MongoDB, Google OAuth, YouTube API
Гиперсегментированные рекламные кампании (2018)Настройка рекламных кампаний, динамическая сегментация, анализ конверсийYandex.Direct API, HTML5, CSS3, PHP, JavaScript

RBAC (Role-Based Access Control) - JWT 2024​

The goal of RBAC was to ensure that users could only access resources and perform actions based on their roles within the system. This model is highly scalable and secure, as roles can be assigned based on job functions or responsibilities, restricting access to sensitive data.

Key Components of the RBAC System:​

  1. Users: Represents individuals interacting with the system. Each user is assigned one or more roles.
  2. Roles: A role defines a collection of permissions, which represent what actions a user in that role can perform. For example, roles could include "Admin," "Manager," and "Support Agent."
  3. Permissions: Permissions are the specific actions allowed for a particular resource, such as "create," "read," "update," or "delete" (CRUD operations).
  4. Resources: These are the objects or data within the CRM that users can interact with, such as leads, clients, projects, or tasks.

RBAC Workflow:​

  1. User Authentication: Users authenticate via JWT tokens. Once the token is issued, the system verifies the token on every request to ensure the user is authenticated.
  2. Role Assignment: Once a user is authenticated, the system checks the user’s assigned roles from the database.
  3. Permission Checking: Based on the user’s role, the system grants or denies access to certain resources and actions.

Data Structure for RBAC:​

The data structure for RBAC typically involves several relational tables in the database. Here’s how it could have been structured:

  1. Users Table:

    • Stores information about each user.
    • Fields: user_id, username, email, password_hash, created_at.
    • Example:
      +---------+-----------+----------------+-------------------------+
      | user_id | username | email | password_hash |
      +---------+-----------+----------------+-------------------------+
      | 1 | jdoe | jdoe@email.com | hashedpasswordhere |
      +---------+-----------+----------------+-------------------------+
  2. Roles Table:

    • Defines the available roles in the system.
    • Fields: role_id, role_name, description.
    • Example:
      +---------+------------+-------------------------------+
      | role_id | role_name | description |
      +---------+------------+-------------------------------+
      | 1 | Admin | Full access to all resources |
      | 2 | Manager | Access to manage projects |
      | 3 | Support | Can view and update tickets |
      +---------+------------+-------------------------------+
  3. Permissions Table:

    • Defines the possible actions that can be performed on resources.
    • Fields: permission_id, action, resource.
    • Example:
      +---------------+--------+-------------+
      | permission_id | action | resource |
      +---------------+--------+-------------+
      | 1 | read | leads |
      | 2 | update | leads |
      | 3 | delete | leads |
      | 4 | create | projects |
      | 5 | read | projects |
      +---------------+--------+-------------+
  4. Role-Permissions Table:

    • Maps roles to specific permissions.
    • Fields: role_permission_id, role_id, permission_id.
    • Example:
      +-------------------+---------+---------------+
      | role_permission_id | role_id | permission_id |
      +-------------------+---------+---------------+
      | 1 | 1 | 1 | // Admin can read leads
      | 2 | 1 | 2 | // Admin can update leads
      | 3 | 2 | 5 | // Manager can read projects
      +-------------------+---------+---------------+
  5. User-Roles Table:

    • Links users to their assigned roles.
    • Fields: user_role_id, user_id, role_id.
    • Example:
      +-------------+---------+---------+
      | user_role_id| user_id | role_id |
      +-------------+---------+---------+
      | 1 | 1 | 1 | // jdoe is an Admin
      | 2 | 2 | 2 | // janedoe is a Manager
      +-------------+---------+---------+

Flow of RBAC in Action:​

  1. User Authentication:

    • A user logs into the CRM system, which returns a JWT token. The token is signed and includes user details such as user_id.
  2. Token Verification:

    • On each request, the server checks the JWT token for validity and extracts the user_id to determine the user's roles and permissions.
  3. Permission Validation:

    • Based on the user_id, the system queries the User-Roles table to get the user’s roles.
    • Then, it checks the Role-Permissions table to see which actions the user’s role is allowed to perform on specific resources.
    • For instance, if a Manager tries to update a project, the system checks whether the Manager role has the update permission on the projects resource. If it does, the request is authorized; otherwise, it’s denied.

JWT Integration for Authorization:​

  • Stateless Authentication: By using JWT tokens, the system doesn’t need to store session data on the server. The JWT contains encrypted user information, including their user_id and roles, which are verified on every request.
  • Security: The JWT token is signed with a secret key and can be verified for authenticity without needing to store session state in the backend. This makes it highly scalable and secure.

Scalability and Security:​

  • Scalability: By using stateless JWT tokens, the authorization system is highly scalable. Each request is self-contained, meaning no session management is required, and any server can validate the JWT without needing to consult a centralized session store.
  • Fine-Grained Access Control: The RBAC model allows for fine-grained control over who can access which resources, based on roles. This ensures that sensitive data is protected and only authorized users can perform certain actions.
  • Auditing: The system could also include an auditing mechanism to log who accessed which resources and performed what actions, which is essential for tracking in secure systems.

Resulting Benefits:​

  • The RBAC system ensured that users only had access to the data and functionality their role allowed, protecting sensitive information from unauthorized access.
  • The use of JWT tokens provided an efficient, secure, and stateless way to manage authentication, improving the system's scalability.
  • The modular design of roles, permissions, and resources allowed for easy updates and changes to the access control policies without requiring major architectural changes.

This approach provided the CRM with a robust, scalable, and secure authorization and permissions management system.

Бухгалтерская программа для sfh 2018​

Database:​

A relational database such as Amazon RDS (MySQL or PostgreSQL) was used to store transaction and payment information. The primary tables in the database included:

Clients:​

Storing client details, payment terms (prepaid or postpaid), and related information.

Transactions:​

Containing records of all payments, including transaction IDs, dates, amounts, and statuses.

Accounts:​

Storing internal accounting data such as account numbers, balances, and reconciled/unreconciled payments.

Invoices:​

For storing invoice information, including due dates, amounts, and payment statuses.

Discrepancies:​

Logging any potential payment issues or mismatches detected during real-time tracking.

Data Collection System:​

To enable real-time payment tracking, the system integrated with banking APIs (e.g., through REST API endpoints) to retrieve transaction data. The server regularly made API requests to banking services to update the status of incoming and outgoing payments, track failed or delayed transactions, and identify any discrepancies between expected and actual payment data.

Data Ingestion:​

The system fetched transaction data from the banking APIs every hour or when triggered by new incoming payment events.

Payment Validation:​

Once fetched, the system cross-referenced the transactions with the internal accounting records stored in the database to ensure consistency.

Discrepancy Detection:​

Any differences (e.g., incorrect amounts or missed payments) were logged in the Discrepancies table, triggering automatic notifications to the relevant personnel.

Overdue Payment Notifications:​

At the end of each month, the system sent automated reminders for overdue payments, with specific logic for prepaid (end of month) and postpaid (30 days after invoice) clients.

Report Generation:​

An automatic report generation module aggregated the monthly payment data and created comprehensive reports that were sent to the accounting team, replacing manual report preparation.

Application Server Workflow:​

The application server, hosted on AWS EC2 instances, managed data collection, processing, and storage. It was responsible for:

Scheduling Data Retrieval:​

The server scheduled API calls to banking services to retrieve payment data at regular intervals.

Data Processing:​

After receiving payment data, the server processed the information by validating transactions against the database, updating payment statuses, and logging discrepancies.

Notification System:​

The server triggered email notifications for overdue payments or discrepancies, ensuring the accounting team was promptly informed of potential issues.

Report Creation:​

At the end of each month, the server generated detailed accounting reports based on collected transaction data and sent them to the finance department.

Functional Requirements:​

Real-time Payment Monitoring:​

Integration with banking APIs to fetch real-time transaction data.

Automatic Payment Validation:​

The system must automatically cross-reference payments with internal records to detect discrepancies.

Overdue Payment Notifications:​

Automated notifications for overdue payments (end of month for prepaid, 30 days after invoice for postpaid).

Automatic Report Generation:​

Generation of monthly reports with transaction summaries and discrepancies.

User Management:​

Support for multiple users (accountants) with access to payment data and reports.

Non-functional Requirements:​

Scalability:​

The system should handle increasing volumes of payment transactions as the client base grows. AWS EC2 and Amazon RDS provide horizontal scalability.

Reliability:​

Payment data must not be lost during network or server failures. The system should ensure data consistency and durability.

Security:​

Sensitive financial data must be encrypted at rest and in transit. Authentication and authorization mechanisms are required for users.

Performance:​

The system should process payment validation and discrepancy detection within seconds of receiving data from the banking APIs.

Availability:​

The system should be available 24/7 with minimal downtime, particularly around key financial reporting periods at the end of the month.

Program Flow:​

Data Retrieval:​

The system fetches transaction data from banking APIs either on a schedule or as events are triggered by incoming payments.

Payment Validation:​

The retrieved data is compared against the internal accounting records in the database.

Discrepancy Logging:​

If there is a mismatch (e.g., incorrect payment amount, missed payment), it is recorded in the database and notifications are sent.

Monthly Processing:​

At the end of the month, the system checks for overdue payments and sends reminders for prepaid and postpaid projects.

Report Generation:​

Monthly reports summarizing all payment data, discrepancies, and overdue payments are automatically generated and sent to the accounting team.

Here's how you can enhance the story while adding the requested details:


Banking API Integration - Tinkoff Bank​

For the banking integration, the system used Tinkoff Bank’s API to track transactions in real time. The system utilized RESTful API endpoints provided by Tinkoff Bank to fetch data on transactions, payment statuses, and account balances. Authentication to the API was handled through OAuth 2.0, ensuring secure access. The system periodically made API calls to endpoints such as:

  • GET /transactions: To retrieve transaction data
  • GET /accounts: To check account balances
  • POST /payments: To initiate payments
  • GET /payment-status: To track the status of payments

In addition to regular data fetching, the system also handled webhook events from Tinkoff Bank, enabling real-time updates when new transactions occurred or when the status of a payment changed. This event-driven integration allowed the system to quickly detect discrepancies between expected and actual payment data and triggered immediate logging of any issues.


Step-by-Step User Flow​

Accountants:​

  1. Login: The accountant logs in using their credentials, authenticated through a secure mechanism like OAuth 2.0.
  2. Payment Validation: The system automatically validates payments by comparing data fetched from the Tinkoff Bank API with internal accounting records stored in the database. If discrepancies are found, they are logged, and an alert is generated.
  3. Report Generation: At the end of the month, the system automatically generates financial reports showing transaction summaries and discrepancies. The accountant can manually review these reports.
  4. Overdue Payment Notifications: Accountants receive notifications at the end of the month for overdue payments, with separate notifications for prepaid and postpaid clients.
  5. Discrepancy Management: In case of discrepancies, the accountant can view the details in the system, check the transaction data, and resolve issues directly.

Managers:​

  1. Dashboard Overview: Managers have access to a dashboard summarizing the financial health of the company, including total incoming and outgoing payments, overdue payments, and discrepancies.
  2. Report Review: Managers can review the automatically generated monthly reports for high-level insights into the financial performance.
  3. Alerts and Notifications: In case of any major discrepancies or significant overdue payments, managers receive automated notifications, allowing them to address issues proactively.

Libraries for Data Processing and Report Generation​

  • Pandas: Used for data processing, particularly in aggregating transaction data and calculating discrepancies.
  • NumPy: Employed to handle numerical operations during payment validation.
  • Matplotlib/Seaborn: These libraries were used for creating visual reports, including graphs and charts that depicted transaction trends, discrepancies, and overdue payments.
  • Jinja2: Utilized for templating reports in HTML and PDF format, providing a structured and customizable layout for monthly accounting reports.

These enhancements provide more technical details about the APIs, user flows, and libraries used in the system.

Система отчетности sfh 2018​

Database:​

A relational database such as Amazon RDS (MySQL or PostgreSQL) was used to store report data. This database housed both raw data fetched from advertising platforms and processed reports for various clients. Key tables included:

Clients:​

Table with client information and their subscription plans.

Ad Campaigns:​

Data on active campaigns.

Report Data:​

Aggregated data from platforms for further processing.

Reporting Settings:​

Settings for report generation for each client, including format and frequency.

Data Collection System:​

API integrations (Google Ads API, Facebook Ads API, etc.) were used to retrieve data from advertising platforms. The application server regularly sent requests to these APIs to collect data on ad campaigns, costs, clicks, impressions, and other metrics, which were then saved in the database for further processing.

Data Collection:​

Automated data collection occurred hourly or daily, depending on client requirements.

Data Processing:​

Raw data was cleaned, normalized, and aggregated for easier reporting.

Report Generation:​

Depending on the client, reports were either generated in table format for Google Docs or converted into visualizations for Power BI.

Notifications:​

Clients were notified via email when their reports were ready.

Application Server Workflow:​

The application was hosted using AWS EC2 for compute tasks and S3 for storing large volumes of raw data. The server performed scheduled tasks, contacting advertising platform APIs, processing the data, and then outputting it to Google Docs or Power BI. Client interactions were facilitated through a REST API, allowing them to request real-time data or view completed reports.

Functional Requirements:​

  • Advertising Platform Integration: Support for APIs from systems such as Google Ads, Facebook Ads, and others.
  • Automated Data Collection: The system must automatically query and collect data from advertising platforms at scheduled intervals.
  • Report Generation: Reports must be generated both in table format (for Google Docs) and as visualizations (for Power BI).
  • Support for Multiple Clients: Each client has unique report settings (format, frequency, metrics).
  • Client Notifications: Clients should receive notifications once their reports are ready.

Non-functional Requirements:​

  • Scalability: The system should support an increase in the number of clients without performance degradation. AWS EC2 and Amazon RDS will ensure horizontal and vertical scaling.
  • Reliability: Data must not be lost during network or server failures and must be recoverable in case of system failure.
  • Security: Access to data should be secured via authentication and encryption. Sensitive data, such as client information and confidential reports, must be encrypted.
  • Performance: Report generation time should not exceed a few seconds for Google Docs and up to a few minutes for larger Power BI visualizations.
  • API Response Time: Client requests to the system should be processed within 200-300 ms.

Database:​

A relational database such as Amazon RDS (MySQL or PostgreSQL) was used to store both raw data fetched from advertising platforms and processed reports for various clients. The database contained the following key tables:

  • Clients: Storing client information, including subscription plans, report frequency, and required metrics.
  • Ad Campaigns: Tracking data on active and historical advertising campaigns.
  • Report Data: Aggregating data from advertising platforms for further processing.
  • Reporting Settings: Settings for report generation, such as format preferences and frequency for each client.

Data Collection System:​

The system integrated with several advertising platforms' APIs to automate data retrieval. Specifically:

  • Google Ads API: Used to gather data on impressions, clicks, and costs for ad campaigns.
  • Facebook Ads API: Collecting similar data, including engagement metrics.
  • LinkedIn Ads API: For clients running professional campaigns on LinkedIn, retrieving key metrics.

These APIs were accessed using OAuth 2.0 authentication, ensuring secure data collection. Requests were made hourly or daily depending on client needs, with data stored in Amazon RDS for further processing.

Data Processing:​

The raw data fetched from these APIs was cleaned, normalized, and aggregated. Key operations included:

  • Data Cleaning: Ensuring all incoming data had consistent formats (e.g., date formats and numerical precision).
  • Normalization: Standardizing metrics across platforms (e.g., impressions, clicks, conversions) to enable easier aggregation.
  • Aggregation: Summarizing data by day, week, or month, as required by client reports.

The system used Apache Airflow for orchestrating data collection, cleaning, and processing tasks.

Report Generation:​

Reports were generated based on client preferences:

  • Google Docs: Standard clients received reports in tabular format, exported to Google Docs for easy access. The integration with Google Docs API allowed reports to be automatically updated.
  • Power BI: VIP clients received more in-depth visual reports through Power BI, where key performance indicators (KPIs) were visually represented through charts and graphs.

Notifications:​

Upon report generation, the system automatically notified clients via email. The notification system was built using AWS SES (Simple Email Service).

Application Server Workflow:​

Hosted on AWS EC2 instances, the application server managed data collection, processing, and report generation. Large volumes of raw data were stored in AWS S3, enabling scalable storage and quick access for report generation. Key tasks performed by the server included:

  1. API Calls: The server regularly fetched data from advertising platform APIs, updating client campaign metrics in the database.
  2. Data Processing: Cleaned and aggregated the data using pandas and NumPy libraries.
  3. Report Generation: Generated reports either in Google Docs format or as Power BI visualizations, using the Jinja2 templating engine for custom reports.
  4. Client Interaction: Exposed a REST API for clients to request real-time data or access completed reports.

Functional Requirements:​

  • Advertising Platform Integration: Support for APIs from platforms such as Google Ads, Facebook Ads, LinkedIn Ads, and others.
  • Automated Data Collection: Automatically querying and collecting data from these platforms at scheduled intervals.
  • Report Generation: Generating reports in both table format (Google Docs) and as visualizations (Power BI).
  • Multi-client Support: Unique report settings per client, including customized metrics and frequency.
  • Client Notifications: Automatic notifications when reports are generated.

Non-functional Requirements:​

  • Scalability: Using AWS EC2 and Amazon RDS ensures horizontal and vertical scaling to support an increasing number of clients without performance degradation.
  • Reliability: With regular backups to Amazon S3 and database replication in Amazon RDS, the system ensures data reliability and availability.
  • Security: Data encryption was implemented both at rest and in transit, with OAuth 2.0 used for secure API authentication. Access to client data was secured through strict role-based access control.
  • Performance: Report generation times were kept within a few seconds for Google Docs and up to a few minutes for Power BI, ensuring timely report delivery.
  • API Response Time: API calls from clients had a response time of 200-300 ms, ensuring a responsive user experience.

Libraries and Tools:​

  • pandas: Used for data cleaning, aggregation, and manipulation.
  • NumPy: Handling numerical operations during data normalization and processing.
  • Matplotlib/Seaborn: For generating visual reports, particularly for Power BI exports.
  • Jinja2: Utilized for templating custom HTML reports and ensuring consistent report formatting.
  • Apache Airflow: Managed and scheduled the various ETL tasks, ensuring smooth and automated data pipelines.

These additions provide a more detailed technical overview, covering the APIs, data processing, and libraries used in the SFH Reporting System.

DataDriven подход - программа Правила 2018 - 2022​

1. Frontend (User Interface) Implementation:​

  • How: The frontend was built using React.js for creating an intuitive, responsive, and interactive user interface. The interface allowed users to create and manage advertising campaigns within a single window. Components included forms for uploading ad content, bid management tools, and scheduling features. Material-UI was used to provide pre-built UI components, like tables, dropdowns, and modal dialogs, ensuring consistency in design.

  • Why:

    • React.js was chosen for its dynamic rendering capabilities, which made managing multiple campaigns and large datasets fast and smooth. This was essential for a user-friendly experience in a system that handled complex advertising configurations.
    • Material-UI provided a professional design system and sped up development by offering pre-built components, allowing for rapid prototyping and implementation.

2. Backend (Core Logic):​

  • How: The backend was developed using Node.js with Express.js to handle API requests and connect the frontend to the database. The backend processed ad campaign data, managed bid adjustments, and communicated with external advertising platforms through their APIs (e.g., Google Ads API, Yandex.Direct API). The system could send requests for bid management and campaign scheduling, adjusting ad spends dynamically based on performance metrics.

  • Why:

    • Node.js was selected for its event-driven architecture, making it suitable for managing high volumes of requests and real-time data updates, critical for bid adjustments and campaign scheduling.
    • Express.js provided a minimalistic framework that made it easy to build RESTful APIs for communication between the frontend, backend, and external advertising platforms.

3. Data Management:​

  • How: MongoDB was used as the primary database to store campaign configurations, bid data, schedules, and performance metrics. MongoDB’s flexible document-based structure allowed for easy storage and retrieval of unstructured advertising data, such as campaign settings and keyword-level bid information.

  • Why:

    • MongoDB was chosen for its ability to handle complex and dynamic data structures, which were essential for storing various types of campaign data. The ability to scale the database was important given the number of campaigns and bid adjustments that needed to be managed across multiple projects.

4. Automation and Bid Management:​

  • How: The system featured bid management automation at the keyword level. A set of rules or algorithms were applied based on performance data (e.g., conversion rates, click-through rates) to adjust bids dynamically. The system also allowed users to set specific bid floors and ceilings to control costs.

  • Why:

    • Automating bid management was critical for optimizing ad spend and ensuring that bids were aligned with campaign performance. This data-driven approach allowed for real-time adjustments, reducing manual work for the marketing team and improving overall efficiency.

5. Scheduling and Control:​

  • How: Campaign schedules were managed using a cron-based system that allowed users to configure start and end times for campaigns, as well as specific hours or days of the week for ad delivery. The system also featured a dashboard that displayed the status of campaigns (e.g., active, paused, scheduled).

  • Why:

    • Scheduling campaigns ensured that ads were only shown during optimal times, improving the return on ad spend (ROAS). By providing control over when ads ran, the system reduced waste and allowed for better targeting.

6. Integration with Advertising Platforms:​

  • How: The system integrated with external advertising platforms (e.g., Google Ads, Yandex.Direct) using their respective APIs. These integrations allowed the system to push campaign data, adjust bids, and pull performance metrics directly from the platforms.

  • Why:

    • API integration was essential for real-time data exchange between the system and advertising platforms. This allowed for dynamic adjustments to be made without manual input, ensuring that campaigns were always optimized based on current performance data.

7. Data-Driven Approach:​

  • How: The system used a data-driven approach by continuously analyzing campaign performance metrics. It pulled data such as click-through rates (CTR), conversions, and cost-per-click (CPC) from the advertising platforms, and then adjusted bids or paused campaigns based on predefined rules.

  • Why:

    • A data-driven approach allowed for real-time optimization, ensuring that marketing managers didn’t have to manually adjust campaigns. This led to more efficient use of advertising budgets and improved overall performance.

8. Reporting and Analytics:​

  • How: The system generated detailed reports that included metrics like spend, conversions, CTR, and CPC for each campaign. The reports were presented in a user-friendly dashboard with visualizations (e.g., charts, graphs) for easy interpretation. The data was also exportable to CSV for further analysis.

  • Why:

    • Providing clear, visual reports was crucial for giving marketing managers insight into the performance of their campaigns. This allowed them to quickly identify what was working and what needed adjustment, making the decision-making process more informed and data-driven.

9. Scalability and Maintenance:​

  • How: The system was designed with scalability in mind, using Docker for containerization. This made it easier to deploy and scale the application as the number of campaigns and projects grew. AWS or a similar cloud service was used for hosting to ensure high availability and load balancing across multiple users.

  • Why:

    • Docker provided an efficient way to manage the deployment environment, ensuring consistency across different servers and making it easier to scale. Cloud hosting ensured that the system could handle peak traffic and multiple concurrent users without performance degradation.

10. Result and Success:​

  • How: The program processed ad campaigns for over 100 projects and handled thousands of campaigns across multiple platforms over the course of 4 years. The system was integrated into the agency’s workflow, becoming a central tool for campaign management.

  • Why:

    • The system’s ability to manage complex campaigns, automate bid adjustments, and control scheduling resulted in more efficient use of ad budgets, leading to over $1 million in ad optimization. This data-driven approach improved decision-making and reduced manual work, allowing marketing managers to focus on strategy.

Summary of Implementation and Rationale:​

  1. Frontend:

    • How: React.js with Material-UI for a responsive and user-friendly interface.
    • Why: React’s fast rendering and component-based structure made it ideal for managing multiple campaigns and configurations.
  2. Backend:

    • How: Node.js with Express.js to handle API requests and manage external platform integrations.
    • Why: Node.js’ non-blocking architecture ensured high performance with real-time updates, essential for bid management.
  3. Database:

    • How: MongoDB to store campaign data, schedules, and bid settings.
    • Why: MongoDB’s flexible schema allowed for easy scaling and efficient handling of dynamic data.
  4. Automation:

    • How: Automated bid adjustments and scheduling using predefined rules and cron jobs.
    • Why: Automation reduced manual effort and improved efficiency, optimizing ad spend.
  5. Integration:

    • How: Integrated with advertising platforms via APIs (e.g., Google Ads, Yandex.Direct).
    • Why: API integration ensured real-time updates and control over campaigns, making the system more efficient and responsive.
  6. Data-Driven Optimization:

    • How: Real-time performance analysis to adjust bids and optimize campaigns.
    • Why: This approach improved ad performance, maximizing returns on the ad budget and saving over $1 million in optimization.

This system helped the agency streamline its advertising operations, improving efficiency, reducing costs, and ensuring that marketing managers could manage campaigns through a single, unified platform. The data-driven approach enhanced decision-making, and automation significantly reduced manual tasks, leading to better overall performance for both the agency and its clients.

Работа с блокировкой телеграмм 2018​

Original AWS System Structure (Before the Incident):​

AWS EC2 Instances: The "Rules" program, responsible for managing ad bids, budget optimization, and report generation, was fully hosted on Amazon EC2 instances.

AWS RDS (Relational Database Service): Data on ad campaigns, budgets, transactions, and performance metrics were stored in Amazon RDS.

S3 Storage for Reports: Processed data and reports were stored in Amazon S3, from where they were delivered to clients and internal stakeholders.

CloudFront: Used for content delivery, ensuring fast report access for clients across different regions.

Reliance on AWS Infrastructure: All these services were centralized on AWS, making the system vulnerable to outages and blocks targeting AWS IP addresses.

New Hybrid System Structure with an On-Premises Server:​

After the incident, the architecture was restructured to add on-premises infrastructure, creating a hybrid setup. The key change was deploying an in-house server to take over critical functions for key clients. Here's how the new system was designed:

1. On-Premises Server Deployment:​

Local Server Setup: A dedicated on-premises server was deployed within the company's internal infrastructure or a private data center. This server was configured to handle the most critical aspects of the "Rules" program, such as ad bid management and report generation for high-priority clients.

Partial Migration of "Rules" Program: The core components of the "Rules" program, including the algorithms responsible for managing bids and processing ad performance data, were migrated from AWS to the local server. This ensured that key clients’ ads remained optimized even if the AWS infrastructure was unavailable.

2. Local Database Setup:​

Local Database (PostgreSQL or MySQL): A database was set up on the local server, storing the most critical client data, such as ad performance metrics, budget data, and report logs. This allowed the system to function autonomously without relying on AWS RDS during the period of downtime.

Data Synchronization: A data synchronization mechanism was established to ensure that the local database would be periodically updated with new data from AWS (once it became available again). This could be done using cron jobs or a custom sync tool to regularly import data from the cloud to the on-premises database.

3. Bid Management and Manual Controls:​

Ad Bid Management: The bid optimization algorithms were moved to the local server. This allowed the system to continue managing and optimizing ad bids based on real-time performance data, ensuring that clients’ advertising budgets were not overspent.

Manual Overrides for Ad Managers: Ad managers were given manual access to the system on the local server to adjust bids and manage campaigns manually if necessary. This provided a level of control that wasn’t available when the system was fully automated on AWS.

4. Local Report Generation:​

Automated Report Generation on Local Server: The report generation logic was partially replicated on the on-premises server, ensuring that key clients continued to receive their reports even during the outage.

Stored Reports for Priority Clients: Reports were generated and stored locally in JSON or CSV format for distribution via email or manual upload to a client portal.

5. VPN for Secure Remote Access:​

VPN Access for Remote Management: A VPN was configured to allow remote access for ad managers and IT staff to monitor the local server, manage bids, and view logs from remote locations. This ensured that the team could still manage the system securely during lockdowns and remote work scenarios.

6. Backup and Redundancy:​

Local Backups: Regular backups of both the local database and ad management software were created and stored both on-site and in secure external storage (such as a separate physical location or a non-blocked cloud service like Microsoft Azure).

Disaster Recovery Plan: A disaster recovery plan was developed to allow quick redeployment of the local server in case of hardware failure, including replication of critical services and data from off-site backups.

7. Local Load Balancing and Failover:​

Local Load Balancer: A load balancer was set up to handle requests and ensure that the server remained responsive during peak traffic times or when multiple users accessed the system simultaneously.

Failover to Cloud: In the event that the local server experienced downtime, a failover system was established to direct traffic back to the AWS cloud infrastructure (once it was operational again), ensuring minimal disruption.

Flow of Operations After the Rebuild:​

Client Requests: Clients continue to manage their ad campaigns and access reports via the existing interfaces, with critical requests (from top clients) now being routed to the local server.

Ad Bid Management: The local server processes ad bid updates using the migrated bid management algorithms, ensuring real-time optimization based on available data.

Data Sync and Reporting: The local database stores campaign performance data, and reports are generated locally. Data is periodically synced with AWS once the cloud infrastructure becomes accessible again.

Manual Adjustments: If needed, ad managers can access the system through the VPN to manually adjust bids and control campaigns, maintaining control over spending during outages.

Client Communication: Critical client reports are generated on the local server and delivered manually or via email, ensuring that clients remain informed about campaign performance despite the AWS disruption.

Работа над игрой LMR 2021​

1. Payment System Development:​

The task involved creating a secure payment system for the online store, which needed to handle transactions efficiently and securely across both mobile and desktop platforms.

AES Cryptographic Algorithm (C#) Implementation:

  • You chose the AES (Advanced Encryption Standard) algorithm to encrypt sensitive user data, such as payment information and passwords.
  • AES is a symmetric encryption algorithm using the same key for both encryption and decryption.
  • In C#, classes like AesCryptoServiceProvider or AesManaged from the System.Security.Cryptography namespace were used to implement encryption and decryption.
  • Key management was critical, ensuring keys were stored securely, likely in Azure Key Vault or AWS KMS.
  • The encryption process likely involved AES in CBC (Cipher Block Chaining) mode and HMAC for message integrity.

2. Cross-Platform Purchase Tracking:​

The payment system needed to work across multiple platforms (mobile and desktop), likely via an API-driven solution.

  • REST API: A RESTful API was developed for mobile and desktop clients to send purchase data to a centralized server.
  • Authentication: OAuth 2.0 or token-based systems like JWT were used to authenticate users making purchases.
  • API endpoints:
    • POST /api/purchase: Logs a new purchase and stores it securely in the database.
    • GET /api/purchases/{userId}: Retrieves a specific user's purchase history.
  • Cross-platform libraries: Xamarin or .NET MAUI may have been used for shared code across platforms.
  • In-app purchases: Integration with Google Play Billing or Apple's In-App Purchase system, ensuring seamless data syncing with the payment system.

3. Database Integration:​

The payment system integrated with a backend database to store purchase information, user details, and payment histories.

  • Relational databases such as Microsoft SQL Server or PostgreSQL were likely used.
  • Key tables:
    • Users: Stored user details, encrypted passwords, and security tokens.
    • Purchases: Logged transaction details like IDs, timestamps, and user IDs.
    • Payments: Captured payment method, amount, and status.
  • Encryption at rest: Sensitive data was encrypted to comply with standards like PCI DSS.
  • Backup and Recovery: Configured for automatic backups using SQL Server Always On or PostgreSQL replication.

4. Account Protection (Security Measures):​

To prevent account sharing and breaches:

  • Two-factor authentication (2FA) was implemented for login security.
  • Session tracking monitored login locations or device information to prevent multiple logins from different devices.
  • Password hashing: Secure algorithms like SHA-256 or bcrypt, combined with salt, protected against dictionary attacks.

5. Testing and Optimization:​

Extensive testing was necessary due to the complexity of the encryption system.

  • Unit testing ensured data was correctly encrypted and decrypted across platforms.
  • Load testing ensured high performance under heavy transaction volumes.
  • Edge case handling ensured stability during network failures or incomplete transactions.

6. Real-Time Payment Processing:​

The system ensured consistency and real-time access to purchased items.

  • Integration with payment gateways like Stripe, PayPal, or Adyen handled payment processing.
  • Webhooks provided real-time updates for successful or failed transactions, updating the database accordingly.

Challenges and Technical Insights:​

  • Cryptography: First-time experience with AES encryption, requiring careful key management and secure implementation.
  • Cross-platform development: Ensured consistent data processing across mobile and desktop platforms.
  • Security best practices: Implemented encryption, hashing, and secure authentication to prevent breaches.

Result and Impact:​

  • The system processed over $1 million in sales and remained operational for years without major issues.
  • Despite delays in the game product itself, the payment system was completed on time and reliably integrated.

Ковид и доставка 2020​

1. Technology Stack:​

Frontend: The delivery website was built using React.js for a responsive, cross-platform user interface, optimized for both mobile and desktop use. React allowed rapid development of interactive features like real-time updates and menu interactions.

Backend: The backend was built with Node.js and Express.js, chosen for its fast development cycle and ability to handle multiple concurrent requests, crucial for high demand during peak hours.

Database: MySQL was used for storing essential data such as customer information, orders, restaurant menus, and transactions, chosen for its reliability and structured data management.

2. Menu Integration:​

Daily Menu Updates: An API was developed to allow restaurant managers to update the daily menu in real-time, ensuring accurate display on the site.

Local Caching for Speed: Redis was used for local caching on the server, storing frequently accessed data, like menu items, in memory for quick retrieval, enhancing performance during high-traffic periods.

3. Real-Time Order Management:​

Order Tracking: Implemented using WebSockets, providing real-time communication between the kitchen and delivery website, allowing the kitchen to update order statuses instantly for customers.

Payment System: Integrated with Stripe to securely handle payments, complying with PCI DSS standards. Payments were processed on the local server with encrypted data for order validation.

4. Local Server Setup:​

Initial Deployment: Due to pandemic constraints, the system was deployed on a local physical server in the restaurant's office, using Nginx as the web server and PM2 for managing Node.js processes.

Hardware Specifications: The server had 16GB of RAM, a quad-core processor, and 2TB of storage, which was sufficient for initial loads but introduced limitations during peak traffic periods.

5. Scalability and Performance Challenges:​

Limited Hardware Resources: The local server setup imposed strict limits on concurrent users, leading to performance bottlenecks during peak times.

Lack of Redundancy: The local server was a single point of failure, and outages would make the delivery platform inaccessible without failover options.

Manual Scaling: Without auto-scaling, the server had to be monitored manually during peak hours, with services restarted if necessary to free up resources.

6. Security Measures on a Local Server:​

Encryption: SSL/TLS was implemented for encrypted communication between users and the server, protecting customer data and payment information.

Data Protection: Sensitive data was encrypted at rest using AES-256, ensuring security even in the event of server compromise.

Firewall Configuration: A local firewall restricted access to necessary ports (HTTP/HTTPS for web traffic and SSH for secure server access), adding a layer of security.

7. Lack of Testing Environment:​

No Staging Environment: Without a staging environment, code changes were deployed directly to production, increasing the risk of bugs or downtime. Detailed logs were monitored in real-time using tools like Graylog.

On-the-Fly Bug Fixing: Issues were addressed immediately in production, with automated backups and cron jobs ensuring regular database backups to external storage.

8. Real-Time Monitoring and Maintenance:​

Manual Monitoring: Open-source tools like Nagios were used to monitor server health (CPU, memory, disk I/O). Notifications were sent via email or SMS if thresholds were exceeded, allowing quick responses.

Manual Scaling: Without cloud auto-scaling, regular load checks during peak times were necessary, with manual restarts performed to maintain uptime.

9. Local Backup and Redundancy:​

Local Backups: External hard drives connected to the server stored nightly backups of the MySQL database and critical files, essential for disaster recovery.

Disaster Recovery Plan: A weekly server image was created for quick system restoration in the event of hardware failure.

10. Results:​

Order Processing Success: The system handled around 100 orders per day, resulting in 30% of the restaurant's total orders processed through the in-house delivery platform within the first three months.

Cost Savings: By moving away from third-party platforms, the restaurant saved over 25% on delivery costs.

Improved Stability Over Time: Regular server maintenance and optimization allowed the system to remain stable during peak hours after the first few weeks.

Summary of Technical Details (Local Server Setup):​

Frontend: React.js for UI, caching with Redis on the local server for faster menu loading.

Backend: Node.js/Express.js, real-time updates with WebSockets for order management.

Database: MySQL on the local server, with regular backups to external drives.

Hosting: Local server with Nginx as the web server, PM2 for managing Node.js processes.

Scalability Challenges: Limited hardware, no auto-scaling, manual monitoring, and system maintenance during peak traffic times.

Security: SSL/TLS for encrypted communication, AES-256 for data at rest, local firewall protection.

No Cloud: All hosting, storage, and backups were handled on-premises, with no cloud services involved.

Manual Backups: Nightly backups to external storage devices and a disaster recovery plan with weekly server images.

This local-server-based solution helped the restaurant adapt to COVID-19 challenges, providing a cost-effective, in-house delivery system to sustain the business.

Яндекс сегменты для видео 2019​

1. Problem Statement:​

YouTube introduced a feature enabling advertisers to create sequential video scenarios based on user engagement (e.g., percentage of video watched). At the time, Yandex, which held a dominant position in the Russian market, lacked such a feature. The goal was to replicate YouTube’s functionality within Yandex's platform by creating dynamic video ad scenarios tied to specific user behavior.

2. Technology Stack:​

  • Frontend: React.js was used to build a responsive and user-friendly interface, allowing advertisers to create and monitor video ad scenarios easily. The dynamic nature of React helped in efficiently updating ad scenario states based on user behavior and video engagement metrics.

  • Backend: The backend was powered by Node.js and Express.js to handle multiple concurrent requests, such as processing video views, creating cohorts, and linking them to Yandex advertising campaigns. The non-blocking architecture of Node.js made it an ideal choice for real-time processing.

  • Database: Amazon DynamoDB was used for storing video engagement data, such as unique view counts and engagement percentages. The highly available and scalable nature of DynamoDB ensured smooth processing of vast amounts of data as campaigns grew in size and complexity.

3. Video Cohort Segmentation:​

  • Data Collection: Each video had its own unique ID in the system. Once a video collected 1,000 unique views and had been running for at least two weeks, a cohort was created. This ensured that the video had sufficient reach and engagement data to create meaningful segments.

  • Segmentation: The cohorts were divided based on the percentage of the video that was watched. For example:

    • 0–25% watched: Low-engagement viewers.
    • 25–50% watched: Moderate-engagement viewers.
    • 50–75% watched: High-engagement viewers.
    • 75–100% watched: Fully engaged viewers.

    These segments were key for building custom ad scenarios. Advertisers could create tailored follow-up ads or messages for each segment, making the ad campaign more personalized and effective.

4. Integration with Yandex Segments:​

Once the cohort for a video reached the required thresholds (1,000 views and 2 weeks of data), it was automatically synchronized with Yandex Segments through Yandex's audience management APIs.

  • Creating Segments in Yandex: The backend system interfaced with the Yandex Audience API to create custom audience segments based on the cohort data. Each cohort (e.g., users who watched 50% of the video) was transformed into a Yandex Segment.

  • Campaign Linkage: After the segments were created in Yandex, they were automatically linked to the advertising campaigns running on Yandex.Direct. This allowed advertisers to target users based on their interaction with the video and serve follow-up ads according to the predefined scenario.

  • Scenario Binding: For each segment, the system allowed advertisers to bind specific videos or ad creatives, defining the next steps in the user journey. For example, users who watched 75% of the video might see a different follow-up ad than those who watched only 25%.

5. Scenario Execution:​

  • Real-Time Triggering: AWS Lambda was used to handle real-time cohort segmentation and scenario execution. As soon as a user completed a certain engagement threshold (e.g., 50% video watched), a trigger was sent to Yandex Audience, adding the user to the corresponding segment.

  • Yandex Ad Campaign Integration: These Yandex Segments were automatically tied to the ongoing Yandex.Direct campaigns. This ensured that users would see the next video or ad in the sequence based on how much of the previous video they had watched, allowing advertisers to guide users through a carefully curated ad journey.

6. Campaign Test:​

Test Case: The system was tested with a campaign for selling New Year corporate event tickets, which is a significant holiday in Russia. The video ads promoted tickets priced at $5,000 each.

  • Cohort Segmentation Success: The video campaign ran for two weeks, gathering over 1,000 unique views. Cohorts were successfully created and segmented based on the percentage of video watched.

  • Scenario Execution: Ads were personalized for each segment, with high-engagement users receiving follow-up offers and low-engagement users receiving more introductory material.

Results:

  • All tickets were sold out by December 1st, well ahead of the event, highlighting the effectiveness of the video segmentation and personalized ad scenarios.

7. Scalability and Optimization:​

  • Data Caching: Redis was used for caching cohort-related data, which improved performance and reduced query load on the database during high-traffic periods, especially during key points in the ad campaign.

  • Data Storage: Raw video view logs were stored in Amazon S3, while DynamoDB was used for quick access to cohort segmentation and real-time user engagement data. This hybrid storage approach ensured both cost efficiency and high performance as the number of video views increased.

8. Focus on Yandex for the Russian Market:​

Given Yandex’s dominance in the Russian market, the system was designed specifically for Yandex Audience and Yandex.Direct integration. This ensured that advertisers targeting the Russian demographic could fully leverage the new video engagement features, similar to those offered by YouTube, but optimized for Yandex's advertising ecosystem.

Summary of Technical Details:​

  • Frontend: React.js for managing video scenario creation and segment visualization.
  • Backend: Node.js and Express.js for handling video views, segment creation, and Yandex API integration.
  • Database: Amazon DynamoDB for storing engagement data and cohort segmentation, Redis for caching.
  • Cloud Infrastructure: AWS Lambda for real-time processing and scenario execution, Amazon S3 for storing raw view logs.
  • Yandex Integration: Audience segmentation with Yandex Audience API and campaign linkage with Yandex.Direct.

This system successfully enabled advertisers to create sequential video ad campaigns on Yandex, mirroring YouTube’s functionality while addressing the unique requirements of the Russian market. The successful sale of high-value event tickets highlighted the effectiveness of this personalized approach to video advertising.

Как делали АБ тесты 2018​

1. Context:​

The A/B testing system was specifically designed for the Moscow market as part of localized campaigns. The focus was on optimizing website conversions for local businesses, ensuring that each test was relevant to Moscow users. This involved tailoring the system to the specific user behavior patterns and preferences of the Moscow audience, including using local infrastructure and analytics platforms.

2. Technology Stack for A/B Testing:​

  • Frontend:

    • React.js was used to manage the creation and setup of A/B tests for local campaigns. It allowed marketers to easily define and launch tests, such as changing headlines, colors, or page layouts, based on user insights specific to Moscow.
  • Backend:

    • Node.js and Express.js were utilized to control traffic allocation and variant delivery for different segments. Traffic was dynamically routed to various test versions based on cookie/session data, ensuring each user consistently saw the same variant throughout their interactions.
  • Static Page Delivery:

    • Local Hosting (Moscow): To optimize for speed and performance in the Moscow market, static assets were stored on servers located closer to Moscow. Instead of using global services like AWS, local Russian infrastructure was leveraged:

      • Selectel or Yandex.Cloud was used to host static assets for A/B test variations (HTML, CSS, and JS files). This ensured low-latency delivery of content, important for user experience and conversion rates in Moscow.
      • Yandex CDN was utilized for caching and delivering these pages, ensuring fast load times within the Moscow region.
    • Content Variants: Each test variant (A, B, C, etc.) was pre-uploaded to Yandex.Cloud or Selectel, allowing flexible delivery of different versions based on user assignment.

3. Dynamic Test Delivery and Traffic Segmentation:​

  • Traffic Split:
    • For traffic allocation between test variants, Google Optimize or Yandex VPR (Visual Page Rendering) was used. These platforms supported dynamic user segmentation and ensured that Moscow-based users were evenly distributed across test versions.

    • Local Session Management: Cookies and session data were handled locally, ensuring compliance with Russian data protection regulations. Once a user was assigned to a variant (e.g., Version A), they consistently saw the same variant throughout their visits.

4. Integration with Analytics Platforms:​

  • Google Analytics and Yandex.Metrica were both heavily utilized to track the performance of A/B tests. The tracking focused on conversions specific to Moscow-based users and businesses:

    • Goal Setting: Separate goals were defined for each variant using Google Analytics and Yandex.Metrica. These goals included tracking key conversion actions, such as:

      • Clicks on contact buttons.
      • Form submissions for local services.
      • Purchases or lead generation actions on variant pages.

      Each platform allowed setting goals for specific test variants, allowing us to track performance based on how Moscow users interacted with different elements.

    • User Behavior Insights: Yandex.Metrica was particularly valuable for understanding the behavior of Moscow users, as it provided heatmaps, session replays, and form analytics tailored to the Russian market. This allowed us to make data-driven decisions when adjusting A/B test variations.

5. Predictive System for Test Duration and Feasibility:​

  • Prediction System:
    • The backend utilized the average CPC (Cost-Per-Click) for Moscow-based campaigns, sourced from Yandex.Direct. By inputting the client’s test budget, expected traffic volume, and conversion goals, the system could predict how long the test would need to run in order to gather statistically significant results.

    • Recommendation Engine: If a client’s budget or traffic expectations were insufficient for the Moscow market, the system suggested one of the following:

      1. Increase the budget: If the client could afford to expand the test.
      2. Reject the test: If no feasible adjustments could yield useful results based on traffic in Moscow.

6. Localized Campaign Test Flow:​

  1. Test Configuration:

    • The client entered their budget (e.g., 300,000 rubles) and selected Moscow as the target region.
    • CPC data from Yandex.Direct was pulled dynamically to estimate the required traffic.
    • The conversion goal was defined (e.g., signups for a Moscow-based event or purchases).
  2. Prediction:

    • Based on the input, the system calculated the expected duration and traffic volume needed for a statistically valid test.
    • If feasible, the system greenlit the test and assigned users to one of the test variants.
  3. Test Execution:

    • Users in Moscow were split between Variant A, Variant B, etc., using Yandex.Metrica to monitor user behavior and track conversions.
  4. Result Aggregation:

    • Once the test ended, results were aggregated in a dashboard, displaying key performance metrics such as conversion rate changes, bounce rates, and overall traffic distribution between variants.

7. Challenges and Results:​

  • Local Market Focus: Since the tests targeted only Moscow users, special attention was given to localized behaviors and preferences. For example, we noticed that certain types of visual elements or call-to-action messages worked better in Moscow than in other regions.

  • Outcome Tracking:

    • Some tests resulted in no major improvement in conversion rates, while others led to significant increases—anywhere from 5% to 50% in specific campaigns, such as event signups or lead generation for local services.

    • The system allowed clients to monitor the planned vs. actual performance in real-time, helping them adjust campaigns if needed.

8. Scalability and Monitoring:​

  • Real-Time Alerts: Using Yandex.Metrica’s API, we set up real-time alerts to notify the marketing team if a test variant performed significantly worse than expected (e.g., low traffic or high bounce rates).

  • Data Caching and Scalability: Redis was used to cache frequently accessed data, such as test traffic counts and variant assignment data. This ensured that even with increased traffic during peak periods (e.g., local events in Moscow), the system remained performant.

Summary of Technical Details:​

  • Frontend: React.js for managing A/B test setups and result tracking.
  • Backend: Node.js and Express.js for dynamic test delivery and traffic allocation.
  • Static Page Hosting: Yandex.Cloud or Selectel for storing and delivering static variant pages.
  • Traffic Segmentation: Google Optimize and Yandex VPR for traffic allocation and dynamic variant serving.
  • Analytics: Google Analytics and Yandex.Metrica for tracking user behavior and conversions.
  • CDN: Yandex CDN for fast delivery of static pages in Moscow.
  • Prediction Engine: Budget and traffic forecasting based on Moscow-specific CPC data from Yandex.Direct.

This localized A/B testing system ensured campaigns were tailored specifically to Moscow’s user base, using local infrastructure for fast content delivery and deep user behavior analysis through Yandex.Metrica. The system was optimized for predicting test outcomes and efficiently handling variant traffic, delivering measurable results in Moscow’s competitive market.

Овер инжиниринг Detailed Application of the Multiton Singleton Pattern (2017) – C# Version​

1. Context:​

In 2017, while working on a small internal project in Russia, I was tasked with parsing competitor prices from different websites to help local businesses in Moscow compare prices. I wanted to use my knowledge of design patterns and applied the Multiton Singleton pattern to manage the different parsing tasks. The goal was to ensure efficient resource management by reusing parser instances for each website, preventing redundant object creation.

2. Technology Stack:​

  • Frontend:

    • The frontend was written using HTML/CSS and JavaScript (jQuery). This enabled users to input competitor website URLs and view the parsed price data dynamically. AJAX was used to send requests to the backend.
  • Backend:

    • The backend logic was implemented in C# using ASP.NET. This allowed for a robust and scalable server-side application. I used the Multiton Singleton pattern in C# to manage parser instances for each competitor website.

3. Applying the Multiton Singleton Pattern in C#:​

The Multiton Singleton pattern ensures that only one instance of a class exists for each unique key, such as a website domain. In this project, I applied the pattern to ensure that each website parser only had one active instance, minimizing overhead while allowing multiple websites to be parsed simultaneously.

4. Code Example in C#:​

using System;
using System.Collections.Generic;

public class ParserFactory
{
// Dictionary to store instances of parsers
private static Dictionary<string, Parser> _instances = new Dictionary<string, Parser>();

// Method to get the parser instance based on website ID
public static Parser GetParser(string websiteId)
{
// Check if the parser for the given website already exists
if (!_instances.ContainsKey(websiteId))
{
// Create a new parser instance if it doesn't exist
_instances[websiteId] = new Parser(websiteId);
}

// Return the existing or newly created parser instance
return _instances[websiteId];
}
}

public class Parser
{
private string _websiteId;

// Constructor
public Parser(string websiteId)
{
_websiteId = websiteId;
}

// Method to parse the website for price data
public void ParsePrices()
{
Console.WriteLine($"Parsing prices for {_websiteId}...");
// Here we would use an HTTP client to fetch the data and parse HTML
// For example, using HttpClient to get HTML and HTML Agility Pack to parse
}
}

// Usage example
class Program
{
static void Main(string[] args)
{
// Get a parser for a website
var parser1 = ParserFactory.GetParser("competitor1.com");
parser1.ParsePrices();

// Get another parser for the same website (reuses the instance)
var parser2 = ParserFactory.GetParser("competitor1.com");
parser2.ParsePrices();

// Get a parser for a different website (creates a new instance)
var parser3 = ParserFactory.GetParser("competitor2.com");
parser3.ParsePrices();
}
}

5. Explanation of the Code:​

  • Multiton Pattern:

    • The ParserFactory class manages instances of parsers. It stores them in a static Dictionary<string, Parser>, where the key is the website ID (e.g., competitor1.com), and the value is the Parser instance.

    • When GetParser is called, it checks if a parser for the given website already exists in the dictionary. If not, a new parser is created, ensuring that only one instance exists for each website.

  • Parser Class:

    • The Parser class contains the logic for parsing price data from a given website. In a real-world scenario, it would use HTTP requests (e.g., via HttpClient) to fetch HTML data and parse it using libraries like Html Agility Pack.

6. Web Scraping Logic (Real-World Scenario):​

In a production environment, the Parser class would use HttpClient to fetch the web page and a library like Html Agility Pack to parse the HTML. Here’s a simplified version of how that might look in C#:

using HtmlAgilityPack;
using System.Net.Http;
using System.Threading.Tasks;

public class Parser
{
private string _websiteId;

public Parser(string websiteId)
{
_websiteId = websiteId;
}

public async Task ParsePricesAsync()
{
using (HttpClient client = new HttpClient())
{
var response = await client.GetStringAsync($"https://{_websiteId}");
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(response);

// Extract price data (example of finding a price element by class)
var priceNodes = doc.DocumentNode.SelectNodes("//span[@class='price']");
foreach (var node in priceNodes)
{
Console.WriteLine($"Price found: {node.InnerText}");
}
}
}
}
  • Html Agility Pack is used to parse the HTML response and extract specific elements like price information. In this case, it looks for span elements with a class of price and logs the extracted price to the console.

7. Results and Learning:​

  • Over-Engineering:

    • While the Multiton Singleton pattern worked as intended, the solution added unnecessary complexity. The pattern was useful for ensuring that each website had only one active parser, but the problem could have been solved more easily without the need for a complex design pattern.

    • My colleagues pointed out that for such a straightforward task, a simpler approach would have been more maintainable and easier to debug.

  • Lesson Learned:

    • This experience taught me the value of pragmatism in software development. Just because a design pattern can be applied doesn't mean it should be. In cases where simplicity is sufficient, over-engineering can lead to maintenance headaches and unnecessary complexity.

Summary of Technical Details:​

  • Frontend: jQuery with HTML/CSS for managing user inputs and AJAX calls to initiate the price parsing process.
  • Backend: C# (ASP.NET) for handling parsing logic, including the implementation of the Multiton Singleton pattern.
  • Multiton Singleton: Used in C# to manage multiple parser instances, ensuring only one instance per website during execution.
  • Web Scraping: cURL equivalent in C# (HttpClient) for fetching HTML, and Html Agility Pack for parsing the HTML content from competitor websites.

By applying the Multiton Singleton pattern in C#, I learned the importance of choosing the right level of abstraction for the task. While the implementation was correct, the complexity was unnecessary for a small-scale project. This experience underscored the need for practical, maintainable solutions tailored to the problem at hand.

Платформа для обучения sfh 2019​

1. Context:​

In 2019, while working at SFH Digital Marketing Agency, I realized that the certifications from Yandex, Google, and Meta that our marketing specialists were obtaining were important but not fully tailored to our clients' needs. After discussing with my stakeholders, it became clear that our team needed a customized training platform that would help clients trust our expertise in their specific business sectors. The goal was to ensure that every specialist was deeply knowledgeable in the areas relevant to the clients they served.

I worked closely with managers to define the training segments and structure, visiting popular e-learning platforms to study best practices in knowledge retention, material presentation, and testing systems. The result was an internal training platform tailored for a team of 30 people, offering structured training paths and personalized learning experiences.

2. Technology Stack:​

  • Frontend:

    • The frontend was developed using React.js. This provided a dynamic and interactive user experience, allowing employees to track their learning progress, access materials, and take tests in a smooth and responsive interface.
    • Material-UI was used to provide a clean, professional design with components that supported the learning structure, such as step-by-step progress bars, forms, and modal dialogs for quizzes and tests.
  • Backend:

    • The backend was written in Node.js with Express.js as the framework to manage API requests and serve content dynamically. This allowed for real-time updates on employee progress and supported a scalable architecture for managing multiple users concurrently.
    • MongoDB was used as the database to store user information, training progress, test results, and training materials. MongoDB’s document-based structure was ideal for storing the diverse and unstructured data related to training paths, quizzes, and learning content.

3. Key Features:​

  • Login System:

    • The platform integrated with Google’s OAuth for authentication, requiring employees to log in using their company Google accounts. This ensured that only authorized personnel had access to the platform and allowed the system to automatically link their training progress to their work email.
  • Training Content and Videos:

    • All video content was hosted on YouTube in unlisted mode, meaning that videos were only accessible through the platform, maintaining a level of control over the training material while leveraging YouTube’s powerful streaming infrastructure.
    • The platform dynamically embedded the videos using the YouTube API, giving users easy access to training content directly from the platform without needing to navigate away.
  • Learning Paths and Progress Tracking:

    • The platform featured a structured learning path system. Each employee had a clearly defined training path, with modules and segments that needed to be completed to progress.
    • A progress tracker was built in React using state management (via Redux), allowing employees to easily see what training they had completed and what was left.
    • Notifications were triggered when milestones were achieved, ensuring employees stayed motivated and aware of their progress.
  • Quizzes and Testing:

    • Each module included interactive quizzes to test employees’ understanding. I used React Quiz Component to create these quizzes, with support for multiple-choice, true/false, and fill-in-the-blank questions.
    • The results of these quizzes were stored in MongoDB and dynamically displayed on each employee’s dashboard, allowing them and their managers to track performance and identify areas where further improvement was needed.

4. Backend and Frontend Interaction:​

  • APIs:

    • The backend used RESTful APIs to manage requests between the frontend and MongoDB database. APIs were responsible for:
      • Fetching training content and progress data for logged-in users.
      • Storing quiz results and updating progress.
      • Authenticating users through Google OAuth and managing user sessions.
    • JWT (JSON Web Tokens) were used for secure session management, ensuring users remained logged in across their sessions without compromising security.
  • Video Integration:

    • The videos were embedded using the YouTube IFrame API. The frontend handled this dynamically, ensuring videos were only available to logged-in users with the correct permissions.
    • Each video module was tied to specific segments of the learning path, and upon completion, an event was triggered to update the user’s progress in the MongoDB database.

5. Storage and Access Control:​

  • Database:

    • MongoDB served as the database for storing employee profiles, training progress, quiz results, and learning path structures. Its flexible schema allowed us to manage the evolving training content and employee-specific progress data easily.
    • Documents in MongoDB stored information such as:
      • Employee data (name, email, role, completed modules, quiz scores).
      • Learning paths (segment names, descriptions, associated quizzes, and required content).
      • Quiz data (questions, correct answers, user responses).
  • Google OAuth:

    • Google OAuth 2.0 was used to authenticate employees through their company email addresses. This ensured that only employees with authorized Google Workspace emails could access the platform, securing the system from unauthorized access.

6. Scalability and Future Expansion:​

  • The platform was designed with scalability in mind. Using Node.js and MongoDB, it could easily handle the growth of new employees or additional training materials without any significant architectural changes.
  • Docker was used for containerization to simplify deployment, ensuring that the platform could be easily deployed or migrated across servers without configuration issues.
  • AWS or DigitalOcean was considered for cloud hosting, ensuring high availability and reliability. The platform could easily scale to accommodate more employees as the agency grew.

7. Results:​

  • Clear Learning Paths: Employees now had a clear understanding of their training goals and what they needed to do to progress. The platform provided them with an easy-to-follow roadmap, ensuring they were always on track with their development.

  • Increased Client Confidence: By using the platform, our marketing specialists were able to focus on specific industry segments, giving clients confidence that they were working with specialists who truly understood their sector.

  • Efficient Onboarding: New hires had a structured learning path that allowed them to quickly get up to speed on the tools, platforms, and strategies the agency used. This streamlined the onboarding process and ensured consistency across the team.

Summary of Technical Details:​

  • Frontend: React.js with Material-UI for a responsive and interactive user interface.
  • Backend: Node.js with Express.js for API management and data handling.
  • Database: MongoDB for flexible, document-based data storage of user profiles, progress, and training content.
  • Authentication: Google OAuth for secure, work-based login.
  • Video Hosting: YouTube unlisted videos embedded via the YouTube API.
  • Quizzes and Testing: React Quiz Component for creating interactive quizzes, with results stored and tracked in MongoDB.

This platform helped our marketing specialists stay on top of their learning, improved client confidence by specializing knowledge, and allowed for easy scalability and adaptation for future growth.

Турандот и новые клиенты 2019​

1. Frontend Implementation:​

  • How: The frontend was developed using HTML5, CSS3, and JavaScript (jQuery). The webpage was designed to be lightweight and responsive, optimized for mobile devices, as tourists and tour operators typically use smartphones or tablets while on the go.

  • Why:

    • HTML5 and CSS3 were chosen for their simplicity and broad compatibility across devices. This ensured that the page could be accessed by users regardless of their device (smartphone, tablet, or desktop).
    • jQuery was used for enhancing user interactions (e.g., form submissions, smooth scrolling) without over-complicating the codebase. It was a well-established and lightweight solution, fitting the project's limited scope.

2. Localization and Language Support:​

  • How: The webpage was designed with support for simplified Chinese, making it easier for Chinese tour companies and tourists to understand the offerings. The content was either translated manually by a native speaker or through a professional translation service to ensure accuracy.

  • Why:

    • Providing localized content was crucial because it catered directly to Chinese tourists. Simplified Chinese ensured that the information was accessible to a broad audience from mainland China, which was the primary target group.
    • Offering the page in the local language increased trust and usability, encouraging more bookings and inquiries from tour companies.

3. Backend Implementation:​

  • How: Since the restaurant found an external contractor to host the website, the backend was handled on their existing infrastructure. The contractor likely used a PHP or Node.js backend with MySQL or MongoDB as the database to manage bookings and inquiries from tour companies. The system also managed inquiries or bookings from the website.

  • Why:

    • Using an existing backend infrastructure made sense from a cost and time perspective. The restaurant already had a hosting provider and was familiar with their system. This allowed for a faster deployment without the need to develop and host a custom backend from scratch.
    • PHP or Node.js are both commonly used for small-to-medium-scale projects. Either would be sufficient to handle the expected traffic and interactions, such as form submissions or inquiries from tour companies.

4. Video and Image Content:​

  • How: The webpage likely included high-quality images and videos of the restaurant, showcasing its offerings, ambience, and appeal to tourists. These media files were either self-hosted on the restaurant's hosting platform or linked to YouTube or Vimeo for video content.

  • Why:

    • Including rich media (images and videos) enhances the user experience and helps promote the restaurant to a new audience. Tour companies rely heavily on visual content when deciding where to take their clients.
    • By hosting the videos on YouTube or Vimeo, the restaurant avoided additional server costs associated with hosting large files. These platforms also ensure fast and reliable video delivery.

5. Form for Tour Companies:​

  • How: A simple contact form was included for tour companies to inquire about group bookings or special deals. The form likely captured essential information like the company’s name, contact information, group size, and preferred visit dates.

  • Why:

    • Including a contact form specifically for tour companies streamlined the inquiry process and made it easier for the restaurant to manage incoming requests.
    • A simple form reduces friction for users, making it more likely that they will complete the process and submit inquiries, helping the restaurant capture new leads.

6. Analytics and Tracking:​

  • How: The website was integrated with Google Analytics and potentially Yandex.Metrica (given the Russian market) to track user interactions, page views, and conversion rates. This allowed the restaurant to monitor how effective the webpage was at attracting tourist groups.

  • Why:

    • Tracking user behavior was critical to understanding the success of the campaign. Using tools like Google Analytics provided insights into visitor numbers, the effectiveness of the Chinese-language content, and whether tourists or tour companies were completing the contact form.
    • These insights could inform future marketing efforts and website improvements, ensuring continued growth in the tourist segment.

7. Hosting and Infrastructure:​

  • How: The webpage was hosted on the restaurant's existing platform, managed by their contractor. This involved setting up a subdomain (e.g., china-restaurant.example.com) or a dedicated section within their primary website.

  • Why:

    • Using the restaurant's existing hosting service minimized setup time and costs. It also ensured that the page was integrated with the restaurant’s existing infrastructure, making it easier for the restaurant to manage content updates and inquiries.
    • The existing contractor was familiar with the platform, making the development and deployment process smoother.

8. Result and Success:​

  • How: Over the course of a year, the webpage attracted a significant number of inquiries from Chinese tour companies. This resulted in a new customer segment — tourist groups — accounting for 20% of all restaurant visitors.

  • Why:

    • By creating a simple, targeted webpage in Chinese, the restaurant was able to attract and convert a previously untapped market segment. The tourist influx from China grew, driven by direct outreach to Chinese tour companies who could now easily access information and make group bookings.

Summary of Implementation and Rationale:​

  1. Frontend:

    • How: Built using HTML5, CSS3, and jQuery to provide a lightweight, mobile-friendly experience.
    • Why: These technologies ensured compatibility across devices and made the development fast and cost-effective.
  2. Backend:

    • How: Handled by an external contractor on the restaurant’s existing infrastructure (likely PHP or Node.js with MySQL or MongoDB).
    • Why: Leveraging existing hosting and systems reduced time to launch and saved costs on infrastructure development.
  3. Localization:

    • How: The webpage content was translated into simplified Chinese.
    • Why: Offering content in the language of the target audience (Chinese tourists) increased accessibility and trust.
  4. Video and Images:

    • How: High-quality media was included to attract tourists, with videos likely hosted on YouTube or Vimeo.
    • Why: Visual content helped convey the restaurant's appeal and using third-party hosting minimized infrastructure costs.
  5. Form for Tour Companies:

    • How: A simple contact form allowed tour companies to submit inquiries about group bookings.
    • Why: A streamlined form encouraged more inquiries, generating leads for the restaurant from a previously untapped market.
  6. Analytics:

    • How: Google Analytics and possibly Yandex.Metrica were used to track visitor behavior and conversions.
    • Why: These analytics tools provided valuable insights into the webpage’s performance and the success of the tourist campaign.
  7. Hosting:

    • How: Hosted on the restaurant’s existing platform.
    • Why: This approach minimized the need for new infrastructure, reducing costs and simplifying maintenance.

Хобби в играх ранний 2022​

1. Frontend (User Interface) Implementation:​

  • How: The inventory system’s UI was implemented using Unity’s UI Toolkit, which includes Canvas, Event System, and RectTransforms to manage the layout and behavior of UI elements. I created a grid-like structure for the inventory, with each slot represented by a UI Button or Image component.

  • Why:

    • Canvas was used as the root container for all UI elements because it ensures proper scaling across different screen resolutions.
    • RectTransforms provided precise control over the placement and size of inventory slots, allowing items to snap into place correctly.
    • Unity’s built-in Event System was chosen to handle user interactions like dragging and dropping, as it simplifies the process of detecting mouse events.

2. Backend (Drag-and-Drop Logic):​

  • How: The drag-and-drop functionality was implemented using C# scripts in combination with Unity’s Event Triggers. These triggers captured the OnBeginDrag, OnDrag, and OnEndDrag events, which allowed me to control the movement of inventory items.

    • I created a base DraggableItem class that handled the drag behavior for each inventory item. This class tracked the initial position of the item and its target slot.
    • The snapping logic was managed by calculating the closest inventory slot using the RectTransform Utility and ensuring that the item snapped into the nearest available slot when dropped.
  • Why:

    • Using Unity’s Event Trigger system allowed me to easily hook into drag-and-drop events without needing to build the functionality from scratch. This reduced complexity and ensured the system adhered to Unity’s standard UI practices.
    • The use of C# classes and object-oriented principles (like inheritance) ensured that the system was extensible, allowing new item types or behaviors to be added later.

3. Item Management:​

  • How: I created a ScriptableObject class in Unity to define different item types (e.g., weapons, armor, potions). Each inventory slot could dynamically hold any item, and the system handled the appearance and behavior of items based on their type.

  • Why:

    • ScriptableObjects are a powerful tool in Unity for managing game data. They allowed me to decouple item data from the rest of the system, making it easier to manage different item types and properties. This also made the system more flexible and scalable for future updates or expansions.

4. Snapping and Item Placement:​

  • How: I used colliders on the inventory slots to detect when an item was dropped in a valid location. Once dropped, the RectTransform of the item was adjusted to match the position of the closest inventory slot, ensuring the item snapped perfectly into place.

  • Why:

    • Colliders were a straightforward way to manage slot detection, leveraging Unity’s physics system to detect whether the item was being dragged into a valid slot. This reduced the need for manual coordinate calculations and ensured that items snapped accurately, improving user experience.

5. Testing and Debugging:​

  • How: I built multiple prototypes to test different approaches for drag-and-drop mechanics. I tested using different event handling methods (manual scripting vs. Unity’s Event Triggers) and snapping techniques (manual coordinate snapping vs. using Unity’s built-in utilities). Each iteration was tested for performance and ease of use.

  • Why:

    • Prototyping and testing were crucial for finding the most efficient and intuitive method to implement the system. Experimenting with both Unity’s built-in features and custom-coded solutions allowed me to find the optimal balance between simplicity and functionality.

6. Learning from Resources:​

  • How: I spent considerable time researching forums, tutorials, and open-source repositories on GitHub to learn how other developers approached drag-and-drop mechanics in Unity. I also studied games with similar systems, such as Diablo 2, to understand how professional games handle item interactions.

  • Why:

    • Researching other developers’ approaches saved time and helped me avoid common pitfalls. By learning from others’ solutions, I was able to implement a drag-and-drop system that was not only functional but optimized for performance and future flexibility.

Summary of Implementation and Rationale:​

  1. Frontend (UI Design):

    • How: Built using Unity’s UI Toolkit (Canvas, RectTransforms, Event System).
    • Why: These tools provided robust and scalable UI management, ensuring the inventory system was responsive and intuitive.
  2. Backend (Drag-and-Drop Logic):

    • How: Implemented using C# with Unity’s Event Triggers to manage drag-and-drop behavior.
    • Why: Event Triggers simplified the management of drag-and-drop events and allowed for more organized and reusable code.
  3. Item Management:

    • How: Defined item types using ScriptableObjects, making the system flexible for different item behaviors.
    • Why: ScriptableObjects separated data from functionality, improving scalability and allowing for easy item management and future updates.
  4. Snapping and Placement:

    • How: Used colliders for detecting valid slot placement and snapped items using RectTransform adjustments.
    • Why: Colliders provided an efficient and reliable way to detect slot positions, ensuring smooth and precise item placement.
  5. Testing and Iteration:

    • How: Developed multiple prototypes and tested various drag-and-drop and snapping methods.
    • Why: Prototyping ensured that I found the most efficient and user-friendly solution, reducing complexity while maintaining functionality.

By leveraging Unity’s built-in systems alongside custom C# logic, I successfully implemented a drag-and-drop inventory system that felt intuitive and responsive, significantly enhancing the gameplay experience in my 2D game. This project not only solved the immediate problem of managing inventory items but also deepened my understanding of Unity’s UI and event handling systems.

GraphQL сам и потом в продакшен​

Клиентская часть: Apollo Client​

На клиенте используется Apollo Client для отправки запросов на сервер. Пример запроса для получения данных о базе данных книг:

import { gql, useQuery } from '@apollo/client';

const GET_BOOK_DATABASE = gql`
query GetBookDatabase(
$after: String
$before: String
$last: Int
$first: Int
$sort: [BookSortInput!]
$filter: BookFilterInput
) {
books(after: $after, before: $before, last: $last, first: $first, sort: $sort, filter: $filter) {
nodes {
bookId
title
author
isbn
publicationYear
genre
coverImage
rating
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}
`;

const BookDatabaseGrid = ({ variables }) => {
const { data, loading, error } = useQuery(GET_BOOK_DATABASE, {
variables: {
after: variables.after,
before: variables.before,
last: variables.last,
first: variables.first,
sort: variables.sort,
filter: variables.filter,
},
});

if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;

return (
<div>
{/* Работа с данными */}
{data.books.nodes.map((book) => (
<div key={book.bookId}>
<p>{book.title} by {book.author} - {book.genre}</p>
{/* и другие данные */}
</div>
))}
</div>
);
};

Серверная часть: Apollo Server и инструмент для просмотра схем​

На сервере данные обрабатываются через Apollo Server, который взаимодействует с GraphQL-схемой и резолверами. Вместо Banana Cake Pop можно использовать любой другой инструмент для отладки и работы с GraphQL, например, GraphQL Playground.

Пример схемы и резолверов на сервере:

const { ApolloServer, gql } = require('apollo-server');

// Определение схемы GraphQL
const typeDefs = gql`
type Book {
bookId: ID!
title: String!
author: String!
isbn: String
publicationYear: Int
genre: String
coverImage: String
rating: Float
}

type PageInfo {
hasNextPage: Boolean
hasPreviousPage: Boolean
startCursor: String
endCursor: String
}

type BooksConnection {
nodes: [Book!]!
pageInfo: PageInfo!
totalCount: Int!
}

input BookSortInput {
field: String!
direction: String!
}

input BookFilterInput {
genre: String
author: String
}

type Query {
books(after: String, before: String, last: Int, first: Int, sort: [BookSortInput!], filter: BookFilterInput): BooksConnection!
}
`;

// Резолверы для схемы
const resolvers = {
Query: {
books: (_, { after, before, last, first, sort, filter }, context) => {
return context.dataSources.bookAPI.getBooks({ after, before, last, first, sort, filter });
},
},
};

// Запуск сервера Apollo
const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});

Пример получения данных​

Данные поступают от API (или базы данных) через резолверы. Запросы могут фильтровать книги по жанру или автору, а также сортировать их по различным параметрам.

Инструмент для работы со схемой, например, GraphQL Playground, можно использовать для просмотра и отладки схемы и запросов.