«Расписание занятий и экзаменов»: техническое исследование§
Исследованы DB/1_sem_2026_2027, служебные файлы в DB и все 15 изображений в screen. Дата исследования: 9 сентября 2026 года. Это описание предоставленного снимка данных и наблюдаемых экранов. Основная программа не запускалась: в проекте есть только связанная утилита Reorder.EXE, а исполняемого файла самого планировщика и его исходного кода нет.
1. Основные выводы§
Перед нами настольная система ведения учебных справочников, планов и расписания занятий и экзаменов. Она хранит данные в файловых таблицах Paradox: отдельный .DB содержит одну таблицу, а индексы и служебные настройки находятся в соседних файлах. Название папки обозначает предполагаемый учебный период, но само по себе не доказывает, что все данные внутри актуальны именно для него.
Данные успешно прочитаны. Из 19 таблиц извлечено 75 909 записей, включая связи и вспомогательные данные. Это не число занятий: непосредственно в Classes.DB находится 15 111 записей занятий, в GROUPS.DB — 554 группы, в TEACHERS.DB — 866 преподавателей, в Rooms.DB — 184 аудитории, в Plan.DB — 4 748 записей плана. Названия в .DB читаются в кодировке CP866. Все значения сопоставлены с независимым чтением через pxlib; исключение касается только счетчика записей в заголовке ClassesInf.DB, а не разницы извлеченных значений.
Технологии связанной утилиты установлены по бинарным заголовкам и ресурсам: Windows x86, Delphi/VCL, Borland Database Engine (BDE). Для основной программы тот же стек весьма вероятен, однако без ее EXE нельзя доказать точную среду сборки, язык всего приложения и версию компилятора.
Для нового интерфейса уже достаточно данных, чтобы сделать поиск по справочникам, учебным планам и занятиям. Надежный первый этап — веб-просмотр отдельной выгрузки в SQLite/UTF-8. Для полноценного календаря и обратной записи сначала необходимо восстановить смысл кодов дня/недели и операций сохранения.
Что особенно важно учесть§
- Скриншоты календаря показывают 2–14 сентября 2024 года, хотя каталог называется
1_sem_2026_2027. В названиях потоков тоже сохранились прошлые учебные годы. Связь скриншотов с текущей копией нужно подтвердить. DayNoв занятиях принимает значения до 299. Это не простой внешний ключ на шесть строкDAYS.DB. У всех непустых значений остатокDayNo % 14находится в диапазоне 0–5; полное правило перевода в дату пока не доказано.- У занятия может не быть прямой группы: 3 458 строк имеют
GroupNo=-1. Состав групп восстанавливается черезPlanNo → GRPPLAN, с учетом подгрупп и вида занятия. ClassesInf.DBиCLASSINF.DB— две разные таблицы. Первая содержит вспомогательное представление позиций, вторая — пустую таблицу дополнительных связей занятия с аудиторией/преподавателем.- В
ClassesInf.DBзаголовок объявляет 15 124 строки, а цепочка активных блоков содержит 15 111. pxlib подтверждает это расхождение. В одной позиции аудитория отличается отClasses.DB. Эту таблицу нельзя безусловно считать независимым актуальным расписанием. - В текстовых
.datвместо русских букв уже записаны#. Это утрата символов, а не выбор неправильной кодировки при просмотре. Для переноса названий нужно читать.DB. - У двух кафедр указаны отсутствующие факультеты (ID 46 и 48); 2 339 записей
Assigned=Trueне имеют аудитории. Первое — несогласованная ссылка, второе требует проверки правил назначенности. - В проекте подготовлены JSON и SQLite для исследования. Исходные файлы не изменялись; совпадение SHA-256 до и после экспорта проверено для всех 65 файлов каталога семестра.
2. Что подтверждено, а что еще предстоит проверить§
В отчете используются три уровня доказательности:
| Уровень | Что означает | Примеры |
|---|---|---|
| Подтверждено файлами | Прочитаны поля, байты, значения, связи, заголовки или ресурсы EXE | Paradox, CP866, количество строк, ключи, поля PlanNo и TeacherNo |
| Видно в интерфейсе | Есть подписанная команда, форма или поле на скриншоте | «Сменить Аудиторию», «Стабильное», список неназначенных занятий |
| Интерпретация | Обоснованная гипотеза, которую нельзя считать проверенным поведением | Алгоритм автосоставления, точный смысл Stable, действие «Отдать на кафедру» |
Изображение кнопки подтверждает наличие предусмотренной команды, но не ее успешное выполнение. Существование поля ограничения подтверждает хранение ограничений, но не доказывает, что программа проверяет их во всех сценариях. Таблицы позволяют восстановить структуру данных гораздо увереннее, чем алгоритмы редактирования.
В исходном наборе не обнаружены основной EXE, исходники .pas/.dpr/.dfm, установщик BDE, руководство пользователя, конфигурация начала семестра, API или журнал изменений. Отсутствие этих файлов именно в переданной папке не означает, что их нет в рабочей установке.
3. Архитектура системы§
Логически систему удобно разделить на пять частей:
| Часть | Основные данные | Роль |
|---|---|---|
| Организация учебного процесса | Факультеты, кафедры, курсы, группы, преподаватели | Определяет участников и организационные связи |
| Ресурсы | Аудитории, дни, начала занятий | Задает помещения и временную сетку |
| Учебная потребность | Дисциплины, записи плана, виды/объем нагрузки, группы плана | Определяет, что требуется провести и для кого |
| Размещение | Занятия, преподаватель, аудитория, код дня, время, признаки недель | Представляет расписанные и неназначенные элементы |
| Ограничения и обслуживание | Запреты преподавателей/аудиторий, индексы, вспомогательные таблицы | Поддерживает проверку и работу файловой БД |
Путь от дисциплины к расписанию выглядит так:
SUBJECTS (дисциплина)
└─ Plan (позиция учебного плана + кафедра + Stable)
├─ PLANITEM (вид занятия + объем + деление на подгруппы)
├─ GRPPLAN → GROUPS (участвующие группы и подгруппы)
├─ PLANROOM → Rooms (набор аудиторий плана; здесь пуст)
└─ Classes (экземпляры/элементы занятий)
├─ TEACHERS
├─ Rooms
└─ DayNo + TimeNo + EachWeek + OddWeek + Assigned
Объект Plan нельзя отождествлять с дисциплиной: одна дисциплина может входить в несколько позиций плана. Объект Classes нельзя отождествлять с записью плана: одной учебной потребности соответствуют несколько элементов расписания. Названия не являются ключами — связи строятся по числовым идентификаторам.
Физический уровень§
База состоит из файлов в каталоге. В исследованном снимке нет признаков отдельного серверного хранилища вроде PostgreSQL или SQL Server. Связанная утилита использует компоненты TTable, TQuery, TDatabase и TSession; в ее ресурсах сохранены DriverName=STANDARD, DatabaseName=ScheduniDB и названия таблиц.
TTable — компонент доступа к таблицам через BDE; документация производителя прямо указывает поддержку Paradox и локальных файловых таблиц. Это согласуется с найденными ресурсами. Документация Embarcadero: TTable.
Файлы .LCK в каталоге DB относятся к блокировкам окружения Paradox/BDE. Их наличие в копии не позволяет определить, кто сейчас держит базу открытой, и не доказывает сетевой режим работы. Для воспроизведения рабочего окружения потребуется проверить параметры BDE, рабочий и сетевой каталоги в установленной программе.
Формат таблиц§
Заголовки показывают форматы Paradox уровня 4, 5 и 7: DAYS.DB и TIMES.DB имеют идентификатор формата 9, большинство таблиц — 11, Courses.DB — 12. Это версии формата файлов, а не версии приложения или Delphi. Во всех 19 таблицах в заголовке указана кодовая страница 866.
Используются поля фиксированной длины: Alpha, Short, Long, AutoIncrement, Logical. В найденных схемах нет дат, вещественных чисел и BLOB-полей; даты расписания, следовательно, нельзя просто прочитать из колонки типа Date. Заголовки и записи прочитаны с учетом цепочки активных блоков, а не поиском похожих байтов по всему файлу: свободные блоки могут хранить остатки старых записей. Структура сверена с исходниками pxlib.
4. Карта основных таблиц§
| Файл | Прочитано строк | Для чего нужен |
|---|---|---|
FACULTY.DB |
6 | Названия факультетов/организационных подразделений |
CHAIRS.DB |
47 | Кафедры и принадлежность факультету |
Courses.DB |
12 | Классификатор курсов/уровней обучения |
GROUPS.DB |
554 | Группы, факультет, курс, численность и число подгрупп |
TEACHERS.DB |
866 | Преподаватели, кафедра, степень, должность, звание, заметки |
SUBJECTS.DB |
5 068 | Полные и краткие названия дисциплин |
Rooms.DB |
184 | Аудитории, вместимость, тип, кафедра и заметки |
DAYS.DB |
6 | Понедельник–суббота, коды 0–5 |
TIMES.DB |
8 | Номера слотов 1–8 и время начала |
STREAMS.DB |
140 | Именованный справочник потоков/периодов |
Plan.DB |
4 748 | Учебная потребность по дисциплине и кафедре |
PLANITEM.DB |
7 098 | Виды и объем занятий для позиции плана |
GRPPLAN.DB |
21 419 | Связи позиции плана с группами и подгруппами |
PLANROOM.DB |
0 | Связи плана/вида занятия с аудиториями; механизм не заполнен в снимке |
Classes.DB |
15 111 | Основные записи занятий и их размещение |
CLASSINF.DB |
0 | Дополнительные сведения занятия: аудитория и преподаватель |
ClassesInf.DB |
15 111 | Вспомогательные позиции и Stable; заголовок указывает 15 124 |
TCHRRSTR.DB |
4 541 | Ограничения преподавателей по дню, времени и варианту недели |
ROOMRSTR.DB |
990 | Ограничения аудиторий по дню, времени и варианту недели |
Точные имена, типы, размеры и первичные ключи всех полей приведены в словаре данных ниже. Пустая таблица описывает предусмотренную структуру, но не доказывает применение соответствующего механизма в текущем расписании.
5. Как связаны группы, планы и занятия§
Прямая группа и группа через план§
У Classes есть GroupNo и Subgroup, но не все занятия привязаны к группе этим полем. В 3 458 строках GroupNo=-1; они относятся к типам л и э, имеют Subgroup=-1, а соответствующие позиции PLANITEM не разделены по подгруппам. Для них участники определяются через GRPPLAN по PlanNo. Часть таких планов содержит всего одну группу: значение -1 само по себе не означает обязательно несколько групп.
GRPPLAN имеет составной ключ (GroupNo, Subgroup, PlanNo). Одна группа может встречаться в одном плане несколько раз — для разных подгрупп. Поэтому список групп для общего занятия нужно получать с устранением повторов по GroupNo, сохраняя отдельно состав подгрупп. Суммирование NStudents по всем строкам GRPPLAN завысит численность.
Для занятий с конкретными GroupNo и Subgroup эти поля нужно учитывать вместе с PLANITEM.GrpSplit. Универсальный запрос, присоединяющий все группы плана ко всем занятиям без учета вида и деления, может приписать занятию лишние группы. В подготовленной SQLite есть отдельные представления прямых данных занятия и членства в плане; они намеренно не скрывают эту особенность.
Два значения слова «поток»§
Есть справочник STREAMS и поле GROUPS.StreamNo. Но у всех 554 групп в этой копии StreamNo=-1: действующей положительной привязки к 140 строкам справочника нет. Одновременно группы реально объединяются через GRPPLAN. Поэтому поле «Поток» в учебном плане и окно «Потоки» нельзя заранее считать одним и тем же механизмом. Разница видна и на экране плана, и в окне потоков.
Курс, идентификаторы и служебные значения§
CourseNo — ключ классификатора, а не обязательно номер года обучения. Например, 6 соответствует «1-й курс магистратуры», а 8 — «6-й курс». Для отображения нужен Courses.CourseName. Поле CourseCount у всех 12 записей равно CourseNo, поэтому его тоже нельзя считать фактическим годом обучения. Назначение этой числовой колонки требует проверки программы.
Значения NULL, 0, -1 нельзя автоматически объединять. Они встречаются в разных полях с разным назначением. В частности, GROUPS.StreamNo=-1 и Classes.GroupNo=-1 — разные контексты. Не следует создавать фиктивные справочные записи с такими ключами только ради формального внешнего ключа.
6. Временная модель и статусы§
Дни и недели§
DAYS.DB содержит коды 0–5. В TCHRRSTR и ROOMRSTR день действительно лежит в этом диапазоне, а Week принимает 0 или 1. В Classes.DayNo обнаружены 72 различных непустых кода от 0 до 299 и NULL; у всех непустых кодов DayNo % 14 лежит между 0 и 5. Значения согласуются с некоторым кодированием периода с шагом 14, но этого недостаточно для восстановления календаря.
Предположение для дальнейшего эксперимента: DayNo // 14 может обозначать номер двухнедельного периода, DayNo % 14 — день, а OddWeek — один из вариантов недели. Это не утвержденная формула. Не определены точка отсчета, нумерация первого периода, правило EachWeek, приоритет флагов и смысл неназначенных записей с оставшейся позицией. В интерфейсе рядом с днем действительно показаны две даты через дефис, но назначение такого отображения нужно подтвердить настройками.
В новом интерфейсе до проверки следует показывать исходный код DayNo и признаки недель. Производную дату стоит оставлять незаполненной. Нельзя выбирать 1 сентября 2026 года только по имени папки или подменять код дня остатком от деления на 7.
Назначенные и неназначенные§
| Показатель | Строк |
|---|---|
Assigned=True |
11 530 |
Assigned=False |
3 581 |
Assigned=False и позиция DayNo/TimeNo/OddWeek заполнена |
288 |
DayNo/TimeNo/OddWeek не заполнены |
3 293 |
EachWeek=True |
23 |
EachWeek=False |
15 088 |
Таким образом, неназначенность не равна отсутствию всех координат. При построении списка следует фильтровать именно по Assigned, а оставшиеся поля показывать как исходные значения. Возможное объяснение — сохранение прежней позиции после отмены или промежуточное состояние; по снимку это не доказано.
Виды занятий и помещений§
В Classes.PlanType найдены шесть кириллических кодов: с — 10 573 строки, л — 3 258, п — 621, з — 358, э — 200, к — 101. По полям учебного плана наиболее вероятное соответствие: лекция л, практика/семинар с, лабораторная работа п, зачет з, экзамен э, консультация к. Особенно важно проверить различие с и п на одной сохраненной записи: буквенного кода самого по себе недостаточно. В прототипе просмотра разумно показывать код рядом с предположительным названием.
Rooms.RoomType использует с (77), л (63), п (40), к (4). Это отдельный классификатор: к для помещения, вероятно, компьютерный класс, а в занятиях — предположительно консультация. RoomSpec=False во всех 184 строках; смысл этого поля по данным не раскрывается. На экране поиска есть и вариант «Лингафонный кабинет», которого среди четырех наблюдаемых кодов нельзя автоматически идентифицировать.
Звонки и продолжительность§
Время хранится строками: 8:00, 9:40, 11:25, 13:20, 15:05, 16:50, 18:30, 20:05. В таблице нет времени окончания. Разность соседних начал включает перерывы и не определяет длительность занятия. PlanQty — числовой объем, а интерфейс называет поля часами; соотношение академического часа, пары, повторений и элементов Classes требует проверки.
Признак Stable§
Plan.Stable=True у 3 738 позиций, False у 1 010. В ClassesInf этот признак совпадает с Plan.Stable по PlanNo для всех 15 111 записей. Это подтверждает передачу признака от плана, но не раскрывает его действие. Нельзя автоматически трактовать его как запрет переноса или как проведенное занятие.
7. Навигатор по интерфейсу§
Начинать знакомство удобнее со справочников, затем перейти к учебному плану и только после этого к сетке расписания.
| Задача | Где искать | Файлы | Скриншот |
|---|---|---|---|
| Найти группу, численность и подгруппы | Справочники → Группы | GROUPS, FACULTY, Courses |
3 |
| Узнать кафедру и сведения преподавателя | Справочники → Преподаватели | TEACHERS, CHAIRS |
4 |
| Посмотреть дисциплины и сокращения | Справочники → Дисциплины | SUBJECTS |
5 |
| Найти аудиторию, тип и вместимость | Справочники → Аудитории | Rooms, CHAIRS |
6 |
| Разобраться в подразделениях | Справочники → Кафедры / Факультеты | CHAIRS, FACULTY |
7, 8 |
| Узнать нагрузку и состав групп по дисциплине | Справочники → Учебный план | Plan, PLANITEM, GRPPLAN, SUBJECTS |
9 |
| Проверить обозначения курсов | Справочники → Курсы | Courses |
10 |
| Посмотреть именованные потоки | Справочники → Потоки | STREAMS, предполагаемая связь с GROUPS |
11 |
| Узнать начала занятий | Справочники → Звонки | TIMES |
12 |
| Найти свободную аудиторию | Расписание → Поиск свободной аудитории | Rooms, Classes, ROOMRSTR, TIMES — ожидаемые источники |
13 |
| Посмотреть общую сетку и неназначенные занятия | Расписание → Основной вид, вероятный переход | Classes и справочники |
14 |
| Перенести занятие, сменить аудиторию/преподавателя | Контекстное меню занятия | Прежде всего Classes; полный набор изменяемых файлов не установлен |
15 |
Меню «Расписание» также содержит «База данных» и «Параметры…», а главное меню — «Помощь». Их окна не представлены. Нельзя подтвердить выбор семестра, импорт, резервное копирование, печать, экспорт в Excel/HTML/XML, автоматическое составление или разграничение прав только по этим названиям.
Сетка позволяет наблюдать выбор недели, группы по колонкам, занятия по дням и временным позициям, всплывающие сведения и список «Не назначены». Контекстное меню предусматривает отмену, перестановку, смену аудитории, замену преподавателя, передачу «на кафедру», переходы к расписаниям и комментарий. Семантика «Отменить» и «Отдать на кафедру» требует отдельного опыта: это может быть изменение статуса, а не удаление записи.
Полный каталог из 59 видимых или предполагаемых интерфейсных возможностей приведен далее. Он не является перечнем 59 выполненных тестов.
8. Служебные и обменные файлы§
Индексы и семейства§
.PX — первичный индекс, пары .XG0/.YG0 и .XG1/.YG1 — вторичные индексы и их индексные структуры. Они нужны старому движку для порядка доступа и поиска. Их не нужно превращать в самостоятельные бизнес-таблицы современного интерфейса. Такое назначение расширений описано в руководстве Corel, раздел Paradox, печатная стр. 748.
В папке действительно 19 .PX, однако соответствие не один к одному: у ClassesInf.DB первичного ключа и одноименного .PX нет; присутствует LOAD.PX, хотя LOAD.DB отсутствует. LOAD.FAM и LOAD.TV содержат ссылки на CLASSES. Это исторические служебные следы, а не доказательство утраты необходимой таблицы нагрузки.
Внутренние имена некоторых .DB — resttemp.DB, у TIMES.DB — TIME.DB. Идентифицировать актуальную таблицу следует по внешнему имени и схеме. Внутреннее старое имя не является основанием переименовывать файлы.
Текстовый обмен§
| Пара | Строк в DAT | Строк в одноименной DB | Содержимое |
|---|---|---|---|
chairs.dat + chairs.sch |
44 | 47 | Кафедры и факультет |
groups.dat + groups.sch |
348 | 554 | Группы, курс, численность, подгруппы |
rooms.dat + rooms.sch |
185 | 184 | Аудитории, вместимость, тип |
subjects.dat + subjects.sch |
1 995 | 5 068 | Названия дисциплин и сокращения |
teachers.dat + teachers.sch |
779 | 866 | Преподаватели и квалификация |
Каждая .sch задает Filetype=Fixed, длины и смещения текстовых полей. .dat состоят из фиксированных строк с разделителями |, концами CRLF и финальным байтом DOS EOF 0x1A. Проверены длины всех записей. .sch здесь означает схему обмена, а не готовое расписание.
Различия количества строк и утрата кириллицы показывают, что .dat нельзя использовать как полную актуальную копию .DB. Некоторые поля обмена даже имеют другие длины и имена. Точные смещения приведены в исследовании обменных файлов.
Прочие файлы§
DBDWORK.INI содержит только CRLF, настройки семестра в нем отсутствуют. Groups.VAL относится к правилам допустимости значений и содержит исторический путь к resttemp.DB; сами правила в этом исследовании не декодированы. LOAD.TV хранит параметры табличного представления, имена полей и шрифт. LOAD.FAM описывает семейство связанных файлов. Старые абсолютные пути внутри них не следует принимать за текущие пути установки.
9. Reorder.EXE и установленный технологический стек§
Reorder.EXE — PE32 GUI x86 размером 622 592 байта. Внутри найдены строки Delphi RTL, Borland, idapi32.DLL, TBDEDataSet, компоненты VCL и бинарные DFM-ресурсы. Основная форма имеет заголовок «Перестановка групп», кнопки «Группы», «Аудитории», перемещение вверх/вниз и «Сохранить»; список поддерживает множественное выделение.
Утилита обращается к CLASSES.DB, GRPPLAN.DB, GROUPS.DB, ROOMS.DB, ROOMRSTR.DB. Предположительно она меняет порядок групп/аудиторий с обновлением связанных ключей. Алгоритм сохранения не выполнялся. В бинарнике присутствует SQL delete from Rooms, поэтому запускать его как просмотрщик на рабочей базе было бы неправильно: это средство изменения данных.
| Технология/свойство | Степень подтверждения |
|---|---|
| Windows x86, PE32, графическая программа | Прямо установлено по заголовку утилиты |
| Paradox, файловое хранение | Прямо установлено по 19 таблицам и индексам |
| CP866 | Указано в заголовках, корректно декодирует русские данные |
| Delphi RTL, VCL, BDE | Прямые строки, компоненты и ресурсы утилиты |
| Object Pascal как язык исходников | Высокая вероятность по совокупности признаков; исходников нет |
| Тот же стек у главной программы | Вероятно; ее EXE не представлен |
| Конкретная версия Delphi/BDE | Не установлена |
| Автоматический оптимизатор расписания, его алгоритм | Не установлен |
| API, серверная часть, веб-технологии исходной системы | В предоставленных файлах не обнаружены |
| Авторизация, роли, журнал действий | Не подтверждены; библиотечные формы входа не доказывают их наличие |
Timestamp EXE формально указывает 1992 год, но противоречит внутренним строкам copyright 1999 и признакам Delphi. Датировать программу по нему нельзя. Подробные байтовые смещения и восстановленные ресурсы сохранены в статическом исследовании и машинном протоколе (локальный материал).
BDE остается технологией совместимости; производитель не рекомендует начинать на ней новую разработку. Это аргумент в пользу отдельного современного слоя просмотра, сохраняя BDE только для возможного моста к старой программе. Embarcadero: Using Databases.
10. Как сделать небольшой веб-интерфейс§
Предлагаемая схема§
Закрытая/согласованная копия каталога Paradox
↓ чтение, CP866 → Unicode, проверка ключей и счетчиков
SQLite + сведения о происхождении + протокол аномалий
↓ сервер только чтения: выборка, поиск, пагинация
Браузер: справочники → планы → занятия → связанные объекты
Для первого варианта достаточно Python и SQLite на сервере, обычного HTML/CSS/JavaScript в браузере. React или отдельная серверная СУБД не обязательны для этого объема и одного снимка. Если появятся одновременное редактирование, несколько семестров и журнал операций, можно перейти к PostgreSQL и полноценному сервису изменений. Это предлагаемая архитектура нового инструмента, а не установленный стек старого приложения.
Веб-браузер не читает Paradox средствами обычного SQL-драйвера. Извлечение выполняется отдельным конвертером или сервером. В этой работе подготовлен небольшой читатель на стандартной библиотеке Python именно для обнаруженных типов полей; дополнительно использована независимая библиотека pxlib для проверки результата. Универсальной поддержки всех файлов Paradox у этого читателя нет.
Страницы первого этапа§
| Раздел | Содержание и действия просмотра | Что требуется для готовности |
|---|---|---|
| Карта данных | 19 таблиц, счетчики, поля, предупреждения, происхождение | Уже извлечено |
| Группы | Поиск по обозначению, факультету, курсу; численность; планы | Уже извлечено |
| Преподаватели | Поиск, кафедра, занятия и ограничения | Уже извлечено |
| Аудитории | Поиск, вместимость, тип, занятия и ограничения | Уже извлечено |
| Учебный план | Дисциплина, кафедра, виды нагрузки, группы/подгруппы | Уже извлечено |
| Занятия | Таблица, поиск по дисциплине/преподавателю/аудитории, исходные статусы | Уже извлечено |
| Неназначенные | Фильтр Assigned=False, отображение оставшихся координат |
Уже извлечено |
| Календарь | Недели, даты, чередование, повторение | Нужна проверенная временная модель |
| Свободные аудитории | Тип, вместимость, занятость и ограничения | Нужны временная модель и правила совместимости |
| Качество данных | Несовпадения ссылок/счетчиков, устаревшие вспомогательные записи | Протокол подготовлен |
Карточки должны переходить друг в друга по идентификаторам. Для каждой записи полезно показывать исходную таблицу и ключ; это позволит сверять новый просмотрщик с оригиналом. В пользовательских списках основными подписями остаются понятные названия.
Предлагаемые API-операции§
Это контракт для будущей реализации, а не обнаруженные эндпоинты исходной системы:
| Метод и путь | Назначение |
|---|---|
GET /api/meta |
Дата снимка, счетчики, предупреждения и версии формата |
GET /api/groups?q=&faculty_id=&course_id=&offset=&limit= |
Поиск групп |
GET /api/groups/{id} |
Карточка группы |
GET /api/groups/{id}/plans |
Позиции плана группы с подгруппами |
GET /api/teachers?q=&chair_id= |
Преподаватели |
GET /api/rooms?q=&min_capacity=&type= |
Аудитории |
GET /api/plans/{id} |
План, виды нагрузки, группы и занятия |
GET /api/classes?teacher_id=&room_id=&assigned=&offset=&limit= |
Занятия с прямыми связями |
GET /api/restrictions?resource_type=&resource_id= |
Исходные ограничения |
На стороне сервера следует использовать параметры SQL и белый список полей сортировки. В браузере названия и заметки нужно выводить как текст (textContent), поскольку в данных уже встречается буквальная строка . Автоматически интерпретировать содержимое как HTML или исправлять строки в исходной базе не нужно.
Для SQLite соединение открывается через URI с mode=ro. Пагинация ограничивает объем ответа. Обновление снимка производится отдельной командой экспорта с атомарной заменой готовой SQLite; браузер не должен запускать переписывание Paradox. В предоставленных свободных текстах встречаются служебные заметки и реквизиты дистанционных занятий, поэтому публичный режим следует строить на отдельном явно выбранном наборе полей.
Что нельзя корректно обещать на первом этапе§
Нельзя выдавать за готовую функцию календарь с точными датами, поиск конфликтов по фактическому времени, расчет свободных аудиторий и обратную запись, пока не проверены правила недель и сохранения. Простой фильтр по совпавшим DayNo и TimeNo способен дать кандидатов на пересечение, но не окончательный список конфликтов: нужны четность, повторение, подгруппы, потоки и разрешенные совмещенные занятия.
11. Что уже можно проверить на этой копии§
Подготовлены SQLite с данными (локальный материал), схема JSON (локальный материал) и отдельный JSON для каждой таблицы. Это производные артефакты; оригинальные .DB остались в своем каталоге. SQLite содержит 19 исходных таблиц, служебную _source_manifest и два представления: class_details и plan_group_membership.
Экспорт повторяется из корня проекта:
python3 tools/export_data.py --allow-count-mismatch
Параметр явно разрешает экспорт доступных строк при известном несовпадении счетчика ClassesInf.DB. Без него программа останавливается на этом расхождении. Она не исправляет заголовок и не создает записи по завышенному счетчику; фактическая утрата 13 записей не доказана.
Открыть SQLite для чтения можно стандартным клиентом SQLite или любым совместимым просмотрщиком. Примеры запросов:
-- Реальные счетчики.
SELECT COUNT(*) AS classes FROM Classes;
SELECT COUNT(*) AS groups_count FROM GROUPS;
-- Назначенность: 0 = False, 1 = True в SQLite.
SELECT Assigned, COUNT(*) AS qty
FROM Classes GROUP BY Assigned;
-- Список занятий без выдуманных календарных дат.
SELECT ClassNo, SubjectName, DirectGroupName,
TeacherName, RoomName, DayNo, TimeName,
Assigned, EachWeek, OddWeek
FROM class_details ORDER BY ClassNo LIMIT 30;
-- Найти группы текстом. :needle передается параметром, например '%МИН%'.
SELECT g.GroupNo, g.GroupName, c.CourseName, f.FacultyName,
g.NStudents, g.NSubgroups
FROM GROUPS g
LEFT JOIN Courses c ON c.CourseNo=g.CourseNo
LEFT JOIN FACULTY f ON f.FacultyNo=g.FacultyNo
WHERE g.GroupName LIKE :needle;
-- Участники конкретного плана без повторного подсчета групп.
SELECT DISTINCT GroupNo, GroupName
FROM plan_group_membership WHERE PlanNo=:plan_id;
-- Все занятия группы, включая общие занятия через план.
-- EXISTS не размножает строку из-за нескольких подгрупп в GRPPLAN.
SELECT c.* FROM class_details c
WHERE c.GroupNo=:group_id
OR (c.GroupNo=-1 AND EXISTS (
SELECT 1 FROM GRPPLAN gp
WHERE gp.PlanNo=c.PlanNo AND gp.GroupNo=:group_id
))
ORDER BY c.ClassNo;
-- Исходные ограничения аудитории: Week оставлен как исходный код.
SELECT RoomNo, DayNo, TimeNo, Week
FROM ROOMRSTR WHERE RoomNo=:room_id
ORDER BY Week, DayNo, TimeNo;
-- Проверить состояние вспомогательной таблицы.
SELECT file, metadata_json FROM _source_manifest
WHERE file='ClassesInf.DB';
Важно: SQLite LIKE по умолчанию не дает полноценного нечувствительного к регистру поиска по кириллице. Для веб-поиска стоит заранее вычислять нормализованную поисковую строку через Unicode casefold() или использовать подходящий механизм индексирования. Точные Unicode-правила для SQLite описаны в документации выражений SQLite.
В class_details.DirectGroupName может быть NULL при GroupNo=-1; это ожидаемое следствие прямого соединения. Представление не заменяет правила вычисления состава групп. SQLite сохраняет исходные 0/-1/NULL, не добавляет неподтвержденные FK и не переписывает поврежденные значения.
Запрос фильтра группы проверен для всех 554 групп против независимого раскрытия JSON: получено 17 727 пар «занятие–группа», без потерь, лишних записей и дублей. Физических занятий при этом 15 111, а 32 группы не имеют занятий. Протокол: group-query-validation.json (локальный материал).
12. Возможности редактирования и путь к совместимости§
Изменения в самой программе§
По интерфейсу предусмотрены карточки справочников, поля плана и команды переноса/замены в расписании. Для точного перечня доступных операций нужно проверить состояние кнопок и сохранение на тестовой копии. Добавление и удаление по неподписанным пиктограммам пока относятся к интерпретациям. Факультеты, курсы и звонки показаны таблицами; возможность редактирования этих экранов отдельно не доказана.
Изменения через новый веб-слой§
Есть два разных варианта развития:
| Вариант | Как работает | Что нужно восстановить |
|---|---|---|
| Совместимый редактор | Новый интерфейс передает операции Windows-посреднику, который работает через старый движок и проверенные правила | Сохранение исходной программы, индексы, вспомогательные таблицы, блокировки, валидация |
| Перенос системы | SQLite/PostgreSQL становится новой основной БД, функции расписания реализуются заново | Полная предметная модель, календарь, генерация, ограничения, пользовательские сценарии |
Непосредственно менять байты .DB с веб-сервера не следует. Даже изменение одного ID или аудитории может требовать синхронизации индексов и производных данных. На текущей копии уже видна разница между Classes и ClassesInf, а Reorder.EXE содержит обращения к нескольким таблицам, включая SQL удаления. Фактическая последовательность его сохранения не выполнялась.
Минимальная единица будущего редактирования — понятная операция: «перенести занятие», «заменить преподавателя», «изменить участников плана», а не произвольный SQL UPDATE. Для нее нужны проверка ожидаемой версии записи, проверка ограничений, согласованное сохранение, журнал до/после и возможность отмены. Если базу продолжит менять оригинальная программа, новый слой должен учитывать параллельные изменения и не перетирать их устаревшим снимком.
Проверка поведения на тестовой копии§
| Эксперимент | Что наблюдать в интерфейсе | Что сравнить в файлах |
|---|---|---|
| Открыть копию и закрыть без действий | Ошибки, выбранный период | Меняются ли счетчики/вспомогательные таблицы сами |
| Изменить одну подпись группы | Видимое имя в списке и сетке | GROUPS, индексы, неизменность ключа |
| Перенести одно занятие в пределах недели | Старое/новое положение | Classes, ClassesInf, DayNo, TimeNo |
| Перенести между четной/нечетной и следующей парой недель | Выбор недели и даты | Кодирование DayNo, OddWeek, EachWeek |
| Отменить назначение | Переход в «Не назначены» | Assigned, сохранение старых координат |
| Сменить аудиторию/преподавателя | Новые сведения занятия | Основные и дополнительные связи, ограничения |
| Изменить Stable у одной позиции | Доступность переноса, отображение | Plan, ClassesInf, другие связанные строки |
| Изменить объем/деление нагрузки | Число элементов и список подгрупп | PLANITEM, GRPPLAN, генерация Classes |
| Открыть «База данных» и «Параметры» | Начало семестра, пути, периоды | Конфигурация вне каталога данных |
| Создать заведомое пересечение на копии | Запрет, предупреждение или разрешение | Какие виды ограничений реально проверяются |
Нужно сравнивать нормализованные записи, а не только бинарные размеры: индексы и служебные счетчики могут изменяться без изменения пользовательских данных. Для каждого опыта следует начинать с отдельной копии одного и того же состояния. Эти эксперименты пока не выполнялись.
13. Воспроизводимость и результаты проверки§
| Проверка | Результат |
|---|---|
Чтение схем всех .DB |
19 схем, известные типы, размеры полей согласованы с размером записи |
| Проверка цепочек блоков | Пройдены ссылки вперед/назад, границы, количество записей |
| Счетчики в заголовках | Совпадают у 18 таблиц; расхождение 13 у ClassesInf.DB |
| Независимое чтение pxlib | Все 75 909 доступных записей совпали как мультимножества после нормализации пустых строк и NULL |
| Пустое числовое значение в pxlib | В пяти CHAIRS.FacultyNo pxlib возвращает -2147483648; нормализовано в NULL согласно формату |
| Первичные ключи в SQLite | Таблицы созданы с ключами из заголовков; загрузка не выявила нарушения этих ключей |
PRAGMA integrity_check |
ok |
Соединение class_details |
15 111 строк, соединения не размножили записи занятий |
| Фильтр расписания группы | Совпадение с независимым раскрытием JSON для всех 554 групп; 17 727 пар «занятие–группа» |
| Целостность исходных файлов | SHA-256 всех 65 файлов каталога семестра совпали до и после экспорта |
| Проверка всех пяти DAT | Длины записей и позиции разделителей соответствуют SCH |
| Просмотр скриншотов | Все 15 просмотрены, функции привязаны к файлам |
| Запуск оригинальной программы и запись Paradox | Не выполнялись |
Проверка через pxlib проводилась на временных копиях. Установленный пакет pypxlib 2.5 содержит библиотеку macOS x86_64; на этом Mac он проверен через arch -x86_64 python3. Рабочий экспортер от pypxlib не зависит и выполняется обычным Python 3.11. Протокол сравнения: pxlib-validation.json (локальный материал); библиотека сравнения: pypxlib.
Читатель tools/paradox_read.py рассчитан на нешифрованные .DB с обнаруженными типами и уровнями формата. Он не разбирает .VAL, не проверяет согласованность записей всех .PX/.XG/.YG, не восстанавливает удаленные записи и не умеет сохранять Paradox. Флаг разрешения несовпадающего счетчика не отключает проверки границ и структуры блоков.
14. Какие дополнительные материалы дадут наибольший эффект§
Для текущего описания и просмотра извлеченных данных дополнительная информация не обязательна. Для проверки программы и редактора наиболее полезны:
- Основной EXE вместе с каталогом установки, версия из «О программе» и, если сохранились, исходники Delphi.
- Скриншоты окон «Параметры», «База данных», настроек периода и выбора недели.
- Подтверждение, к какому состоянию базы относятся изображения сентября 2024 года, и известная фактическая дата одного занятия из переданной копии.
- Две копии базы до и после одного контролируемого переноса занятия и смены четности недели.
- Пояснение, что оператор понимает под «Стабильное», «Отдать на кафедру», «Отменить», «час» и «поток».
- Приоритет следующего этапа: просмотр/поиск или запись изменений с сохранением работы старой программы.
Эти материалы позволят перейти от восстановленной структуры к проверенному описанию бизнес-алгоритмов. Уже сейчас карту файлов, справочники, планы и исходные позиции можно исследовать через подготовленную SQLite.
15. Конкретные вопросы качества данных§
| Наблюдение | Значение для интерпретации | Следующий шаг |
|---|---|---|
| ClassesInf: 15 124 в заголовке, 15 111 в активных блоках | Счетчик не согласован с доступными записями; это подтвердили два читателя | Проверить открытие/закрытие на копии; не придумывать недостающие строки |
| Одна аудитория расходится между Classes и ClassesInf | PlanNo=226555, DayNo=16, TimeNo=3, OddWeek=True: 10141 против 10151 | Сверить с оригинальным приложением, какой источник оно показывает |
| Две CHAIRS.FacultyNo ссылаются на отсутствующие ID 46 и 48 | Нарушена предполагаемая связь с факультетами | Уточнить правильные подразделения; до этого LEFT JOIN и явное предупреждение |
| Пять CHAIRS.FacultyNo равны NULL | Подразделение не задано | Сохранять отсутствие значения, не приписывать факультет |
| 2 339 Assigned=True без аудитории; 23 из них без преподавателя | Назначенность не равна полной укомплектованности ресурсов | Отдельно показывать оба признака; не называть все случаи ошибками |
| Все 554 GROUPS.StreamNo=-1 | Именованный справочник потоков фактически не связан с группами | Состав занятий брать через GRPPLAN |
| 5 068 дисциплин, 5 028 различных названий | Совпадение названий не означает одинаковый объект | Соединять по SubjectNo |
| 47 кафедр, 33 различных названия | Есть совпадения/служебные обозначения | Соединять по ChairNo |
| Буквальное в названиях | Служебная HTML-последовательность стала текстом | Отображать безопасно; исправлять только после предметной сверки |
| DAT существенно отличаются от DB и потеряли кириллицу | Обменные файлы не являются актуальной полной копией | Основной источник — DB |
Все положительные ссылки основного плана, групп, элементов нагрузки и занятий, кроме двух указанных связей кафедр, найдены в ожидаемых справочниках. Все 15 111 пар (PlanNo, PlanType) занятий существуют в PLANITEM. Все явные группы/подгруппы занятий входят в соответствующие GRPPLAN; номера подгрупп укладываются в число подгрупп группы.
1 674 позиции плана связаны с несколькими группами, максимум — с 21. Всего 4 748 позиций имеют хотя бы одну группу. Без ссылок из других выгруженных таблиц остаются 4 066 дисциплин, 82 преподавателя, 19 аудиторий, 32 группы и 140 потоков. Это может быть исторический запас справочников; эти строки не удалялись и не объявляются лишними.
Подробные агрегаты и методика: анализ связей, машинные метрики (локальный материал).
Приложение A. Полный словарь 88 полей§
Типы, размеры и порядок ключей прочитаны из заголовков файлов. Описания назначения восстановлены по именам, значениям и интерфейсу; неоднозначные поля отмечены. Столбец PK отражает первичный ключ формата, а не обязательность всех прочих полей. Правила .VAL отдельно не восстановлены.
Alpha — строка фиксированной длины в байтах CP866; Short — знаковое 16-битное число; Long и AutoIncrement — 32-битные числа; Logical — логическое значение с возможным NULL. Пустой Alpha в экспорте представлен пустой строкой, логические значения в JSON — true/false/null, в SQLite — 1/0/NULL. Размер в UTF-8 может быть больше исходного байтового лимита.
A. CHAIRS.DB — Кафедры и принадлежность факультету§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 47; счетчик заголовка: 47; ключ: ChairNo. Формат Paradox 5, кодировка cp866, размер записи 58 байт. Внутреннее имя: CHAIRS.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
ChairNo |
AutoIncrement / 4 | Да | Идентификатор кафедры; ссылка на CHAIRS вне самой CHAIRS. Служебные 0/-1 зависят от таблицы. | NULL: 0; диапазон: 464…521 |
ChairName |
Alpha / 50 | — | Название кафедры; не уникальный ключ. | Пустых: 0; различных: 33; макс. длина: 27 |
FacultyNo |
Long / 4 | — | Идентификатор факультета; ссылка на FACULTY. В CHAIRS есть NULL и две отсутствующие положительные ссылки. | NULL: 5; диапазон: 46…57 |
A. CLASSINF.DB — Дополнительные ресурсы занятия; таблица пуста§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 0; счетчик заголовка: 0; ключ: ClassNo, RoomNo. Формат Paradox 5, кодировка cp866, размер записи 12 байт. Внутреннее имя: CLASSINF.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
ClassNo |
Long / 4 | Да | Идентификатор занятия; ключ Classes, ссылка из CLASSINF. | Таблица пуста |
RoomNo |
Long / 4 | Да | Идентификатор аудитории; ссылка на Rooms. В Classes значение -1 означает отсутствие указанной аудитории. | Таблица пуста |
TeacherNo |
Long / 4 | — | Идентификатор преподавателя; ссылка на TEACHERS. В Classes значение -1 означает отсутствие указанного преподавателя. | Таблица пуста |
A. Classes.DB — Основные записи занятий§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 15111; счетчик заголовка: 15111; ключ: ClassNo. Формат Paradox 5, кодировка cp866, размер записи 94 байт. Внутреннее имя: Classes.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
ClassNo |
AutoIncrement / 4 | Да | Идентификатор занятия; ключ Classes, ссылка из CLASSINF. | NULL: 0; диапазон: 710248…732032 |
GroupNo |
Long / 4 | — | Идентификатор группы; ссылка на GROUPS. В Classes при -1 состав определяется через GRPPLAN. | NULL: 0; диапазон: -1…434159 |
Subgroup |
Short / 2 | — | Номер подгруппы. В GRPPLAN 1–5; в Classes также -1 без конкретной подгруппы. | NULL: 0; диапазон: -1…5 |
PlanNo |
Long / 4 | — | Идентификатор позиции плана; ссылка на Plan вне самой Plan. | NULL: 0; диапазон: 222250…229104 |
PlanType |
Alpha / 1 | — | Однобайтовый кириллический код вида занятия. Шесть кодов; точная расшифровка сверяется с программой. | Пустых: 0; различных: 6; макс. длина: 1 |
EachWeek |
Logical / 1 | — | Флаг, по имени — еженедельность. Приоритет над OddWeek и алгоритм повторения требуют проверки. | True: 23; False: 15088; NULL: 0 |
Assigned |
Logical / 1 | — | Флаг назначенности по имени и сопоставлению интерфейса. Не гарантирует наличие аудитории/преподавателя. | True: 11530; False: 3581; NULL: 0 |
OddWeek |
Logical / 1 | — | Флаг варианта недели, по имени — нечетная. NULL возможен без позиции; календарная привязка не установлена. | True: 6035; False: 5783; NULL: 3293 |
DayNo |
Short / 2 | — | В DAYS и ограничениях код дня 0–5; в Classes/ClassesInf составной код 0–299 или NULL, не прямой FK на DAYS. | NULL: 3293; диапазон: 0…299 |
TimeNo |
Short / 2 | — | Номер временной позиции TIMES (1–8); в занятиях возможен NULL. | NULL: 3293; диапазон: 1…8 |
TeacherNo |
Long / 4 | — | Идентификатор преподавателя; ссылка на TEACHERS. В Classes значение -1 означает отсутствие указанного преподавателя. | NULL: 0; диапазон: -1…47553 |
RoomNo |
Long / 4 | — | Идентификатор аудитории; ссылка на Rooms. В Classes значение -1 означает отсутствие указанной аудитории. | NULL: 0; диапазон: -1…10179 |
Comment |
Alpha / 64 | — | Текстовый комментарий занятия. Не использовать для восстановления ключей и состава групп. | Пустых: 12196; различных: 247; макс. длина: 64 |
A. ClassesInf.DB — Предположительно производные позиции расписания; есть рассогласование§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 15111; счетчик заголовка: 15124; ключ: не задан. Формат Paradox 5, кодировка cp866, размер записи 16 байт. Внутреннее имя: resttemp.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
PlanNo |
Long / 4 | — | Идентификатор позиции плана; ссылка на Plan вне самой Plan. | NULL: 0; диапазон: 222250…229104 |
RoomNo |
Long / 4 | — | Идентификатор аудитории; ссылка на Rooms. В Classes значение -1 означает отсутствие указанной аудитории. | NULL: 0; диапазон: -1…10179 |
EachWeek |
Logical / 1 | — | Флаг, по имени — еженедельность. Приоритет над OddWeek и алгоритм повторения требуют проверки. | True: 23; False: 15088; NULL: 0 |
OddWeek |
Logical / 1 | — | Флаг варианта недели, по имени — нечетная. NULL возможен без позиции; календарная привязка не установлена. | True: 6035; False: 5783; NULL: 3293 |
Assigned |
Logical / 1 | — | Флаг назначенности по имени и сопоставлению интерфейса. Не гарантирует наличие аудитории/преподавателя. | True: 11530; False: 3581; NULL: 0 |
DayNo |
Short / 2 | — | В DAYS и ограничениях код дня 0–5; в Classes/ClassesInf составной код 0–299 или NULL, не прямой FK на DAYS. | NULL: 3293; диапазон: 0…299 |
TimeNo |
Short / 2 | — | Номер временной позиции TIMES (1–8); в занятиях возможен NULL. | NULL: 3293; диапазон: 1…8 |
Stable |
Logical / 1 | — | Флаг «Стабильное» из плана; действие на редактирование/размещение не доказано. | True: 11491; False: 3620; NULL: 0 |
Предупреждение: Header declares 15124 rows; active block chain contains 15111.
A. Courses.DB — Классификатор курсов и уровней обучения§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 12; счетчик заголовка: 12; ключ: CourseNo. Формат Paradox 7, кодировка cp866, размер записи 261 байт. Внутреннее имя: Courses.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
CourseNo |
AutoIncrement / 4 | Да | Идентификатор записи Courses; не обязательно номер года обучения. | NULL: 0; диапазон: 1…12 |
CourseCount |
Short / 2 | — | Числовой атрибут классификатора. Во всех 12 строках равен CourseNo; не является надежным номером года обучения. Роль не установлена. | NULL: 0; диапазон: 1…12 |
CourseName |
Alpha / 255 | — | Отображаемое название курса, включая магистратуру/аспирантуру. | Пустых: 0; различных: 12; макс. длина: 21 |
A. DAYS.DB — Дни шестидневной недели§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 6; счетчик заголовка: 6; ключ: DayNo. Формат Paradox 4, кодировка cp866, размер записи 15 байт. Внутреннее имя: resttemp.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
DayNo |
Short / 2 | Да | В DAYS и ограничениях код дня 0–5; в Classes/ClassesInf составной код 0–299 или NULL, не прямой FK на DAYS. | NULL: 0; диапазон: 0…5 |
DayName |
Alpha / 11 | — | Полное название дня. | Пустых: 0; различных: 6; макс. длина: 11 |
ShortDayName |
Alpha / 2 | — | Краткое название дня для отображения. | Пустых: 0; различных: 6; макс. длина: 2 |
A. FACULTY.DB — Факультеты / организационные подразделения§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 6; счетчик заголовка: 6; ключ: FacultyNo. Формат Paradox 5, кодировка cp866, размер записи 36 байт. Внутреннее имя: FACULTY.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
FacultyNo |
AutoIncrement / 4 | Да | Идентификатор факультета; ссылка на FACULTY. В CHAIRS есть NULL и две отсутствующие положительные ссылки. | NULL: 0; диапазон: 52…57 |
FacultyName |
Alpha / 32 | — | Отображаемое название факультета/подразделения. | Пустых: 0; различных: 6; макс. длина: 4 |
A. GROUPS.DB — Учебные группы§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 554; счетчик заголовка: 554; ключ: GroupNo. Формат Paradox 5, кодировка cp866, размер записи 28 байт. Внутреннее имя: GROUPS.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
GroupNo |
AutoIncrement / 4 | Да | Идентификатор группы; ссылка на GROUPS. В Classes при -1 состав определяется через GRPPLAN. | NULL: 0; диапазон: 433604…434159 |
GroupName |
Alpha / 8 | — | Обозначение группы; для связи использовать GroupNo. | Пустых: 0; различных: 554; макс. длина: 8 |
FacultyNo |
Long / 4 | — | Идентификатор факультета; ссылка на FACULTY. В CHAIRS есть NULL и две отсутствующие положительные ссылки. | NULL: 0; диапазон: 52…57 |
NSubgroups |
Short / 2 | — | Количество подгрупп группы (в этой копии 1–5). | NULL: 0; диапазон: 1…5 |
NStudents |
Short / 2 | — | Количество студентов группы; распределение студентов по отдельным подгруппам отдельно не хранится здесь. | NULL: 0; диапазон: 1…93 |
StreamNo |
Long / 4 | — | Идентификатор STREAMS или служебное -1. В GROUPS все значения -1. | NULL: 0; диапазон: -1…-1 |
CourseNo |
Long / 4 | — | Идентификатор записи Courses; не обязательно номер года обучения. | NULL: 0; диапазон: 1…11 |
A. GRPPLAN.DB — Участие групп и подгрупп в позиции плана§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 21419; счетчик заголовка: 21419; ключ: GroupNo, Subgroup, PlanNo. Формат Paradox 5, кодировка cp866, размер записи 10 байт. Внутреннее имя: GRPPLAN.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
GroupNo |
Long / 4 | Да | Идентификатор группы; ссылка на GROUPS. В Classes при -1 состав определяется через GRPPLAN. | NULL: 0; диапазон: 433604…434159 |
Subgroup |
Short / 2 | Да | Номер подгруппы. В GRPPLAN 1–5; в Classes также -1 без конкретной подгруппы. | NULL: 0; диапазон: 1…5 |
PlanNo |
Long / 4 | Да | Идентификатор позиции плана; ссылка на Plan вне самой Plan. | NULL: 0; диапазон: 222250…229104 |
A. PLANITEM.DB — Вид, объем нагрузки и деление на подгруппы§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 7098; счетчик заголовка: 7098; ключ: PlanNo, PlanType. Формат Paradox 5, кодировка cp866, размер записи 8 байт. Внутреннее имя: resttemp.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
PlanNo |
Long / 4 | Да | Идентификатор позиции плана; ссылка на Plan вне самой Plan. | NULL: 0; диапазон: 222250…229104 |
PlanType |
Alpha / 1 | Да | Однобайтовый кириллический код вида занятия. Шесть кодов; точная расшифровка сверяется с программой. | Пустых: 0; различных: 6; макс. длина: 1 |
PlanQty |
Short / 2 | — | Объем по виду занятия. Интерфейс называет часами; единица и преобразование в Classes требуют проверки. | NULL: 0; диапазон: 1…18 |
GrpSplit |
Logical / 1 | — | Разделять вид занятия по подгруппам; соответствует флажкам плана и фактическим подгруппам. | True: 772; False: 6326; NULL: 0 |
A. PLANROOM.DB — Связь плана/вида с аудиториями; таблица пуста§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 0; счетчик заголовка: 0; ключ: PlanNo, PlanType, RoomNo. Формат Paradox 5, кодировка cp866, размер записи 9 байт. Внутреннее имя: PLANROOM.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
PlanNo |
Long / 4 | Да | Идентификатор позиции плана; ссылка на Plan вне самой Plan. | Таблица пуста |
PlanType |
Alpha / 1 | Да | Однобайтовый кириллический код вида занятия. Шесть кодов; точная расшифровка сверяется с программой. | Таблица пуста |
RoomNo |
Long / 4 | Да | Идентификатор аудитории; ссылка на Rooms. В Classes значение -1 означает отсутствие указанной аудитории. | Таблица пуста |
A. Plan.DB — Позиции учебного плана§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 4748; счетчик заголовка: 4748; ключ: PlanNo. Формат Paradox 5, кодировка cp866, размер записи 13 байт. Внутреннее имя: resttemp.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
PlanNo |
AutoIncrement / 4 | Да | Идентификатор позиции плана; ссылка на Plan вне самой Plan. | NULL: 0; диапазон: 222250…229104 |
SubjectNo |
Long / 4 | — | Идентификатор дисциплины; ссылка на SUBJECTS. | NULL: 0; диапазон: 2295…7641 |
ChairNo |
Long / 4 | — | Идентификатор кафедры; ссылка на CHAIRS вне самой CHAIRS. Служебные 0/-1 зависят от таблицы. | NULL: 0; диапазон: 465…521 |
Stable |
Logical / 1 | — | Флаг «Стабильное» из плана; действие на редактирование/размещение не доказано. | True: 3738; False: 1010; NULL: 0 |
A. ROOMRSTR.DB — Ограничения аудиторий§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 990; счетчик заголовка: 990; ключ: RoomNo, DayNo, TimeNo, Week. Формат Paradox 5, кодировка cp866, размер записи 74 байт. Внутреннее имя: resttemp.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
RoomNo |
Long / 4 | Да | Идентификатор аудитории; ссылка на Rooms. В Classes значение -1 означает отсутствие указанной аудитории. | NULL: 0; диапазон: 10041…10179 |
DayNo |
Short / 2 | Да | В DAYS и ограничениях код дня 0–5; в Classes/ClassesInf составной код 0–299 или NULL, не прямой FK на DAYS. | NULL: 0; диапазон: 0…5 |
TimeNo |
Short / 2 | Да | Номер временной позиции TIMES (1–8); в занятиях возможен NULL. | NULL: 0; диапазон: 1…8 |
Week |
Short / 2 | Да | Код варианта недели ограничения: 0 или 1; соответствие четной/нечетной неделе требует проверки. | NULL: 0; диапазон: 0…1 |
Reason |
Alpha / 64 | — | Причина/заметка ограничения; свободный текст может включать служебные сведения. | Пустых: 0; различных: 75; макс. длина: 64 |
A. Rooms.DB — Аудитории§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 184; счетчик заголовка: 184; ключ: RoomNo. Формат Paradox 5, кодировка cp866, размер записи 84 байт. Внутреннее имя: resttemp.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
RoomNo |
AutoIncrement / 4 | Да | Идентификатор аудитории; ссылка на Rooms. В Classes значение -1 означает отсутствие указанной аудитории. | NULL: 0; диапазон: 9994…10179 |
RoomName |
Alpha / 8 | — | Обозначение аудитории; отдельного справочника корпусов в копии не найдено. | Пустых: 0; различных: 184; макс. длина: 8 |
RoomCap |
Short / 2 | — | Вместимость аудитории; наличие поля не доказывает обязательную проверку при размещении. | NULL: 0; диапазон: 1…210 |
RoomSpec |
Logical / 1 | — | Логический признак помещения; все False, точный смысл не установлен. | True: 0; False: 184; NULL: 0 |
RoomType |
Alpha / 1 | — | Код назначения помещения; отдельный классификатор от PlanType. В копии с/л/п/к. | Пустых: 0; различных: 4; макс. длина: 1 |
RoomMemo |
Alpha / 64 | — | Замечания об аудитории. | Пустых: 182; различных: 3; макс. длина: 34 |
ChairNo |
Long / 4 | — | Идентификатор кафедры; ссылка на CHAIRS вне самой CHAIRS. Служебные 0/-1 зависят от таблицы. | NULL: 0; диапазон: -1…516 |
A. STREAMS.DB — Именованный справочник потоков/периодов§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 140; счетчик заголовка: 140; ключ: StreamNo. Формат Paradox 5, кодировка cp866, размер записи 259 байт. Внутреннее имя: STREAMS.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
StreamNo |
AutoIncrement / 4 | Да | Идентификатор STREAMS или служебное -1. В GROUPS все значения -1. | NULL: 0; диапазон: 374…568 |
StreamName |
Alpha / 255 | — | Название потока/периода. Может содержать исторические учебные годы. | Пустых: 0; различных: 140; макс. длина: 51 |
A. SUBJECTS.DB — Дисциплины и краткие названия§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 5068; счетчик заголовка: 5068; ключ: SubjectNo. Формат Paradox 5, кодировка cp866, размер записи 50 байт. Внутреннее имя: SUBJECTS.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
SubjectNo |
AutoIncrement / 4 | Да | Идентификатор дисциплины; ссылка на SUBJECTS. | NULL: 0; диапазон: 2293…7641 |
SubjectName |
Alpha / 35 | — | Полное/основное название дисциплины с историческим ограничением длины. | Пустых: 0; различных: 5028; макс. длина: 35 |
SubjectChar |
Alpha / 1 | — | Однобайтовый условный символ дисциплины; точная роль в интерфейсе не подтверждена. | Пустых: 5068; различных: 1; макс. длина: 0 |
SubjectShortName |
Alpha / 10 | — | Краткое название дисциплины для компактного отображения. | Пустых: 0; различных: 4667; макс. длина: 10 |
A. TCHRRSTR.DB — Ограничения преподавателей§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 4541; счетчик заголовка: 4541; ключ: TeacherNo, DayNo, TimeNo, Week. Формат Paradox 5, кодировка cp866, размер записи 74 байт. Внутреннее имя: TCHRRSTR.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
TeacherNo |
Long / 4 | Да | Идентификатор преподавателя; ссылка на TEACHERS. В Classes значение -1 означает отсутствие указанного преподавателя. | NULL: 0; диапазон: 43451…47547 |
DayNo |
Short / 2 | Да | В DAYS и ограничениях код дня 0–5; в Classes/ClassesInf составной код 0–299 или NULL, не прямой FK на DAYS. | NULL: 0; диапазон: 0…5 |
TimeNo |
Short / 2 | Да | Номер временной позиции TIMES (1–8); в занятиях возможен NULL. | NULL: 0; диапазон: 1…8 |
Week |
Short / 2 | Да | Код варианта недели ограничения: 0 или 1; соответствие четной/нечетной неделе требует проверки. | NULL: 0; диапазон: 0…1 |
Reason |
Alpha / 64 | — | Причина/заметка ограничения; свободный текст может включать служебные сведения. | Пустых: 0; различных: 1019; макс. длина: 64 |
A. TEACHERS.DB — Преподаватели§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 866; счетчик заголовка: 866; ключ: TeacherNo. Формат Paradox 5, кодировка cp866, размер записи 126 байт. Внутреннее имя: TEACHERS.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
TeacherNo |
AutoIncrement / 4 | Да | Идентификатор преподавателя; ссылка на TEACHERS. В Classes значение -1 означает отсутствие указанного преподавателя. | NULL: 0; диапазон: 43451…47553 |
TeacherName |
Alpha / 30 | — | Фамилия и инициалы/отображаемое имя преподавателя; не использовать как ключ. | Пустых: 0; различных: 866; макс. длина: 19 |
ChairNo |
Long / 4 | — | Идентификатор кафедры; ссылка на CHAIRS вне самой CHAIRS. Служебные 0/-1 зависят от таблицы. | NULL: 0; диапазон: -1…521 |
TeacherDegree |
Alpha / 16 | — | Ученая степень. | Пустых: 552; различных: 40; макс. длина: 16 |
TeacherPosition |
Alpha / 16 | — | Должность. | Пустых: 55; различных: 10; макс. длина: 13 |
TeacherTitle |
Alpha / 16 | — | Ученое звание. | Пустых: 865; различных: 2; макс. длина: 13 |
TeacherMemo |
Alpha / 40 | — | Замечания о преподавателе. | Пустых: 852; различных: 15; макс. длина: 39 |
A. TIMES.DB — Временные позиции и начала занятий§
Источник: файл (локальный материал); JSON (локальный материал). Активных строк: 8; счетчик заголовка: 8; ключ: TimeNo. Формат Paradox 4, кодировка cp866, размер записи 12 байт. Внутреннее имя: TIME.DB.
| Поле | Тип / байт | PK | Назначение | Наблюдения по данным |
|---|---|---|---|---|
TimeNo |
Short / 2 | Да | Номер временной позиции TIMES (1–8); в занятиях возможен NULL. | NULL: 0; диапазон: 1…8 |
TimeName |
Alpha / 10 | — | Строка начала занятия, например 8:00. Конец и длительность здесь отсутствуют. | Пустых: 0; различных: 8; макс. длина: 5 |
Приложение B. Все 65 файлов каталога семестра§
Размеры приведены для предоставленного снимка. SHA-256 каждого файла находятся в source-manifest.json (локальный материал). Ссылки ведут на оригинальные файлы; для чтения данных удобнее SQLite/JSON.
| Файл | Байт | Содержимое / назначение |
|---|---|---|
| chairs.dat (локальный материал) | 3 389 | Обменные строки фиксированной ширины: Кафедры и принадлежность факультету; кириллица заменена # |
| CHAIRS.DB (локальный материал) | 6 144 | Кафедры и принадлежность факультету |
| CHAIRS.PX (локальный материал) | 4 096 | Первичный индекс CHAIRS.DB |
| chairs.sch (локальный материал) | 213 | Схема полей/длин/смещений chairs.dat; Filetype=Fixed |
| Classes.DB (локальный материал) | 3 801 088 | Основные записи занятий |
| Classes.PX (локальный материал) | 34 816 | Первичный индекс Classes.DB |
| Classes.XG0 (локальный материал) | 456 704 | Вторичный индекс PlanNoIdx: PlanNo + ClassNo |
| Classes.XG1 (локальный материал) | 512 000 | Вторичный индекс TeacherNoIdx: TeacherNo + ClassNo |
| Classes.YG0 (локальный материал) | 8 192 | Индексная структура для classes.xg0; полное дерево не проверено |
| Classes.YG1 (локальный материал) | 10 240 | Индексная структура для classes.xg1; полное дерево не проверено |
| ClassesInf.DB (локальный материал) | 544 768 | Предположительно производные позиции расписания; есть рассогласование |
| CLASSINF.DB (локальный материал) | 2 048 | Дополнительные ресурсы занятия; таблица пуста |
| CLASSINF.PX (локальный материал) | 2 048 | Первичный индекс CLASSINF.DB |
| Courses.DB (локальный материал) | 6 144 | Классификатор курсов и уровней обучения |
| Courses.PX (локальный материал) | 4 096 | Первичный индекс Courses.DB |
| DAYS.DB (локальный материал) | 4 096 | Дни шестидневной недели |
| DAYS.PX (локальный материал) | 4 096 | Первичный индекс DAYS.DB |
| DBDWORK.INI (локальный материал) | 2 | Только CRLF; полезных настроек нет |
| FACULTY.DB (локальный материал) | 4 096 | Факультеты / организационные подразделения |
| FACULTY.PX (локальный материал) | 4 096 | Первичный индекс FACULTY.DB |
| groups.dat (локальный материал) | 9 049 | Обменные строки фиксированной ширины: Учебные группы; кириллица заменена # |
| GROUPS.DB (локальный материал) | 18 432 | Учебные группы |
| GROUPS.PX (локальный материал) | 4 096 | Первичный индекс GROUPS.DB |
| groups.sch (локальный материал) | 341 | Схема полей/длин/смещений groups.dat; Filetype=Fixed |
| Groups.VAL (локальный материал) | 349 | Правила допустимости/метаданные GROUPS; содержательные правила не декодированы |
| GROUPS.XG0 (локальный материал) | 8 192 | Вторичный индекс GroupStreamIdx: StreamNo + GroupNo |
| GROUPS.YG0 (локальный материал) | 4 096 | Индексная структура для groups.xg0; полное дерево не проверено |
| GRPPLAN.DB (локальный материал) | 235 520 | Участие групп и подгрупп в позиции плана |
| GRPPLAN.PX (локальный материал) | 4 096 | Первичный индекс GRPPLAN.DB |
| GRPPLAN.XG0 (локальный материал) | 718 848 | Вторичный индекс PlanGroupIdx: PlanNo GroupNo Subgroup + первичный ключ |
| GRPPLAN.YG0 (локальный материал) | 16 384 | Индексная структура для grpplan.xg0; полное дерево не проверено |
| LOAD.FAM (локальный материал) | 240 | Метаданные семейства; ссылки на CLASSES.TV |
| LOAD.PX (локальный материал) | 4 096 | Индекс исторического LOAD; одноименного LOAD.DB в снимке нет |
| LOAD.TV (локальный материал) | 2 096 | Настройки табличного представления :WORK:CLASSES.DB |
| Plan.DB (локальный материал) | 229 376 | Позиции учебного плана |
| Plan.PX (локальный материал) | 4 096 | Первичный индекс Plan.DB |
| PLANITEM.DB (локальный материал) | 212 992 | Вид объем нагрузки и деление на подгруппы |
| PLANITEM.PX (локальный материал) | 4 096 | Первичный индекс PLANITEM.DB |
| PLANROOM.DB (локальный материал) | 2 048 | Связь плана/вида с аудиториями; таблица пуста |
| PLANROOM.PX (локальный материал) | 2 048 | Первичный индекс PLANROOM.DB |
| Reorder.EXE (локальный материал) | 622 592 | Утилита перестановки групп/аудиторий Windows x86 Delphi/VCL/BDE; не запускалась |
| ROOMRSTR.DB (локальный материал) | 354 304 | Ограничения аудиторий |
| ROOMRSTR.PX (локальный материал) | 8 192 | Первичный индекс ROOMRSTR.DB |
| rooms.dat (локальный материал) | 4 811 | Обменные строки фиксированной ширины: Аудитории; кириллица заменена # |
| Rooms.DB (локальный материал) | 22 528 | Аудитории |
| Rooms.PX (локальный материал) | 4 096 | Первичный индекс Rooms.DB |
| rooms.sch (локальный материал) | 210 | Схема полей/длин/смещений rooms.dat; Filetype=Fixed |
| STREAMS.DB (локальный материал) | 51 200 | Именованный справочник потоков/периодов |
| STREAMS.PX (локальный материал) | 4 096 | Первичный индекс STREAMS.DB |
| STREAMS.XG0 (локальный материал) | 61 440 | Вторичный индекс StreamNameIdx: StreamName + StreamNo; имена в верхнем регистре |
| STREAMS.YG0 (локальный материал) | 18 432 | Индексная структура для streams.xg0; полное дерево не проверено |
| subjects.dat (локальный материал) | 123 691 | Обменные строки фиксированной ширины: Дисциплины и краткие названия; кириллица заменена # |
| SUBJECTS.DB (локальный материал) | 296 960 | Дисциплины и краткие названия |
| SUBJECTS.PX (локальный материал) | 4 096 | Первичный индекс SUBJECTS.DB |
| subjects.sch (локальный материал) | 223 | Схема полей/длин/смещений subjects.dat; Filetype=Fixed |
| TCHRRSTR.DB (локальный материал) | 1 038 336 | Ограничения преподавателей |
| TCHRRSTR.PX (локальный материал) | 18 432 | Первичный индекс TCHRRSTR.DB |
| teachers.dat (локальный материал) | 69 332 | Обменные строки фиксированной ширины: Преподаватели; кириллица заменена # |
| TEACHERS.DB (локальный материал) | 215 040 | Преподаватели |
| TEACHERS.PX (локальный материал) | 4 096 | Первичный индекс TEACHERS.DB |
| teachers.sch (локальный материал) | 357 | Схема полей/длин/смещений teachers.dat; Filetype=Fixed |
| TEACHERS.XG0 (локальный материал) | 18 432 | Вторичный индекс TeacherFacultyIdx: фактически ChairNo + TeacherNo |
| TEACHERS.YG0 (локальный материал) | 4 096 | Индексная структура для teachers.xg0; полное дерево не проверено |
| TIMES.DB (локальный материал) | 4 096 | Временные позиции и начала занятий |
| TIMES.PX (локальный материал) | 4 096 | Первичный индекс TIMES.DB |
Внешние служебные файлы в DB§
| Файл | Байт | Назначение |
|---|---|---|
| PARADOX.LCK (локальный материал) | 110 | Файл блокировок Paradox |
| PDOXUSRS.LCK (локальный материал) | 21 504 | Файл блокировок BDE; содержит исторический путь E:\LOCK\ и имена таблиц |
.DS_Store |
— | Метаданные просмотра папки macOS, не часть логики расписания |
В каталоге семестра 65 файлов, еще два файла приложения — блокировки в родительском DB. .DS_Store не включен в эти 67 файлов приложения. По содержимому копии блокировок нельзя определить активных пользователей. В отчете форматов указаны байтовые доказательства.
Что проверено у индексов§
Все шесть мультимножеств вторичных ключей вместе с первичными ключами совпали с соответствующими DB; для STREAMS применено приведение регистра. Поля индексов перечислены в инвентаре выше. При этом индексное дерево YG и полное поведение поиска BDE не проверялись. В служебном Blk Num есть расхождения с текущими физическими блоками: их смысл требует проверки движком и не трактуется здесь как доказанное повреждение. Подробности: исследование индексов.
Приложение C. Полный каталог функций по скриншотам§
Здесь «видна» означает видимый экран/подписанную команду; «предполагается» — вывод по форме или неподписанной пиктограмме.
| № | Функция | Статус и источник |
|---|---|---|
| 1 | Открыть список групп | Видна — 1, 3 |
| 2 | Найти/отфильтровать группы | Видно поле — 3; логика поиска не показана |
| 3 | Вести факультет, численность, подгруппы и курс группы | Видны поля — 3; сохранение не показано |
| 4 | Добавить/изменить/удалить группу | Предполагается по пиктограммам — 3 |
| 5 | Открыть список преподавателей | Видна — 1, 4 |
| 6 | Найти/отфильтровать преподавателя | Видно поле — 4 |
| 7 | Вести кафедру, должность, звание, степень, замечания преподавателя | Видны поля — 4 |
| 8 | Добавить/изменить/удалить преподавателя | Предполагается по пиктограммам — 4 |
| 9 | Открыть список дисциплин | Видна — 1, 5 |
| 10 | Найти/отфильтровать дисциплину | Видно поле — 5 |
| 11 | Вести полное и краткое название дисциплины | Видны поля — 5 |
| 12 | Добавить/изменить/удалить дисциплину | Предполагается по пиктограммам — 5 |
| 13 | Открыть список аудиторий | Видна — 1, 6 |
| 14 | Найти/отфильтровать аудиторию | Видно поле — 6 |
| 15 | Вести вместимость, назначение, кафедру, замечания аудитории | Видны поля — 6 |
| 16 | Добавить/изменить/удалить аудиторию | Предполагается по пиктограммам — 6 |
| 17 | Открыть список кафедр | Видна — 1, 7 |
| 18 | Найти/отфильтровать кафедру | Видно поле — 7 |
| 19 | Связать кафедру с факультетом | Видно поле — 7 |
| 20 | Добавить/изменить кафедру | Предполагается по пиктограммам — 7 |
| 21 | Просмотреть факультеты | Видна — 1, 8 |
| 22 | Просмотреть учебный план выбранной группы | Видна — 1, 9 |
| 23 | Указать дисциплину и кафедру в плане | Видны поля — 9 |
| 24 | Указать недельную нагрузку по лекциям, практикам, лабораторным | Видны поля — 9 |
| 25 | Учитывать проведение практик/лабораторных по подгруппам | Видны флажки — 9 |
| 26 | Учитывать экзамены, консультации, зачеты | Видны блоки — 9; поведение ввода не показано |
| 27 | Задать признак «Стабильное» | Видны флажок и значения — 9; смысл неизвестен |
| 28 | Просмотреть группы, объединенные для записи плана | Видно поле «Поток» — 9 |
| 29 | Добавить/изменить/удалить запись учебного плана | Предполагается по пиктограммам — 9 |
| 30 | Просмотреть классификатор курсов и уровней обучения | Видна — 1, 10 |
| 31 | Просмотреть потоки и состав групп | Видна — 1, 11 |
| 32 | Создать поток | Видна кнопка «Новый» — 11 |
| 33 | Удалить поток | Видна кнопка «Удалить» — 11 |
| 34 | Включить/исключить группу из потока | Предполагается по стрелкам и спискам — 11 |
| 35 | Выбрать режим потока «Полное»/«Нечетная»/«Четная»/«Экзамены» | Кнопки видны, неактивны — 11; результат неизвестен |
| 36 | Просмотреть начала занятий | Видна таблица «Звонки» — 1, 12 |
| 37 | Открыть общее расписание | Видна сетка — 14, 15; вероятный переход «Основной вид» — 2 |
| 38 | Выбрать неделю | Видно поле — 14, 15 |
| 39 | Просмотреть занятия по дням, позициям и группам | Видна сетка — 14, 15 |
| 40 | Просмотреть детали занятия при наведении | Видна всплывающая карточка — 14 |
| 41 | Просмотреть неназначенные занятия | Видна панель — 14, 15 |
| 42 | Обновить представление расписания | Видна кнопка «Обновить» — 14, 15 |
| 43 | Отменить выбранный элемент | Видна команда — 15; точная семантика неизвестна |
| 44 | Переставить занятие | Видна команда — 15 |
| 45 | Сменить аудиторию занятия | Видна команда — 15 |
| 46 | Заменить преподавателя | Видна команда — 15 |
| 47 | Отдать на кафедру | Видна команда — 15; точная семантика неизвестна |
| 48 | Открыть расписание группы | Видна команда — 15 |
| 49 | Открыть расписание преподавателя | Видна команда — 15 |
| 50 | Открыть расписание аудитории | Команда видна, неактивна — 15 |
| 51 | Работать с комментарием занятия | Видна команда — 15 |
| 52 | Открыть поиск свободных аудиторий | Видны меню и окно — 2, 13 |
| 53 | Выбрать день поиска аудитории | Видны кнопки — 13 |
| 54 | Отобрать аудитории по назначению | Видны варианты — 13 |
| 55 | Просмотреть свободные аудитории по времени | Видны колонки — 13; выдача пуста |
| 56 | Выполнить действие «База данных» | Видна команда — 2; содержание неизвестно |
| 57 | Открыть параметры | Видны меню/кнопка — 2, 14, 15 |
| 58 | Открыть помощь | Видно меню — 1, 2 |
| 59 | Выйти из приложения | Видна команда «Выход», Alt+X — 1 |
Номера источников в последней колонке соответствуют Screenshot_N.jpg. Это каталог предусмотренных интерфейсом возможностей, а не перечень 59 проверенных рабочих операций.
Указатель всех 15 скриншотов§
| Файл | Что показывает |
|---|---|
| Screenshot_1.jpg | Главное окно и раскрытые «Справочники» |
| Screenshot_2.jpg | Раскрытое меню «Расписание» |
| Screenshot_3.jpg | Группы и карточка группы |
| Screenshot_4.jpg | Преподаватели и карточка преподавателя |
| Screenshot_5.jpg | Дисциплины |
| Screenshot_6.jpg | Аудитории |
| Screenshot_7.jpg | Кафедры |
| Screenshot_8.jpg | Факультеты |
| Screenshot_9.jpg | Учебный план |
| Screenshot_10.jpg | Курсы |
| Screenshot_11.jpg | Потоки |
| Screenshot_12.jpg | Звонки |
| Screenshot_13.jpg | Поиск свободных аудиторий |
| Screenshot_14.jpg | Общее расписание и всплывающие сведения |
| Screenshot_15.jpg | Контекстные команды занятия |
Полное описание каждой формы с разграничением наблюдения и интерпретации: screens-analysis.md.
Приложение D. Файлы результата и их назначение§
| Артефакт | Назначение |
|---|---|
| system-report.html | Этот отчет в автономном HTML с оглавлением, фильтром разделов и печатью |
| system-report.md (локальный материал) | Полный исходный текст отчета |
| schedule.sqlite (локальный материал) | 19 исходных таблиц, два представления и происхождение данных |
| schema.json (локальный материал) | Все поля, ключи, параметры формата, блоки и предупреждения |
| source-manifest.json (локальный материал) | SHA-256 всех 65 файлов каталога семестра |
| metrics.json (локальный материал) | Агрегаты, проверки связей и качества |
| pxlib-validation.json (локальный материал) | Независимое сравнение всех доступных записей |
| indexes-evidence.json (локальный материал) | Заголовки и проверка вторичных ключей |
| auxiliary-evidence.json (локальный материал) | Статически извлеченные формы EXE и схемы текстовых файлов |
| paradox_read.py (локальный материал) | Читатель найденных форматов Paradox без операций записи |
| export_data.py (локальный материал) | Воспроизводимый экспорт JSON и SQLite |
| validate_pxlib.py (локальный материал) | Необязательное сравнение с pypxlib на временных копиях |
| analyze_relations.py (локальный материал) | Повторный расчет связей и агрегатов из JSON |
| inspect_auxiliary.py (локальный материал) | Статическое исследование DAT/SCH и конкретного Reorder.EXE |
| inspect_indexes.py (локальный материал) | Проверка вторичных индексов |
| build_report.py (локальный материал) | Сборка этого Markdown из текста, схемы и каталогов |
| render_report.py (локальный материал) | Преобразование итогового Markdown в HTML |
Это техническое исследование и подготовка данных для просмотра. Полноценное веб-приложение, развертывание, автосоставление и редактор с обратной записью в Paradox в рамках этой работы не реализованы. Архитектура и проверяемые шаги их создания описаны выше.