You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

16 KiB

Анализ таблиц для тестирования сотрудников

Модуль TestingWebApp использует отдельную БД clinic_tests (см. PROJECT_STATUS.md и README.md). Ниже — разбор наследуемых / смежных сущностей в другой схеме, для сравнения и миграционных дискуссий.

Обзор существующих таблиц

В базе данных существуют следующие таблицы, связанные с тестированием:

1. training_questions - Вопросы обучения

Колонка Тип Описание
id integer Первичный ключ
position text Должность/категория
test_type text Тип темы/теста
question text Текст вопроса
answer_1 - answer_12 text Варианты ответов
answer_count smallint Количество правильных ответов

Проблемы:

  • Отсутствует явное указание правильного ответа
  • Нет типа вопроса (одиночный/множественный выбор, текстовый, сопоставление)
  • Нет баллов за вопрос
  • Нет порядка вопросов
  • Поле position используется как категория, но не связано с должностями

2. training_results - Результаты обучения

Колонка Тип Описание
id integer Первичный ключ
telegram_id bigint ID сотрудника
correct_answers integer Правильные ответы
total_questions integer Всего вопросов
score integer Балл
completed_at timestamp Дата завершения
passed boolean Пройден/не пройден

Индексы:

  • idx_training_results_telegram_id - по telegram_id

Проблемы:

  • Нет связи с конкретным тестом (test_type)
  • Нет количества попыток
  • Нет детализации по ответам

3. training_settings - Настройки обучения

Колонка Тип Описание
id integer Первичный ключ
position varchar(100) Должность
question_count integer Количество вопросов (по умолчанию 10)
passing_score integer Проходной балл (по умолчанию 70)
time_limit integer Ограничение времени в минутах (по умолчанию 30)
active boolean Активен/неактивен

Индексы:

  • idx_training_settings_position - по position

Проблемы:

  • Нет связи с категорией теста
  • Нет ограничения количества попыток
  • Нет настройки случайного порядка вопросов

4. test_assignments - Назначения тестов

Колонка Тип Описание
id integer Первичный ключ
la_name text Название адаптации
intern_fio text ФИО стажера
user_credentials text Учетные данные
test_theme text Тема теста
test_subtheme text Подтема теста
attempts_allowed integer Количество попыток
passing_score integer Проходной балл
la_id integer Ссылка на адаптацию
intern_id bigint ID сотрудника (staff_members.id)
deadline timestamp Срок сдачи

Внешние ключи:

  • intern_id -> staff_members(id)
  • la_id -> learning_adaptations(id)

Проблемы:

  • Назначения привязаны к конкретным сотрудникам, а не к должностям
  • Нет статуса прохождения
  • Нет связи с результатами

5. test_table - Таблица тестов

Колонка Тип Описание
id integer Первичный ключ
name varchar(100) Название теста

Проблемы:

  • Минимальная структура, практически не используется

6. corp_groups_tester - Тестировщики (корпоративные группы)

Колонка Тип Описание
id integer Первичный ключ
fio text ФИО
telegram_id varchar(20) Telegram ID
position varchar(200) Должность
department varchar(200) Отдел
phone varchar(20) Телефон
email varchar(100) Email
hire_date date Дата приема

Проблемы:

  • Дублирует данные staff_members
  • Не используется в текущей системе

Рекомендуемая расширенная схема для ClinicTestingApp

Новые таблицы

1. tests - Основные тесты

