fleet-ble-monitor/frontend/docs/backend-domain-model.md

21 KiB
Raw Blame History

Fleet BLE Monitor Backend Contract Draft

Черновик backend-модели, GraphQL-like API и use-cases для fleet-ble-monitor.

Документ написан в формате, близком к GraphQL Docs: у сущности сразу перечислены поля, рядом указаны связанные enum/input/page-типы. Это не финальная схема, а база для обсуждения со старшим.

Общие скаляры

scalar DateTime
scalar Date

DateTime — ISO-строка даты и времени.

Date — календарная дата в формате YYYY-MM-DD.

User

Пользователь системы. Используется для авторизации, прав доступа и как получатель отчетов.

type User {
  id: ID!
  lastName: String!
  firstName: String!
  middleName: String
  email: String!
  login: String!
  role: UserRole!
  createdAt: DateTime!
  updatedAt: DateTime
}

UserRole

Роль пользователя.

enum UserRole {
  ADMIN
  USER
}

ADMIN — администратор.

USER — пользователь.

UsersPage

Страница пользователей для таблицы.

type UsersPage {
  totalPages: Int!
  totalElements: Int!
  page: [User!]!
}

UserSortField

Поле сортировки пользователей.

enum UserSortField {
  ID
  NAME
  DATE
}

SortDirection

Общее направление сортировки.

enum SortDirection {
  ASC
  DESC
}

LoginPayload

input LoginPayload {
  loginOrEmail: String!
  password: String!
}

CreateUserPayload

input CreateUserPayload {
  lastName: String!
  firstName: String!
  middleName: String
  email: String!
  login: String!
  password: String!
  role: UserRole!
}

UpdateUserPayload

input UpdateUserPayload {
  lastName: String
  firstName: String
  middleName: String
  email: String
  login: String
  password: String
  role: UserRole
}

Machine

АТТ / единица техники. Основная бизнес-сущность мониторинга.

type Machine {
  id: ID!
  name: String!
  licensePlate: String!
  type: MachineType!
  department: Department!
  description: String
  beacon: Beacon
  lastKnownState: MachineStateCode!
  lastDataReceivedAt: DateTime
  createdAt: DateTime!
  updatedAt: DateTime!
}

MachineType

Справочник типов АТТ.

type MachineType {
  id: ID!
  name: String!
  description: String
  createdAt: DateTime!
  updatedAt: DateTime!
}

Примеры: каток, самосвал, погрузчик, экскаватор.

Department

Справочник подразделений, участков или объектов.

type Department {
  id: ID!
  name: String!
  description: String
  createdAt: DateTime!
  updatedAt: DateTime!
}

MachineStateCode

Последнее известное базовое состояние АТТ.

enum MachineStateCode {
  IDLE
  ENGINE_ON
  MOVING
  NO_DATA
}

IDLE — стоит.

ENGINE_ON — заведена.

MOVING — в движении.

NO_DATA — нет данных.

MachinesPage

type MachinesPage {
  totalPages: Int!
  totalElements: Int!
  page: [Machine!]!
}

MachineSortField

enum MachineSortField {
  ID
  NAME
  DATE
}

CreateMachinePayload

input CreateMachinePayload {
  name: String!
  licensePlate: String!
  typeId: ID!
  departmentId: ID!
  description: String
}

UpdateMachinePayload

input UpdateMachinePayload {
  name: String
  licensePlate: String
  typeId: ID
  departmentId: ID
  description: String
}

Beacon

BLE-маяк. Хранит идентификатор, MAC-адрес, статус привязки, последнюю связь.

type Beacon {
  id: ID!
  identifier: String!
  macAddress: String!
  status: BeaconStatus!
  boundMachine: Machine
  lastSeenAt: DateTime
  createdAt: DateTime!
  updatedAt: DateTime!
}

BeaconStatus

enum BeaconStatus {
  FREE
  BOUND
}

FREE — маяк свободен.

BOUND — маяк привязан к АТТ.

