v0.5.3
- Мелкие исправления увеличивающие работу конвертера
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
# *СОДЕРЖАНИЕ
|
||||
|
||||
[TOC]
|
||||
|
||||
# *ВВЕДЕНИЕ
|
||||
|
||||
Обслуживание парка оборудования в производственных подразделениях опирается на заявки, которые до сих пор часто передаются по телефону и фиксируются в электронных таблицах. При таком порядке теряется история обращений, а срок реакции зависит от загруженности диспетчера.
|
||||
|
||||
Объектом работы является процесс приёма и исполнения заявок на техническое обслуживание. Предмет работы — архитектура и программная реализация модуля учёта таких заявок.
|
||||
|
||||
Цель работы — спроектировать и реализовать модуль учёта заявок, обеспечивающий регистрацию обращений, контроль сроков исполнения и хранение истории обслуживания.
|
||||
|
||||
Для достижения цели решаются следующие задачи:
|
||||
|
||||
1. Проанализировать процесс обработки заявок и существующие решения для его автоматизации.
|
||||
2. Сформировать требования к модулю и спроектировать его архитектуру и модель данных.
|
||||
3. Реализовать ключевые функции модуля и оценить объём хранилища.
|
||||
|
||||
В работе применяются структурный анализ процессов, объектно-ориентированное моделирование в нотации UML и сравнительный анализ программных решений.
|
||||
|
||||
# 1 Анализ процесса обработки заявок
|
||||
|
||||
## 1.1 Описание процесса и его участников
|
||||
|
||||
В обработке заявки участвуют три роли: инициатор со стороны производственного подразделения, диспетчер службы обслуживания и исполнитель. Инициатор сообщает о неисправности, диспетчер регистрирует обращение и назначает исполнителя, исполнитель выполняет работы и закрывает заявку.
|
||||
|
||||
Границы автоматизируемого процесса и его внешние интерфейсы приведены на @Рисунок:idef_a0.
|
||||
|
||||
%idef_a0 Контекстная диаграмма процесса обслуживания
|
||||
|
||||
```idef0
|
||||
title Обработать заявку на обслуживание
|
||||
node A-0
|
||||
number 1
|
||||
project Модуль учёта заявок
|
||||
context TOP
|
||||
|
||||
[A0] Обработать заявку на обслуживание
|
||||
<- Обращение инициатора
|
||||
^ Регламент технического обслуживания
|
||||
-> Закрытая заявка с отметкой о работах
|
||||
v Служба обслуживания
|
||||
```
|
||||
|
||||
Наблюдение за работой диспетчера в течение недели дало следующие показатели: в среднем 42 обращения в сутки, среднее время регистрации 6 минут, доля обращений с неполными сведениями об оборудовании 18 %. Именно неполнота сведений вызывает повторное обращение к инициатору и удлиняет реакцию на заявку.
|
||||
|
||||
## 1.2 Сравнение существующих решений
|
||||
|
||||
Для автоматизации процесса рассматривались три варианта: универсальная система управления обслуживанием, модуль в составе используемой на предприятии учётной системы и собственная разработка. Критериями сравнения выбраны стоимость владения, возможность интеграции со справочником оборудования и трудоёмкость внедрения [1].
|
||||
|
||||
Результаты сравнения сведены в @Таблица:tab_cmp.
|
||||
|
||||
%tab_cmp Сравнение вариантов автоматизации процесса
|
||||
|
||||
| Вариант | Стоимость владения | Интеграция со справочником | Трудоёмкость внедрения |
|
||||
|---------|--------------------|----------------------------|------------------------|
|
||||
| Универсальная система обслуживания | высокая | через файловый обмен | средняя |
|
||||
| Модуль учётной системы | средняя | штатная | высокая |
|
||||
| Собственная разработка | низкая | по REST | низкая |
|
||||
|
||||
Универсальная система покрывает больше сценариев, чем требуется подразделению, и вносит внешний файловый обмен, который сам становится источником расхождений [2]. Модуль учётной системы обеспечивает штатную интеграцию, но его доработка требует привлечения поставщика. Собственная разработка выбрана как вариант, закрывающий требования при наименьшей трудоёмкости.
|
||||
|
||||
## 1.3 Требования к модулю
|
||||
|
||||
Требования сгруппированы по категориям и приведены в @Таблица:tab_req. Формулировки нефункциональных требований опираются на рекомендации по описанию качества программных систем [3].
|
||||
|
||||
%tab_req Требования к модулю учёта заявок
|
||||
|
||||
| Категория | Требование |
|
||||
|-----------|------------|
|
||||
| Функциональные | регистрация заявки с привязкой к единице оборудования |
|
||||
| ^ | назначение исполнителя и контроль срока |
|
||||
| ^ | хранение истории обслуживания единицы оборудования |
|
||||
| Производительность | обработка 100 заявок в час при 20 одновременных пользователях |
|
||||
| ^ | время отклика интерфейса не более 2 с |
|
||||
| Надёжность | доступность не ниже 99,5 % в рабочие часы |
|
||||
| Интеграция | получение справочника оборудования по REST |
|
||||
|
||||
Ограничения проекта: развёртывание в контуре предприятия, единая аутентификация через корпоративную службу, хранение данных не менее трёх лет.
|
||||
|
||||
# 2 Проектирование модуля
|
||||
|
||||
## 2.1 Архитектура модуля
|
||||
|
||||
Модуль спроектирован по трёхуровневой схеме: клиентское приложение, сервис прикладной логики и хранилище. Такое разделение позволяет обновлять правила обработки заявок без изменения клиента [4].
|
||||
|
||||
Контейнерная структура модуля приведена на @Рисунок:c4_containers.
|
||||
|
||||
%c4_containers Контейнеры модуля учёта заявок +landscape
|
||||
|
||||
```uml-c4
|
||||
Person(dispatcher, "Диспетчер", "Регистрирует и распределяет заявки")
|
||||
Person(worker, "Исполнитель", "Выполняет работы по заявке")
|
||||
System_Boundary(app, "Модуль учёта заявок") {
|
||||
Container(spa, "Веб-клиент", "React", "Интерфейс диспетчера и исполнителя")
|
||||
Container(api, "Сервис заявок", "FastAPI", "Правила обработки и контроль сроков")
|
||||
ContainerDb(db, "Хранилище заявок", "PostgreSQL", "Заявки, работы, история")
|
||||
}
|
||||
System_Ext(equip, "Справочник оборудования", "Учётная система предприятия")
|
||||
System_Ext(sso, "Корпоративная служба входа", "Единая аутентификация")
|
||||
|
||||
Rel(dispatcher, spa, "Регистрирует заявки", "HTTPS")
|
||||
Rel(worker, spa, "Отмечает выполнение", "HTTPS")
|
||||
Rel(spa, api, "Вызывает методы", "REST/JSON")
|
||||
Rel(api, db, "Читает и пишет", "SQL")
|
||||
Rel(api, equip, "Запрашивает единицы оборудования", "REST")
|
||||
Rel(spa, sso, "Аутентифицирует пользователя", "OIDC")
|
||||
```
|
||||
|
||||
Справочник оборудования остаётся во внешней учётной системе: дублирование его в модуле привело бы к расхождению данных при выводе оборудования из эксплуатации.
|
||||
|
||||
## 2.2 Модель данных
|
||||
|
||||
Логическая модель данных охватывает три сущности: заявку, работу по заявке и запись истории обслуживания. Единица оборудования в модуле не хранится, вместо неё сохраняется её идентификатор во внешнем справочнике.
|
||||
|
||||
Модель данных приведена на @Рисунок:erd.
|
||||
|
||||
%erd Логическая модель данных модуля
|
||||
|
||||
```uml
|
||||
@startuml
|
||||
hide circle
|
||||
skinparam linetype ortho
|
||||
|
||||
entity "Заявка" as request {
|
||||
* id : bigint <<PK>>
|
||||
--
|
||||
* equipment_ref : varchar(32)
|
||||
* created_at : timestamp
|
||||
* due_at : timestamp
|
||||
* status : varchar(16)
|
||||
description : text
|
||||
}
|
||||
|
||||
entity "Работа" as work {
|
||||
* id : bigint <<PK>>
|
||||
--
|
||||
* request_id : bigint <<FK>>
|
||||
* performer : varchar(128)
|
||||
* started_at : timestamp
|
||||
finished_at : timestamp
|
||||
}
|
||||
|
||||
entity "Запись истории" as history {
|
||||
* id : bigint <<PK>>
|
||||
--
|
||||
* request_id : bigint <<FK>>
|
||||
* changed_at : timestamp
|
||||
* old_status : varchar(16)
|
||||
* new_status : varchar(16)
|
||||
}
|
||||
|
||||
request ||--o{ work
|
||||
request ||--o{ history
|
||||
@enduml
|
||||
```
|
||||
|
||||
Статус заявки хранится строкой из фиксированного набора значений, а не ссылкой на справочник: набор состояний определяется регламентом обслуживания и меняется вместе с версией модуля.
|
||||
|
||||
## 2.3 Оценка объёма хранилища
|
||||
|
||||
Объём данных за период эксплуатации оценивается произведением числа записей на средний размер записи с учётом коэффициента служебных структур базы данных [5].
|
||||
|
||||
%eq_volume
|
||||
$$
|
||||
V = N \cdot S \cdot k
|
||||
$$
|
||||
|
||||
где $N$ — число заявок за период; $S$ — средний размер записи вместе со связанными работами и историей, байт; $k$ — коэффициент накладных расходов хранилища.
|
||||
|
||||
При 42 заявках в сутки, среднем размере записи 4 килобайта и коэффициенте 1,6 расчёт по (@Формула:eq_volume) даёт около 98 мегабайт данных за три года. Такой объём не требует секционирования таблиц и позволяет держать всю историю в основном хранилище.
|
||||
|
||||
# 3 Реализация ключевых функций
|
||||
|
||||
## 3.1 Контроль срока исполнения
|
||||
|
||||
Срок исполнения заявки вычисляется от момента регистрации по нормативу, заданному для категории оборудования. Заявка считается просроченной, если работы не завершены к расчётному сроку.
|
||||
|
||||
Реализация проверки приведена в @Листинг:code_overdue.
|
||||
|
||||
%code_overdue Проверка просроченных заявок
|
||||
|
||||
```python
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
NORMS_HOURS = {'critical': 4, 'standard': 24, 'planned': 72}
|
||||
|
||||
|
||||
def due_at(created_at: datetime, category: str) -> datetime:
|
||||
return created_at + timedelta(hours=NORMS_HOURS[category])
|
||||
|
||||
|
||||
def is_overdue(request: dict, now: datetime) -> bool:
|
||||
if request['status'] == 'closed':
|
||||
return False
|
||||
return now > due_at(request['created_at'], request['category'])
|
||||
```
|
||||
|
||||
Нормативы вынесены в отдельную структуру: их изменение регламентом не требует правки логики проверки.
|
||||
|
||||
## 3.2 Проверка полноты сведений при регистрации
|
||||
|
||||
Доля обращений с неполными сведениями об оборудовании составляла 18 %, поэтому регистрация заявки блокируется до получения идентификатора единицы оборудования из внешнего справочника. Обращение к справочнику выполняется при вводе, а не при сохранении: диспетчер видит ошибку до того, как заполнит остальные поля.
|
||||
|
||||
Проверка вернула долю отклонённых при вводе форм на уровне 4 % от общего числа регистраций, остальные обращения были дополнены сведениями сразу.
|
||||
|
||||
# *ЗАКЛЮЧЕНИЕ
|
||||
|
||||
Проанализирован процесс приёма и исполнения заявок на техническое обслуживание: в нём участвуют три роли, а основной потерей времени является уточнение сведений об оборудовании, затрагивающее почти каждое пятое обращение.
|
||||
|
||||
Сформированы требования к модулю и выбран вариант собственной разработки — он закрывает требования подразделения при наименьшей трудоёмкости внедрения и позволяет получать справочник оборудования по REST вместо файлового обмена.
|
||||
|
||||
Модуль спроектирован по трёхуровневой схеме; модель данных содержит заявку, работу и запись истории, а справочник оборудования остаётся во внешней системе. Оценка объёма хранилища за три года эксплуатации составила около 98 мегабайт, что не требует секционирования таблиц.
|
||||
|
||||
Реализованы контроль срока исполнения с нормативами по категориям оборудования и проверка полноты сведений на этапе ввода: доля неполных обращений снизилась с 18 % до 4 %.
|
||||
|
||||
# *СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
|
||||
|
||||
[1]: Ричардс М., Форд Н. Фундаментальный подход к программной архитектуре: паттерны, свойства, проверенные методы. — СПб.: Питер, 2023. — 432 с.
|
||||
|
||||
[2]: Клеппман М. Высоконагруженные приложения: программирование, масштабирование, поддержка. — СПб.: Питер, 2022. — 640 с.
|
||||
|
||||
[3]: ГОСТ Р ИСО/МЭК 25010-2015. Информационные технологии. Системная и программная инженерия. Требования и оценка качества систем и программного обеспечения. — М.: Стандартинформ, 2022. — 36 с.
|
||||
|
||||
[4]: Ньюмен С. От монолита к микросервисам. — М.: ДМК Пресс, 2022. — 274 с.
|
||||
|
||||
[5]: Документация PostgreSQL 16. Раздел «Database Physical Storage». — URL: https://www.postgresql.org/docs/16/storage.html (дата обращения: 14.02.2026).
|
||||
|
||||
[6]: Кириллина Ю. В. и др. Методические указания по оформлению учебных работ. — М.: РТУ МИРЭА, 2022. — 64 с.
|
||||
|
||||
# *ПРИЛОЖЕНИЯ
|
||||
|
||||
Приложение А — Схема состояний заявки
|
||||
Приложение Б — Фрагмент сценария регистрации заявки
|
||||
|
||||
## Приложение А Схема состояний заявки
|
||||
|
||||
Переходы между состояниями заявки приведены на @Рисунок:state_req. Требования к оформлению схемы приняты по методическим указаниям [6].
|
||||
|
||||
%state_req Состояния заявки на обслуживание
|
||||
|
||||
```uml
|
||||
@startuml
|
||||
[*] --> Новая
|
||||
Новая --> Назначена : назначен исполнитель
|
||||
Назначена --> ВРаботе : работы начаты
|
||||
ВРаботе --> Закрыта : работы завершены
|
||||
Назначена --> Отклонена : обращение неправомерно
|
||||
Новая --> Отклонена : обращение неправомерно
|
||||
Закрыта --> [*]
|
||||
Отклонена --> [*]
|
||||
@enduml
|
||||
```
|
||||
|
||||
## Приложение Б Фрагмент сценария регистрации заявки
|
||||
|
||||
Последовательность обращений при регистрации заявки приведена на @Рисунок:seq_reg.
|
||||
|
||||
%seq_reg Последовательность регистрации заявки
|
||||
|
||||
```uml
|
||||
@startuml
|
||||
autonumber
|
||||
actor Диспетчер as d
|
||||
participant "Веб-клиент" as spa
|
||||
participant "Сервис заявок" as api
|
||||
participant "Справочник оборудования" as equip
|
||||
database "Хранилище" as db
|
||||
|
||||
d -> spa : вводит идентификатор оборудования
|
||||
spa -> api : GET /equipment/{ref}
|
||||
api -> equip : GET /units/{ref}
|
||||
equip --> api : сведения об оборудовании
|
||||
api --> spa : карточка оборудования
|
||||
d -> spa : заполняет описание неисправности
|
||||
spa -> api : POST /requests
|
||||
api -> db : INSERT request
|
||||
db --> api : идентификатор заявки
|
||||
api --> spa : номер заявки и срок исполнения
|
||||
@enduml
|
||||
```
|
||||
Reference in New Issue
Block a user