CREATE TABLE tests (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,              -- Название теста
    description TEXT,                        -- Описание
    category VARCHAR(100),                   -- Категория (тема)
    position VARCHAR(100),                   -- Должность (nullable - для всех)
    question_count INTEGER DEFAULT 10,      -- Количество вопросов в тесте
    time_limit_minutes INTEGER,             -- Ограничение времени (null = без ограничений)
    attempts_allowed INTEGER DEFAULT 3,     -- Количество попыток
    passing_score_percent INTEGER DEFAULT 70, -- Проходной процент
    random_questions BOOLEAN DEFAULT FALSE, -- Случайный порядок вопросов
    is_active BOOLEAN DEFAULT TRUE,         -- Активен
    created_by INTEGER,                      -- ID администратора
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_tests_category ON tests(category);
CREATE INDEX idx_tests_position ON tests(position);

2. test_questions - Вопросы тестов

CREATE TABLE test_questions (
    id SERIAL PRIMARY KEY,
    test_id INTEGER NOT NULL REFERENCES tests(id) ON DELETE CASCADE,
    question_text TEXT NOT NULL,            -- Текст вопроса
    question_type VARCHAR(50) NOT NULL,      -- single_choice, multiple_choice, text, matching, ordering
    points INTEGER DEFAULT 1,               -- Баллы за вопрос
    question_order INTEGER,                  -- Порядок вопроса
    explanation TEXT,                        -- Пояснение к ответу
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_test_questions_test_id ON test_questions(test_id);

3. test_answers - Ответы на вопросы

CREATE TABLE test_answers (
    id SERIAL PRIMARY KEY,
    question_id INTEGER NOT NULL REFERENCES test_questions(id) ON DELETE CASCADE,
    answer_text TEXT NOT NULL,               -- Текст ответа
    is_correct BOOLEAN DEFAULT FALSE,        -- Правильный ответ
    answer_order INTEGER,                      -- Порядок (для сопоставления/порядка)
    points_if_correct INTEGER DEFAULT 1       -- Баллы (если отличаются от question.points)
);

CREATE INDEX idx_test_answers_question_id ON test_answers(question_id);

4. test_assignments_extended - Расширенные назначения тестов

CREATE TABLE test_assignments_extended (
    id SERIAL PRIMARY KEY,
    test_id INTEGER NOT NULL REFERENCES tests(id) ON DELETE CASCADE,
    staff_id INTEGER NOT NULL REFERENCES staff_members(id) ON DELETE CASCADE,
    assigned_by INTEGER,                      -- ID администратора
    assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    deadline TIMESTAMP,                      -- Срок сдачи
    attempts_allowed INTEGER,                 -- Переопределение количества попыток (null = из теста)
    status VARCHAR(50) DEFAULT 'pending',     -- pending, in_progress, completed, expired
    UNIQUE(test_id, staff_id)
);

CREATE INDEX idx_test_assignments_test_id ON test_assignments_extended(test_id);
CREATE INDEX idx_test_assignments_staff_id ON test_assignments_extended(staff_id);

5. test_attempts - Попытки прохождения

CREATE TABLE test_attempts (
    id SERIAL PRIMARY KEY,
    assignment_id INTEGER NOT NULL REFERENCES test_assignments_extended(id) ON DELETE CASCADE,
    attempt_number INTEGER NOT NULL,          -- Номер попытки
    started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    completed_at TIMESTAMP,                  -- Завершена
    score_points INTEGER,                     -- Набрано баллов
    score_percent NUMERIC(5,2),               -- Процент
    passed BOOLEAN,                           -- Пройден/не пройден
    time_spent_seconds INTEGER               -- Потраченное время
);

CREATE INDEX idx_test_attempts_assignment_id ON test_attempts(assignment_id);

6. test_answers_given - Ответы пользователя

CREATE TABLE test_answers_given (
    id SERIAL PRIMARY KEY,
    attempt_id INTEGER NOT NULL REFERENCES test_attempts(id) ON DELETE CASCADE,
    question_id INTEGER NOT NULL REFERENCES test_questions(id) ON DELETE CASCADE,
    given_answer_ids INTEGER[],               -- ID выбранных ответов (для choice)
    given_text TEXT,                          -- Текстовый ответ
    is_correct BOOLEAN,                       -- Правильный/неправильный
    points_earned INTEGER,                    -- Полученные баллы
    answered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_test_answers_given_attempt_id ON test_answers_given(attempt_id);

7. test_categories - Категории тестов

CREATE TABLE test_categories (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL UNIQUE,
    description TEXT,
    parent_id INTEGER REFERENCES test_categories(id),
    is_active BOOLEAN DEFAULT TRUE
);

8. test_reports - Сформированные отчеты

CREATE TABLE test_reports (
    id SERIAL PRIMARY KEY,
    report_type VARCHAR(50) NOT NULL,         -- department, employee, category
    parameters JSONB,                         -- Параметры отчета
    file_path VARCHAR(500),                   -- Путь к файлу
    format VARCHAR(10),                       -- pdf, xlsx
    generated_by INTEGER,                     -- ID администратора
    generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Расширение существующих таблиц (миграции)

training_questions

-- Добавить тип вопроса
ALTER TABLE training_questions ADD COLUMN IF NOT EXISTS question_type VARCHAR(50) DEFAULT 'single_choice';

-- Добавить баллы
ALTER TABLE training_questions ADD COLUMN IF NOT EXISTS points INTEGER DEFAULT 1;

-- Добавить правильный ответ (индекс)
ALTER TABLE training_questions ADD COLUMN IF NOT EXISTS correct_answer_index INTEGER;

-- Добавить порядок
ALTER TABLE training_questions ADD COLUMN IF NOT EXISTS sort_order INTEGER;

-- Добавить пояснение
ALTER TABLE training_questions ADD COLUMN IF NOT EXISTS explanation TEXT;

training_results

-- Добавить связь с тестом
ALTER TABLE training_results ADD COLUMN IF NOT EXISTS test_id INTEGER REFERENCES tests(id);

-- Добавить номер попытки
ALTER TABLE training_results ADD COLUMN IF NOT EXISTS attempt_number INTEGER DEFAULT 1;

-- Добавить время прохождения
ALTER TABLE training_results ADD COLUMN IF NOT EXISTS time_spent_seconds INTEGER;

-- Добавить детализацию ответов (JSON)
ALTER TABLE training_results ADD COLUMN IF NOT EXISTS answers_detail JSONB;

training_settings

-- Добавить связь с тестом
ALTER TABLE training_settings ADD COLUMN IF NOT EXISTS test_id INTEGER REFERENCES tests(id);

-- Добавить категорию
ALTER TABLE training_settings ADD COLUMN IF NOT EXISTS category VARCHAR(100);

-- Добавить случайный порядок
ALTER TABLE training_settings ADD COLUMN IF NOT EXISTS random_order BOOLEAN DEFAULT FALSE;

Связь с staff_members

Текущая проблема: используется telegram_id для связи с сотрудниками.

Решение: перейти на использование staff_members.id как универсального идентификатора:

-- Добавить staff_id в training_results
ALTER TABLE training_results ADD COLUMN IF NOT EXISTS staff_id INTEGER REFERENCES staff_members(id);

-- Миграция данных
UPDATE training_results tr
SET staff_id = sm.id
FROM staff_members sm
WHERE tr.telegram_id = sm.telegram_id;

-- Создать внешний ключ после миграции
ALTER TABLE training_results 
ADD CONSTRAINT training_results_staff_id_fkey 
FOREIGN KEY (staff_id) REFERENCES staff_members(id);

Типы вопросов

Тип Код Описание
Одиночный выбор single_choice Один правильный ответ из нескольких
Множественный выбор multiple_choice Несколько правильных ответов
Текстовый ответ text Свободный текст
Сопоставление matching Сопоставление пар
Порядок элементов ordering Расстановка в правильном порядке

API Endpoints (рекомендуемые)

Тесты

  • GET /api/tests - Список тестов
  • POST /api/tests - Создать тест
  • GET /api/tests/{id} - Получить тест с вопросами
  • PUT /api/tests/{id} - Обновить тест
  • DELETE /api/tests/{id} - Удалить тест

Вопросы

  • GET /api/tests/{test_id}/questions - Список вопросов
  • POST /api/tests/{test_id}/questions - Добавить вопрос
  • PUT /api/questions/{id} - Обновить вопрос
  • DELETE /api/questions/{id} - Удалить вопрос

Назначения

  • GET /api/assignments - Список назначений
  • POST /api/assignments - Назначить тест
  • GET /api/employees/{id}/assignments - Назначения сотрудника

Прохождение

  • POST /api/tests/{id}/start - Начать тест
  • POST /api/attempts/{id}/answer - Ответить на вопрос
  • POST /api/attempts/{id}/complete - Завершить тест

Отчеты

  • GET /api/reports/department - Отчет по отделениям
  • GET /api/reports/employee/{id} - Отчет по сотруднику
  • GET /api/reports/category/{id} - Отчет по категории
  • GET /api/reports/export - Экспорт отчета (PDF/Excel)