BeaconTelemetryPacket

Сырое сообщение от маяка.

type BeaconTelemetryPacket {
  id: ID!
  beacon: Beacon!
  machine: Machine
  mac: String!
  vibration: Float!
  duration: Int!
  timeMillis: Long!
  receivedAt: DateTime!
}

BeaconTelemetryPayload

Payload входящего сообщения от маяка.

input BeaconTelemetryPayload {
  mac: String!
  vibration: Float!
  duration: Int!
  timeMillis: Long!
}

duration — длительность замера/пакета в секундах.

timeMillis — время события на стороне маяка или шлюза.

MachineStateDefinition

Справочник состояний АТТ без привязки к конкретным значениям акселерометра.

type MachineStateDefinition {
  id: ID!
  name: String!
  icon: String!
  color: String!
  description: String
  isSystem: Boolean!
  createdAt: DateTime!
  updatedAt: DateTime!
}

Примеры:

  • Стоит
  • Заведена
  • В движении
  • Работа с нагрузкой
  • Нет данных

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

CreateMachineStateDefinitionPayload

input CreateMachineStateDefinitionPayload {
  name: String!
  icon: String!
  color: String!
  description: String
}

UpdateMachineStateDefinitionPayload

input UpdateMachineStateDefinitionPayload {
  name: String
  icon: String
  color: String
  description: String
}

MachineCalibrationRule

Правило калибровки для конкретной АТТ. Связывает диапазон значений вибрации с состоянием из справочника.

type MachineCalibrationRule {
  id: ID!
  machine: Machine!
  stateDefinition: MachineStateDefinition!
  vibrationMin: Float!
  vibrationMax: Float!
  createdAt: DateTime!
  updatedAt: DateTime!
}

CreateMachineCalibrationRulePayload

input CreateMachineCalibrationRulePayload {
  machineId: ID!
  stateDefinitionId: ID!
  vibrationMin: Float!
  vibrationMax: Float!
}

UpdateMachineCalibrationRulePayload

input UpdateMachineCalibrationRulePayload {
  stateDefinitionId: ID
  vibrationMin: Float
  vibrationMax: Float
}

MachineStateInterval

Распознанный интервал состояния АТТ.

type MachineStateInterval {
  id: ID!
  machine: Machine!
  stateDefinition: MachineStateDefinition
  stateCode: MachineStateCode
  startedAt: DateTime!
  endedAt: DateTime
  durationSeconds: Int!
  vibrationMin: Float
  vibrationMax: Float
  vibrationAvg: Float
  sampleCount: Int!
  isNoData: Boolean!
}

Если stateDefinition равен null, участок считается нераспознанным.

Если isNoData = true, участок относится к системному состоянию Нет данных.

MachineStateHistoryPage

type MachineStateHistoryPage {
  totalPages: Int!
  totalElements: Int!
  page: [MachineStateInterval!]!
}

MachineUsageSummary

Краткая статистика по АТТ за период.

type MachineUsageSummary {
  machine: Machine!
  periodStart: DateTime!
  periodEnd: DateTime!
  movingSeconds: Int!
  engineOnSeconds: Int!
  idleSeconds: Int!
  noDataSeconds: Int!
  stateChangesCount: Int!
  utilizationPercent: Int!
}

FleetReportSchedule

Настройка ежедневной рассылки отчета по парку АТТ.

type FleetReportSchedule {
  id: ID!
  name: String!
  recipients: [User!]!
  reportFormat: ReportFormat!
  sendTime: String!
  period: ReportPeriod!
  timezone: String!
  enabled: Boolean!
  createdAt: DateTime!
  updatedAt: DateTime!
}

ReportFormat

Формат отчета.

enum ReportFormat {
  PDF
  XLSX
}

ReportPeriod

Период отчета.

enum ReportPeriod {
  PREVIOUS_DAY
}

PREVIOUS_DAY — предыдущий календарный день относительно timezone расписания.

CreateFleetReportSchedulePayload

