719 lines
28 KiB
YAML
719 lines
28 KiB
YAML
openapi: 3.1.0
|
||
info:
|
||
title: Krona Staff API
|
||
version: 0.3.1
|
||
description: API посещаемости Krona Staff для кабинета сотрудника, терминала и табеля руководителя.
|
||
license:
|
||
name: Proprietary
|
||
url: https://git.ochenstarik.ru/ochenstarik/krona-staff/src/branch/main/LICENSE
|
||
servers:
|
||
- url: /api/v1/staff
|
||
security: []
|
||
paths:
|
||
/live:
|
||
get:
|
||
summary: Check process liveness
|
||
operationId: getLiveness
|
||
tags: [Operations]
|
||
responses:
|
||
'200':
|
||
description: Process is alive
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Health' }
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
/ready:
|
||
get:
|
||
summary: Check dependency readiness
|
||
operationId: getReadiness
|
||
tags: [Operations]
|
||
responses:
|
||
'200':
|
||
description: Required dependencies are ready
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Health' }
|
||
'503': { description: A required dependency is unavailable }
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
/version:
|
||
get:
|
||
summary: Read runtime build identity
|
||
operationId: getVersion
|
||
tags: [Operations]
|
||
responses:
|
||
'200':
|
||
description: Runtime build identity
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Version' }
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
/session:
|
||
post:
|
||
summary: Открыть защищённую сессию администратора
|
||
operationId: createStaffSession
|
||
tags: [Authentication]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [access_token]
|
||
properties:
|
||
access_token: { type: string, minLength: 32, maxLength: 4096, writeOnly: true }
|
||
responses:
|
||
'200':
|
||
description: Сессия открыта; токен перенесён в HttpOnly Secure cookie
|
||
'401': { description: Ключ недействителен }
|
||
'403': { description: Ключ не имеет прав администратора }
|
||
delete:
|
||
summary: Завершить сессию администратора
|
||
operationId: deleteStaffSession
|
||
tags: [Authentication]
|
||
responses:
|
||
'204': { description: Сессия завершена }
|
||
'403': { description: Запрос с постороннего сайта отклонён }
|
||
/portal:
|
||
get:
|
||
summary: Получить доступную пользователю сводку посещаемости и табеля
|
||
operationId: getStaffPortal
|
||
tags: [Attendance]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Сводка с автоматическим ограничением данными текущего сотрудника
|
||
content:
|
||
application/json:
|
||
schema: { type: object }
|
||
'403': { description: Недостаточно прав }
|
||
/employees:
|
||
post:
|
||
summary: Добавить сотрудника
|
||
operationId: createStaffEmployee
|
||
tags: [Employees]
|
||
security: [{ bearerAuth: [] }]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/EmployeeCreate'
|
||
responses:
|
||
'201':
|
||
description: Сотрудник создан
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Employee' }
|
||
'403': { description: Недостаточно прав }
|
||
'409': { description: Табельный номер уже используется }
|
||
/professions:
|
||
get:
|
||
summary: Получить кадровый справочник профессий
|
||
operationId: listStaffProfessions
|
||
tags: [Employees]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200': { description: Tenant profession catalogue }
|
||
'401': { description: Требуется авторизация }
|
||
post:
|
||
summary: Добавить профессию в кадровый справочник
|
||
operationId: createStaffProfession
|
||
tags: [Employees]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'201': { description: Profession created }
|
||
'403': { description: Недостаточно прав }
|
||
'409': { description: Профессия уже существует }
|
||
/professions/{professionId}:
|
||
parameters:
|
||
- in: path
|
||
name: professionId
|
||
required: true
|
||
schema: { type: string, pattern: '^[0-9A-HJKMNP-TV-Z]{26}$' }
|
||
patch:
|
||
summary: Изменить профессию или её статус
|
||
operationId: updateStaffProfession
|
||
tags: [Employees]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200': { description: Profession updated }
|
||
'403': { description: Недостаточно прав }
|
||
'404': { description: Профессия не найдена }
|
||
/employees/{employeeId}:
|
||
patch:
|
||
summary: Изменить карточку или статус сотрудника
|
||
operationId: updateStaffEmployee
|
||
tags: [Employees]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- in: path
|
||
name: employeeId
|
||
required: true
|
||
schema: { $ref: '#/components/schemas/Ulid' }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/EmployeeUpdate'
|
||
responses:
|
||
'200':
|
||
description: Сотрудник изменён
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Employee' }
|
||
'403': { description: Недостаточно прав }
|
||
'404': { description: Сотрудник не найден }
|
||
/attendance/events:
|
||
post:
|
||
summary: Принять идемпотентную отметку терминала
|
||
operationId: recordAttendanceEvent
|
||
tags: [Attendance]
|
||
security: [{ bearerAuth: [] }]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [employee_id, event_type, occurred_at, source_event_id]
|
||
properties:
|
||
event_id: { $ref: '#/components/schemas/Ulid' }
|
||
employee_id: { $ref: '#/components/schemas/Ulid' }
|
||
event_type: { enum: [check_in, check_out] }
|
||
occurred_at: { type: string, format: date-time }
|
||
source_event_id: { type: string, minLength: 1, maxLength: 200 }
|
||
device_id: { $ref: '#/components/schemas/Ulid' }
|
||
org_unit_id: { $ref: '#/components/schemas/Ulid' }
|
||
responses:
|
||
'201': { description: Отметка принята }
|
||
'200': { description: Повтор уже принятой отметки }
|
||
'403': { description: Недостаточно прав }
|
||
/work-sessions/reconcile:
|
||
post:
|
||
summary: Сверить отметки терминала и сформировать смены за период
|
||
operationId: reconcileStaffWorkSessions
|
||
tags: [Work Sessions]
|
||
security: [{ bearerAuth: [] }]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [date_from, date_to]
|
||
properties:
|
||
date_from: { type: string, format: date }
|
||
date_to: { type: string, format: date }
|
||
business_day_start_hour: { type: integer, minimum: 0, maximum: 23, default: 4 }
|
||
automatic_close_hour: { type: integer, minimum: 0, maximum: 23, default: 2 }
|
||
open_shift_threshold_minutes:
|
||
{ type: integer, minimum: 60, maximum: 2880, default: 840 }
|
||
responses:
|
||
'200':
|
||
description: Итоги сверки, включая события без назначенного подразделения
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
[
|
||
groups,
|
||
sessions_created_or_updated,
|
||
confirmed_sessions_skipped,
|
||
anomalous_sessions,
|
||
unresolved_events,
|
||
]
|
||
properties:
|
||
groups: { type: integer, minimum: 0 }
|
||
sessions_created_or_updated: { type: integer, minimum: 0 }
|
||
confirmed_sessions_skipped: { type: integer, minimum: 0 }
|
||
anomalous_sessions: { type: integer, minimum: 0 }
|
||
unresolved_events: { type: integer, minimum: 0 }
|
||
'403': { description: Недостаточно прав }
|
||
/work-sessions/{sessionId}:
|
||
patch:
|
||
summary: Подтвердить, отклонить или скорректировать рабочую смену
|
||
operationId: reviewStaffWorkSession
|
||
tags: [Work Sessions]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- in: path
|
||
name: sessionId
|
||
required: true
|
||
schema: { $ref: '#/components/schemas/Ulid' }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [status]
|
||
properties:
|
||
status: { enum: [confirmed, rejected] }
|
||
worked_minutes: { type: integer, minimum: 0, maximum: 2880 }
|
||
started_at:
|
||
oneOf: [{ type: string, format: date-time }, { type: 'null' }]
|
||
ended_at:
|
||
oneOf: [{ type: string, format: date-time }, { type: 'null' }]
|
||
correction_note: { type: string, maxLength: 1000 }
|
||
responses:
|
||
'200': { description: Смена проверена; подтверждённые часы перенесены в табель }
|
||
'400': { description: Для корректировки не указана причина или интервал некорректен }
|
||
'403': { description: Недостаточно прав }
|
||
'404': { description: Смена не найдена }
|
||
/timesheets/{employeeId}/{workDate}:
|
||
put:
|
||
summary: Сохранить строку табеля
|
||
operationId: saveTimesheetEntry
|
||
tags: [Timesheet]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- in: path
|
||
name: employeeId
|
||
required: true
|
||
schema: { $ref: '#/components/schemas/Ulid' }
|
||
- in: path
|
||
name: workDate
|
||
required: true
|
||
schema: { type: string, format: date }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [minutes_worked, status]
|
||
properties:
|
||
minutes_worked: { type: integer, minimum: 0, maximum: 1440 }
|
||
status: { enum: [draft, submitted, approved, rejected] }
|
||
note: { type: string, maxLength: 1000 }
|
||
responses:
|
||
'200': { description: Строка табеля сохранена }
|
||
'403': { description: Недостаточно прав }
|
||
/employees/{employeeId}/access-token:
|
||
post:
|
||
summary: Выпустить новый одноразово показываемый ключ личного кабинета сотрудника
|
||
operationId: rotateEmployeeAccessToken
|
||
tags: [Employees]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- in: path
|
||
name: employeeId
|
||
required: true
|
||
schema: { $ref: '#/components/schemas/Ulid' }
|
||
responses:
|
||
'200': { description: Ключ выпущен; на сервере сохранён только его SHA-256 отпечаток }
|
||
'403': { description: Недостаточно прав }
|
||
'404': { description: Сотрудник не найден }
|
||
/employees/{employeeId}/pay-assignment:
|
||
get:
|
||
summary: Получить зарплатный профиль сотрудника
|
||
operationId: getEmployeePayAssignment
|
||
tags: [Payroll]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- in: path
|
||
name: employeeId
|
||
required: true
|
||
schema: { $ref: '#/components/schemas/Ulid' }
|
||
responses:
|
||
'200':
|
||
description: Зарплатный профиль сотрудника
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/PayAssignment' }
|
||
'403': { description: Недостаточно прав }
|
||
'404': { description: Сотрудник или зарплатный профиль не найден }
|
||
put:
|
||
summary: Сохранить зарплатный профиль сотрудника
|
||
operationId: saveEmployeePayAssignment
|
||
tags: [Payroll]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- in: path
|
||
name: employeeId
|
||
required: true
|
||
schema: { $ref: '#/components/schemas/Ulid' }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/PayAssignmentSave' }
|
||
responses:
|
||
'200':
|
||
description: Зарплатный профиль сохранён
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/PayAssignment' }
|
||
'403': { description: Недостаточно прав }
|
||
'404': { description: 'Сотрудник, точка или схема не найдены' }
|
||
/pay-rules:
|
||
get:
|
||
summary: Получить список схем расчёта зарплаты
|
||
operationId: listStaffPayRules
|
||
tags: [Payroll]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Список доступных схем расчёта
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [pay_rules]
|
||
properties:
|
||
pay_rules:
|
||
type: array
|
||
items: { type: object }
|
||
'403': { description: Недостаточно прав }
|
||
/org-units:
|
||
get:
|
||
summary: Получить доступные торговые точки
|
||
operationId: listStaffOrgUnits
|
||
tags: [Organization]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200': { description: Список доступных торговых точек }
|
||
'403': { description: Недостаточно прав }
|
||
/finance:
|
||
get:
|
||
summary: Получить доходы, расходы и дневную динамику за период
|
||
operationId: getStaffFinance
|
||
tags: [Finance]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- { in: query, name: from, required: true, schema: { type: string, format: date } }
|
||
- { in: query, name: to, required: true, schema: { type: string, format: date } }
|
||
responses:
|
||
'200': { description: Финансовые операции и агрегаты }
|
||
'403': { description: Недостаточно прав }
|
||
/finance/{orgUnitId}/{businessDate}/{metricKey}:
|
||
put:
|
||
summary: Сохранить сумму по финансовой категории за день
|
||
operationId: saveStaffFinanceMetric
|
||
tags: [Finance]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- {
|
||
in: path,
|
||
name: orgUnitId,
|
||
required: true,
|
||
schema: { $ref: '#/components/schemas/Ulid' },
|
||
}
|
||
- { in: path, name: businessDate, required: true, schema: { type: string, format: date } }
|
||
- { in: path, name: metricKey, required: true, schema: { type: string } }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [value_minor]
|
||
properties:
|
||
value_minor:
|
||
{ type: integer, minimum: -9000000000000000, maximum: 9000000000000000 }
|
||
currency_code: { type: string, pattern: '^[A-Z]{3}$' }
|
||
responses:
|
||
'200': { description: Сумма сохранена }
|
||
'403': { description: Недостаточно прав }
|
||
/schedule:
|
||
get:
|
||
summary: Получить плановые смены и фактические отметки сканера
|
||
operationId: getStaffSchedule
|
||
tags: [Schedule]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- { in: query, name: from, required: true, schema: { type: string, format: date } }
|
||
- { in: query, name: to, required: true, schema: { type: string, format: date } }
|
||
responses:
|
||
'200': { description: Календарь плановых и фактических смен }
|
||
'403': { description: Недостаточно прав }
|
||
/schedule/{employeeId}/{businessDate}:
|
||
put:
|
||
summary: Запланировать или удалить смену сотрудника
|
||
operationId: saveStaffPlannedShift
|
||
tags: [Schedule]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- {
|
||
in: path,
|
||
name: employeeId,
|
||
required: true,
|
||
schema: { $ref: '#/components/schemas/Ulid' },
|
||
}
|
||
- { in: path, name: businessDate, required: true, schema: { type: string, format: date } }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [org_unit_id, planned_minutes]
|
||
properties:
|
||
org_unit_id: { $ref: '#/components/schemas/Ulid' }
|
||
planned_minutes: { type: integer, minimum: 0, maximum: 1440 }
|
||
start_time: { type: string }
|
||
end_time: { type: string }
|
||
note: { type: string, maxLength: 500 }
|
||
responses:
|
||
'200': { description: План смены сохранён }
|
||
'403': { description: Недостаточно прав }
|
||
/payroll:
|
||
get:
|
||
summary: Получить зарплатные итоги и расчётный лист за период
|
||
operationId: getStaffPayroll
|
||
tags: [Payroll]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- { in: query, name: from, required: true, schema: { type: string, format: date } }
|
||
- { in: query, name: to, required: true, schema: { type: string, format: date } }
|
||
responses:
|
||
'200': { description: 'Начисления, выплаты, остаток и подтверждённые часы' }
|
||
'403': { description: Недостаточно прав }
|
||
/payroll/calculate:
|
||
post:
|
||
summary: Рассчитать зарплату за период
|
||
operationId: calculateStaffPayroll
|
||
tags: [Payroll]
|
||
security: [{ bearerAuth: [] }]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
month: { type: string, pattern: '^\\d{4}-\\d{2}$' }
|
||
from: { type: string, format: date }
|
||
to: { type: string, format: date }
|
||
org_unit_id: { $ref: '#/components/schemas/Ulid' }
|
||
responses:
|
||
'200':
|
||
description: Предварительный результат расчёта
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
[run_id, status, period_start, period_end, total_accrued_minor, totals, warnings]
|
||
properties:
|
||
run_id: { $ref: '#/components/schemas/Ulid' }
|
||
status: { const: calculated }
|
||
period_start: { type: string, format: date }
|
||
period_end: { type: string, format: date }
|
||
total_accrued_minor: { type: string }
|
||
totals: { type: array, items: { type: object } }
|
||
warnings: { type: array, items: { type: object } }
|
||
'400': { description: Некорректный период }
|
||
'403': { description: Недостаточно прав }
|
||
'409': { description: Расчёт за этот период уже утверждён }
|
||
/payroll/runs/{runId}/approve:
|
||
post:
|
||
summary: Утвердить расчёт зарплаты и записать начисления в реестр
|
||
operationId: approveStaffPayrollRun
|
||
tags: [Payroll]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- in: path
|
||
name: runId
|
||
required: true
|
||
schema: { $ref: '#/components/schemas/Ulid' }
|
||
responses:
|
||
'200':
|
||
description: Расчёт утверждён и проведён в реестр
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
[run_id, status, approved_by, approved_at, total_accrued_minor, entries_posted]
|
||
properties:
|
||
run_id: { $ref: '#/components/schemas/Ulid' }
|
||
status: { const: approved }
|
||
approved_by: { $ref: '#/components/schemas/Ulid' }
|
||
approved_at: { type: string, format: date-time }
|
||
total_accrued_minor: { type: string }
|
||
entries_posted: { type: integer }
|
||
'400': { description: Расчёт не в статусе calculated }
|
||
'403': { description: Недостаточно прав }
|
||
'404': { description: Расчёт не найден }
|
||
/payroll/runs/{runId}:
|
||
get:
|
||
summary: Получить подробности расчёта зарплаты
|
||
operationId: getStaffPayrollRun
|
||
tags: [Payroll]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- in: path
|
||
name: runId
|
||
required: true
|
||
schema: { $ref: '#/components/schemas/Ulid' }
|
||
responses:
|
||
'200':
|
||
description: Детали расчёта со строками
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [run, lines]
|
||
properties:
|
||
run: { type: object }
|
||
lines: { type: array, items: { type: object } }
|
||
'403': { description: Недостаточно прав }
|
||
'404': { description: Расчёт не найден }
|
||
/imports/owner-workbook:
|
||
post:
|
||
summary: Идемпотентно импортировать локально разобранную книгу владельца
|
||
operationId: importStaffOwnerWorkbook
|
||
tags: [Import]
|
||
security: [{ bearerAuth: [] }]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [source_name]
|
||
properties:
|
||
source_name: { type: string, maxLength: 240 }
|
||
units: { type: array, items: { type: object } }
|
||
financial_entries: { type: array, items: { type: object } }
|
||
employees: { type: array, items: { type: object } }
|
||
schedule_items: { type: array, items: { type: object } }
|
||
payroll_entries: { type: array, items: { type: object } }
|
||
responses:
|
||
'200': { description: Пакет импортирован повторяемо без дублирования }
|
||
'403': { description: Недостаточно прав }
|
||
components:
|
||
securitySchemes:
|
||
bearerAuth:
|
||
type: http
|
||
scheme: bearer
|
||
bearerFormat: JWT
|
||
responses:
|
||
BadRequest:
|
||
description: Invalid request
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Problem' }
|
||
schemas:
|
||
Ulid:
|
||
type: string
|
||
pattern: '^[0-9A-HJKMNP-TV-Z]{26}$'
|
||
examples: [01J00000000000000000000000]
|
||
Health:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [status]
|
||
properties:
|
||
status: { type: string }
|
||
Employee:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [id, personnel_number, display_name, position, gender, status]
|
||
properties:
|
||
id: { $ref: '#/components/schemas/Ulid' }
|
||
core_user_id:
|
||
oneOf:
|
||
- { $ref: '#/components/schemas/Ulid' }
|
||
- { type: 'null' }
|
||
personnel_number: { type: string }
|
||
display_name: { type: string }
|
||
position: { type: string }
|
||
gender: { enum: ['', male, female] }
|
||
status: { enum: [active, blocked, dismissed] }
|
||
EmployeeCreate:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [personnel_number, display_name]
|
||
properties:
|
||
personnel_number: { type: string, minLength: 1, maxLength: 80 }
|
||
display_name: { type: string, minLength: 1, maxLength: 240 }
|
||
position: { type: string, maxLength: 160 }
|
||
gender: { enum: ['', male, female] }
|
||
EmployeeUpdate:
|
||
type: object
|
||
additionalProperties: false
|
||
minProperties: 1
|
||
properties:
|
||
personnel_number: { type: string, minLength: 1, maxLength: 80 }
|
||
display_name: { type: string, minLength: 1, maxLength: 240 }
|
||
position: { type: string, maxLength: 160 }
|
||
gender: { enum: ['', male, female] }
|
||
status: { enum: [active, blocked, dismissed] }
|
||
Problem:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [type, title, status, trace_id]
|
||
properties:
|
||
type: { type: string, format: uri-reference }
|
||
title: { type: string }
|
||
status: { type: integer, minimum: 400, maximum: 599 }
|
||
trace_id: { $ref: '#/components/schemas/Ulid' }
|
||
Version:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [name, version, mode]
|
||
properties:
|
||
name: { const: krona-staff }
|
||
version: { type: string }
|
||
mode: { enum: [standalone, platform] }
|
||
PayAssignment:
|
||
type: object
|
||
additionalProperties: false
|
||
required:
|
||
[
|
||
id,
|
||
employee_id,
|
||
pay_rule_id,
|
||
pay_rule_code,
|
||
pay_rule_name,
|
||
rate_minor,
|
||
percent_bp,
|
||
guarantee_minor,
|
||
pool_weight_bp,
|
||
effective_from,
|
||
]
|
||
properties:
|
||
id: { $ref: '#/components/schemas/Ulid' }
|
||
employee_id: { $ref: '#/components/schemas/Ulid' }
|
||
org_unit_id:
|
||
oneOf:
|
||
- { $ref: '#/components/schemas/Ulid' }
|
||
- { type: 'null' }
|
||
pay_rule_id: { $ref: '#/components/schemas/Ulid' }
|
||
pay_rule_code: { type: string }
|
||
pay_rule_name: { type: string }
|
||
rate_minor: { type: integer, minimum: 0 }
|
||
percent_bp: { type: integer, minimum: 0 }
|
||
guarantee_minor: { type: integer, minimum: 0 }
|
||
pool_weight_bp: { type: integer, minimum: 0 }
|
||
effective_from: { type: string, format: date }
|
||
effective_to:
|
||
oneOf:
|
||
- { type: string, format: date }
|
||
- { type: 'null' }
|
||
params: { type: object }
|
||
note: { type: string }
|
||
PayAssignmentSave:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [pay_rule_id]
|
||
properties:
|
||
org_unit_id:
|
||
oneOf:
|
||
- { $ref: '#/components/schemas/Ulid' }
|
||
- { type: 'null' }
|
||
pay_rule_id: { $ref: '#/components/schemas/Ulid' }
|
||
rate_minor: { type: integer, minimum: 0 }
|
||
percent_bp: { type: integer, minimum: 0, maximum: 10000 }
|
||
guarantee_minor: { type: integer, minimum: 0 }
|
||
pool_weight_bp: { type: integer, minimum: 0, maximum: 20000 }
|
||
effective_from: { type: string, format: date }
|
||
note: { type: string, maxLength: 500 }
|