input CreateFleetReportSchedulePayload {
  recipientUserIds: [ID!]!
  reportFormat: ReportFormat!
  sendTime: String!
}

UpdateFleetReportSchedulePayload

input UpdateFleetReportSchedulePayload {
  recipientUserIds: [ID!]
  reportFormat: ReportFormat
  sendTime: String
  enabled: Boolean
}

FleetReportDelivery

История конкретной попытки отправки отчета.

type FleetReportDelivery {
  id: ID!
  schedule: FleetReportSchedule
  reportDate: Date!
  reportFormat: ReportFormat!
  recipients: [User!]!
  status: ReportDeliveryStatus!
  fileName: String
  errorMessage: String
  createdAt: DateTime!
  sentAt: DateTime
}

ReportDeliveryStatus

enum ReportDeliveryStatus {
  CREATED
  GENERATING
  SENT
  FAILED
}

CREATED — задача создана.

GENERATING — отчет формируется.

SENT — отчет отправлен.

FAILED — ошибка генерации или отправки.

FleetDailyReport

Доменная модель дневного отчета по парку АТТ.

type FleetDailyReport {
  date: Date!
  generatedAt: DateTime!
  summary: FleetDailyReportSummary!
  machines: [FleetDailyReportMachineRow!]!
  history: [FleetDailyReportHistoryRow!]!
}

FleetDailyReportSummary

type FleetDailyReportSummary {
  totalMachines: Int!
  boundMachines: Int!
  unboundMachines: Int!
  machinesWithMovement: Int!
  machinesWithoutData: Int!
  movingSeconds: Int!
  engineOnSeconds: Int!
  idleSeconds: Int!
  noDataSeconds: Int!
  stateChangesCount: Int!
}

FleetDailyReportMachineRow

type FleetDailyReportMachineRow {
  machine: Machine!
  movingSeconds: Int!
  engineOnSeconds: Int!
  idleSeconds: Int!
  noDataSeconds: Int!
  stateChangesCount: Int!
  utilizationPercent: Int!
}

FleetDailyReportHistoryRow

type FleetDailyReportHistoryRow {
  machine: Machine!
  startedAt: DateTime!
  endedAt: DateTime!
  stateDefinition: MachineStateDefinition
  stateCode: MachineStateCode
  durationSeconds: Int!
}

GenerateFleetDailyReportPayload

input GenerateFleetDailyReportPayload {
  date: Date!
  format: ReportFormat!
}

ReportFile

Ссылка на готовый файл отчета.

type ReportFile {
  fileName: String!
  mimeType: String!
  downloadUrl: String!
  expiresAt: DateTime
}

Физическая отдача файла может быть не через GraphQL, а через REST endpoint или object storage URL. GraphQL в таком случае возвращает downloadUrl.

Query

type Query {
  currentUser: User

  getUsers(
    page: Int!
    pageSize: Int
    query: String
    roles: [UserRole!]
    sortDirection: SortDirection!
    sortField: UserSortField!
  ): UsersPage!

  getUser(id: ID!): User

  getMachines(
    page: Int!
    pageSize: Int
    query: String
    sortDirection: SortDirection!
    sortField: MachineSortField!
  ): MachinesPage!

  getMachine(id: ID!): Machine

  getMachineTypes: [MachineType!]!

  getDepartments: [Department!]!

  getBeacons: [Beacon!]!

  getFreeBeacons: [Beacon!]!

  getBeaconTelemetry(
    beaconId: ID
    machineId: ID
    startDate: DateTime!
    endDate: DateTime!
  ): [BeaconTelemetryPacket!]!

  getMachineStateDefinitions: [MachineStateDefinition!]!

  getMachineCalibrationRules(machineId: ID!): [MachineCalibrationRule!]!

  getMachineStateHistory(
    machineId: ID!
    startDate: DateTime!
    endDate: DateTime!
    page: Int
    pageSize: Int
  ): MachineStateHistoryPage!

  getMachineUsageSummary(
    machineId: ID!
    startDate: DateTime!
    endDate: DateTime!
  ): MachineUsageSummary!

  getUnrecognizedTelemetryIntervals(
    machineId: ID!
    startDate: DateTime!
    endDate: DateTime!
  ): [MachineStateInterval!]!

  getFleetReportSchedules: [FleetReportSchedule!]!

  getFleetReportDeliveries(
    scheduleId: ID
    dateFrom: Date
    dateTo: Date
  ): [FleetReportDelivery!]!

  getFleetDailyReport(date: Date!): FleetDailyReport!

  createFleetDailyReportDownloadUrl(
    payload: GenerateFleetDailyReportPayload!
  ): ReportFile!
}

Mutation

type Mutation {
  login(payload: LoginPayload!): User!

  logout: Boolean!

  createUser(payload: CreateUserPayload!): User!

  updateUser(
    id: ID!
    payload: UpdateUserPayload!
  ): User!

  deleteUser(id: ID!): Boolean!

  createMachine(payload: CreateMachinePayload!): Machine!

  updateMachine(
    id: ID!
    payload: UpdateMachinePayload!
  ): Machine!

  deleteMachine(id: ID!): Boolean!

  bindBeaconToMachine(
    machineId: ID!
    beaconId: ID!
  ): Machine!

  unbindBeaconFromMachine(machineId: ID!): Machine!

  registerBeaconTelemetryPacket(
    payload: BeaconTelemetryPayload!
  ): Boolean!

  createMachineType(name: String!): MachineType!

  updateMachineType(
    id: ID!
    name: String!
  ): MachineType!

  deleteMachineType(id: ID!): Boolean!

  createDepartment(name: String!): Department!

  updateDepartment(
    id: ID!
    name: String!
  ): Department!

  deleteDepartment(id: ID!): Boolean!

  createMachineStateDefinition(
    payload: CreateMachineStateDefinitionPayload!
  ): MachineStateDefinition!

  updateMachineStateDefinition(
    id: ID!
    payload: UpdateMachineStateDefinitionPayload!
  ): MachineStateDefinition!

  deleteMachineStateDefinition(id: ID!): Boolean!

  createMachineCalibrationRule(
    payload: CreateMachineCalibrationRulePayload!
  ): MachineCalibrationRule!

  updateMachineCalibrationRule(
    id: ID!
    payload: UpdateMachineCalibrationRulePayload!
  ): MachineCalibrationRule!

  deleteMachineCalibrationRule(id: ID!): Boolean!

  recognizeMachineStates(
    machineId: ID!
    startDate: DateTime!
    endDate: DateTime!
  ): [MachineStateInterval!]!

  createFleetReportSchedule(
    payload: CreateFleetReportSchedulePayload!
  ): FleetReportSchedule!

  updateFleetReportSchedule(
    id: ID!
    payload: UpdateFleetReportSchedulePayload!
  ): FleetReportSchedule!

  deleteFleetReportSchedule(id: ID!): Boolean!

  sendFleetDailyReport(
    scheduleId: ID!
    reportDate: Date!
  ): FleetReportDelivery!
}

Use-Cases

Пользователи

LoginUserUseCase — авторизует пользователя по логину/email и паролю.

GetCurrentUserUseCase — возвращает текущего авторизованного пользователя.

GetUsersUseCase — возвращает список пользователей с поиском, сортировкой и пагинацией.

CreateUserUseCase — создает пользователя.

UpdateUserUseCase — редактирует данные пользователя.

DeleteUserUseCase — удаляет пользователя или блокирует, если будет выбран soft-delete подход.

АТТ

GetMachinesUseCase — возвращает список АТТ с поиском, сортировкой и пагинацией.

GetMachineByIdUseCase — возвращает карточку конкретной АТТ.

CreateMachineUseCase — создает новую АТТ.

UpdateMachineUseCase — редактирует данные АТТ.

DeleteMachineUseCase — удаляет АТТ или переводит в архив.

BindBeaconToMachineUseCase — привязывает свободный маяк к АТТ.

UnbindBeaconFromMachineUseCase — отвязывает маяк от АТТ.

Маяки и телеметрия

RegisterBeaconTelemetryPacketUseCase — принимает сырое сообщение от маяка и сохраняет его.

ResolveBeaconByMacUseCase — находит маяк по MAC-адресу из входящего пакета.

AttachTelemetryPacketToMachineUseCase — определяет, к какой АТТ относится пакет, если маяк привязан.

GetBeaconTelemetryUseCase — возвращает сырые показания маяка за период.

GetFreeBeaconsUseCase — возвращает список свободных маяков.

Калибровка

GetMachineStateDefinitionsUseCase — возвращает справочник состояний АТТ.

CreateMachineStateDefinitionUseCase — создает новое состояние в справочнике.

UpdateMachineStateDefinitionUseCase — редактирует состояние справочника.

DeleteMachineStateDefinitionUseCase — удаляет состояние, если оно не используется правилами.

GetMachineCalibrationRulesUseCase — возвращает правила калибровки конкретной АТТ.

CreateMachineCalibrationRuleUseCase — создает правило калибровки для АТТ.

UpdateMachineCalibrationRuleUseCase — редактирует правило калибровки.

DeleteMachineCalibrationRuleUseCase — удаляет правило калибровки.

ValidateMachineCalibrationRuleUseCase — проверяет правило на конфликты с уже существующими диапазонами.

RecognizeMachineStatesUseCase — по сырым данным акселерометра и правилам калибровки строит интервалы состояний.

GetUnrecognizedTelemetryIntervalsUseCase — возвращает участки телеметрии, которые не попали ни под одно правило.

История и аналитика

GetMachineStateHistoryUseCase — возвращает историю состояний АТТ за период.

GetMachineUsageSummaryUseCase — собирает краткую статистику по АТТ за период.

GetMachineDailyUsageStatsUseCase — возвращает дневную статистику по АТТ для графиков.

AggregateMachineStateIntervalsUseCase — агрегирует интервалы состояний из телеметрии.

Отчеты

GetFleetReportSchedulesUseCase — возвращает настройки рассылок отчетов.

CreateFleetReportScheduleUseCase — создает настройку ежедневной рассылки отчета.

UpdateFleetReportScheduleUseCase — редактирует настройку рассылки.

DeleteFleetReportScheduleUseCase — удаляет настройку рассылки.

GenerateFleetDailyReportUseCase — собирает дневной отчет по парку АТТ за выбранную дату.

ExportFleetDailyReportToPdfUseCase — формирует PDF-файл дневного отчета.

ExportFleetDailyReportToXlsxUseCase — формирует Excel-файл дневного отчета.

DownloadFleetDailyReportUseCase — отдает файл отчета пользователю по запросу из интерфейса.

RunScheduledFleetReportsUseCase — периодически запускает активные расписания рассылок.

SendFleetDailyReportUseCase — генерирует отчет и отправляет его выбранным пользователям.

CreateFleetReportDeliveryUseCase — создает запись о попытке отправки отчета.

MarkFleetReportDeliveryAsSentUseCase — помечает отправку как успешную.

MarkFleetReportDeliveryAsFailedUseCase — сохраняет ошибку отправки.

Доменные сервисы

MachineStateRecognitionService — определяет состояние АТТ по телеметрии и правилам калибровки.

MachineAnalyticsService — считает агрегаты: время в движении, заведена, стояла, нет данных, смены состояний.

FleetDailyReportBuilder — собирает доменную модель дневного отчета.

FleetReportExporter — общий интерфейс для экспорта отчета в файл.

PdfFleetReportExporter — экспортирует отчет в PDF.

XlsxFleetReportExporter — экспортирует отчет в Excel.

MailService — отправляет письма с вложениями.

ReportScheduler — запускает ежедневные рассылки по расписанию.