Files
2025-11-26 21:32:41 +03:00

382 lines
20 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
модуль ученики
импорт "стд::вывод"
импорт "исх/строка"
импорт "исх/спринтф"
импорт "исх/массивы"
импорт "исх/сеть/хттп"
импорт "исх/форматы/джесон"
импорт "исх/сеть/хттп/маршрутизатор"
импорт "исх/картотека"
импорт "исх/картотека/репозитории"
импорт "исх/бюрократия"
фн создать*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет {
пусть оплошность := ""
пусть картотека = картотека.зайти()
пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если пользователь = пусто {
вернуть хттп.ответ_401()
}
пусть учитель = репозитории.пользователь учитель(пользователь^.идентификатор, оплошность)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если учитель = пусто {
вернуть хттп.ответ_403()
}
пусть данные = джесон.парсить(обращение.туловище, оплошность)
если оплошность # "" {
вернуть хттп.ответ_400()
}
пусть имя := данные.получить("имя").строка()
пусть фамилия := данные.получить("фамилия").строка()
пусть отчество := данные.получить("отчество").строка()
пусть пароль := данные.получить("пароль").строка()
пусть повтор пароля := данные.получить("повтор пароля").строка()
пусть снилс := данные.получить("снилс").строка()
пусть паспорт := данные.получить("паспорт").строка()
если имя = пусто | фамилия = пусто | отчество = пусто | пароль = пусто | повтор пароля = пусто | снилс = пусто | паспорт = пусто {
вернуть хттп.ответ_400()
}
если имя^ = "" | фамилия^ = "" | отчество^ = "" | пароль^ = "" | повтор пароля^ = "" | снилс^ = "" | паспорт^ = "" {
вернуть хттп.ответ_400()
}
если пароль^ # повтор пароля^ {
вернуть хттп.создать ответ(
хттп.ответ_400(),
хттп.ХттпОтвет{ туловище: "Пароли не совпадают." }
)
}
пусть имя пользователя = спринтф.ф("$стр.$стр", имя^, фамилия^)
пусть ответ = картотека.запросить безопасно(`
INSERT INTO users (first_name, last_name, middle_name, username, password)
VALUES (?, ?, ?, ?, ?)
RETURNING id
`, оплошность, имя^, фамилия^, отчество^, имя пользователя, пароль^)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если длина(ответ.значения) = 0 {
вернуть хттп.ответ_500()
}
пусть айди пользователя = ответ.значения[0](:джесон.ДжесонОбъект).получить("id").число()
если айди пользователя = пусто {
вернуть хттп.ответ_500()
}
пусть ученик = картотека.запросить безопасно(`
INSERT INTO students (user_id, mentor_id, snils, passport)
VALUES (?, ?, ?, ?)
RETURNING id
`, оплошность,
айди пользователя^.значение,
учитель^.идентификатор,
снилс^,
паспорт^
)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если длина(ученик.значения) = 0 {
вернуть хттп.ответ_500()
}
пусть созданный = ученик.значения[0](:джесон.ДжесонОбъект)
пусть идентификатор ученика = созданный.получить("id").число()
если идентификатор ученика = пусто {
вернуть хттп.ответ_500()
}
пусть тело = джесон.сериализовать(джесон.ДжесонОбъект{
значения: джесон.ДжесонКлючЗначения[
джесон.ДжесонКлючЗначение{ ключ: "идентификатор", значение: джесон.ДжесонЧисло{ значение: идентификатор ученика^.значение } },
джесон.ДжесонКлючЗначение{ ключ: "имя", значение: джесон.ДжесонСтрока{ значение: имя^ } },
джесон.ДжесонКлючЗначение{ ключ: "фамилия", значение: джесон.ДжесонСтрока{ значение: фамилия^ } },
джесон.ДжесонКлючЗначение{ ключ: "отчество", значение: джесон.ДжесонСтрока{ значение: отчество^ } },
джесон.ДжесонКлючЗначение{ ключ: "снилс", значение: джесон.ДжесонСтрока{ значение: снилс^ } },
джесон.ДжесонКлючЗначение{ ключ: "паспорт", значение: джесон.ДжесонСтрока{ значение: паспорт^ } },
джесон.ДжесонКлючЗначение{ ключ: "учитель", значение: джесон.ДжесонЧисло{ значение: учитель^.идентификатор } },
джесон.ДжесонКлючЗначение{ ключ: "имя пользователя", значение: джесон.ДжесонСтрока{ значение: имя пользователя } }
]
})
вернуть хттп.создать ответ(
хттп.ответ_201(),
хттп.ХттпОтвет{ туловище: тело }
)
}
фн список учеников*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет {
пусть оплошность := ""
пусть картотека = картотека.зайти()
пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если пользователь = пусто {
вернуть хттп.ответ_401()
}
пусть учитель = репозитории.пользователь учитель(пользователь^.идентификатор, оплошность)
пусть админ = репозитории.пользователь админ(пользователь^.идентификатор, оплошность)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если учитель = пусто & ~админ {
вернуть хттп.ответ_403()
}
пусть фильтр по учителю := -1
пусть параметр учитель = обращение.запрос-в-пути.найти("учитель")
если параметр учитель # пусто {
пусть номер байта := 0
строка.извлечь цел(параметр учитель^.значение, номер байта, фильтр по учителю)
} иначе если ~админ {
фильтр по учителю := учитель^.идентификатор
}
если фильтр по учителю = -1 {
вернуть хттп.ответ_400()
}
пусть найдено = картотека.запросить безопасно(`
SELECT s.id, s.snils, s.passport, s.mentor_id, u.first_name, u.last_name, u.middle_name, u.username
FROM students s
JOIN users u ON u.id = s.user_id
WHERE s.mentor_id = ?
ORDER BY s.id
`, оплошность, фильтр по учителю)
если оплошность # "" {
вернуть хттп.ответ_500()
}
пусть джесон ученики = джесон.ДжесонМногоЗначений{}
цикл запись среди найдено.значения {
пусть объект = запись(:джесон.ДжесонОбъект)
пусть идентификатор = объект.получить("id").число()
пусть имя = объект.получить("first_name").строка()
пусть фамилия = объект.получить("last_name").строка()
пусть отчество = объект.получить("middle_name").строка()
пусть снилс = объект.получить("snils").строка()
пусть паспорт = объект.получить("passport").строка()
пусть наставник = объект.получить("mentor_id").число()
пусть имя пользователя = объект.получить("username").строка()
пусть студент = джесон.ДжесонОбъект{}
студент.вставить("идентификатор", джесон.ДжесонЧисло{ значение: идентификатор^.значение })
студент.вставить("имя", джесон.ДжесонСтрока{ значение: имя^ })
студент.вставить("фамилия", джесон.ДжесонСтрока{ значение: фамилия^ })
студент.вставить("отчество", джесон.ДжесонСтрока{ значение: отчество^ })
студент.вставить("снилс", джесон.ДжесонСтрока{ значение: снилс^ })
студент.вставить("паспорт", джесон.ДжесонСтрока{ значение: паспорт^ })
студент.вставить("наставник", джесон.ДжесонЧисло{ значение: наставник^.значение })
студент.вставить("имя пользователя", джесон.ДжесонСтрока{ значение: имя пользователя^ })
джесон ученики.значения.добавить(студент)
}
пусть тело = джесон.сериализовать(джесон.ДжесонОбъект{
значения: джесон.ДжесонКлючЗначения[
джесон.ДжесонКлючЗначение{
ключ: "ученики",
значение: джесон ученики
}
]
})
вернуть хттп.ХттпОтвет{ туловище: тело }
}
фн получить*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет {
пусть оплошность := ""
пусть картотека = картотека.зайти()
пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если пользователь = пусто {
вернуть хттп.ответ_401()
}
пусть учитель = репозитории.пользователь учитель(пользователь^.идентификатор, оплошность)
пусть админ = репозитории.пользователь админ(пользователь^.идентификатор, оплошность)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если учитель = пусто & ~админ {
вернуть хттп.ответ_403()
}
если длина(параметры) < 1 {
вернуть хттп.ответ_400()
}
пусть ид ученика = параметры[0]
пусть ученик := джесон.ДжесонМногоЗначений{}
если админ {
ученик := картотека.запросить безопасно(`
SELECT s.id, s.snils, s.passport, s.mentor_id, u.first_name, u.last_name, u.middle_name, u.username
FROM students s
JOIN users u ON u.id = s.user_id
WHERE s.id = ?
`, оплошность, ид ученика)
} иначе {
ученик := картотека.запросить безопасно(`
SELECT s.id, s.snils, s.passport, s.mentor_id, u.first_name, u.last_name, u.middle_name, u.username
FROM students s
JOIN users u ON u.id = s.user_id
WHERE s.id = ? AND s.mentor_id = ?
`, оплошность, ид ученика, учитель^.идентификатор)
}
если оплошность # "" {
вернуть хттп.ответ_500()
}
если длина(ученик.значения) = 0 {
вернуть хттп.ответ_404()
}
пусть объект = ученик.значения[0](:джесон.ДжесонОбъект)
пусть идентификатор = объект.получить("id").число()
пусть имя = объект.получить("first_name").строка()
пусть фамилия = объект.получить("last_name").строка()
пусть отчество = объект.получить("middle_name").строка()
пусть снилс = объект.получить("snils").строка()
пусть паспорт = объект.получить("passport").строка()
пусть наставник = объект.получить("mentor_id").число()
пусть имя пользователя = объект.получить("username").строка()
если идентификатор = пусто | имя = пусто | фамилия = пусто | отчество = пусто | снилс = пусто | паспорт = пусто | наставник = пусто | имя пользователя = пусто {
вернуть хттп.ответ_500()
}
пусть тело = джесон.сериализовать(джесон.ДжесонОбъект{
значения: джесон.ДжесонКлючЗначения[
джесон.ДжесонКлючЗначение{ ключ: "идентификатор", значение: джесон.ДжесонЧисло{ значение: идентификатор^.значение } },
джесон.ДжесонКлючЗначение{ ключ: "имя", значение: джесон.ДжесонСтрока{ значение: имя^ } },
джесон.ДжесонКлючЗначение{ ключ: "фамилия", значение: джесон.ДжесонСтрока{ значение: фамилия^ } },
джесон.ДжесонКлючЗначение{ ключ: "отчество", значение: джесон.ДжесонСтрока{ значение: отчество^ } },
джесон.ДжесонКлючЗначение{ ключ: "снилс", значение: джесон.ДжесонСтрока{ значение: снилс^ } },
джесон.ДжесонКлючЗначение{ ключ: "паспорт", значение: джесон.ДжесонСтрока{ значение: паспорт^ } },
джесон.ДжесонКлючЗначение{ ключ: "наставник", значение: джесон.ДжесонЧисло{ значение: наставник^.значение } },
джесон.ДжесонКлючЗначение{ ключ: "имя пользователя", значение: джесон.ДжесонСтрока{ значение: имя пользователя^ } }
]
})
вернуть хттп.ХттпОтвет{ туловище: тело }
}
фн удалить*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет {
пусть оплошность := ""
пусть картотека = картотека.зайти()
пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если пользователь = пусто {
вернуть хттп.ответ_401()
}
пусть учитель = репозитории.пользователь учитель(пользователь^.идентификатор, оплошность)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если учитель = пусто {
вернуть хттп.ответ_403()
}
если длина(параметры) < 1 {
вернуть хттп.ответ_400()
}
пусть ид ученика = параметры[0]
пусть удален = картотека.запросить безопасно(`
DELETE FROM students WHERE id = ? AND mentor_id = ?
RETURNING id, user_id
`, оплошность, ид ученика, учитель^.идентификатор)
если оплошность # "" {
вернуть хттп.ответ_500()
}
если длина(удален.значения) = 0 {
вернуть хттп.ответ_404()
}
пусть объект = удален.значения[0](:джесон.ДжесонОбъект)
пусть айди пользователя = объект.получить("user_id").число()
если айди пользователя = пусто {
вернуть хттп.ответ_500()
}
картотека.запросить безопасно(`
DELETE FROM users WHERE id = ?
`, оплошность, айди пользователя^.значение)
если оплошность # "" {
вернуть хттп.ответ_500()
}
вернуть хттп.ответ_204()
}
фн добавить маршруты*(маршрутизатор: маршрутизатор.Маршрутизатор): маршрутизатор.Маршрутизатор {
маршрутизатор.добавить маршрут("/api/students", массивы.Строки["POST"], создать)
маршрутизатор.добавить маршрут("/api/students", массивы.Строки["GET"], список учеников)
маршрутизатор.добавить маршрут("/api/students/$", массивы.Строки["GET"], получить)
маршрутизатор.добавить маршрут("/api/students/$", массивы.Строки["DELETE"], удалить)
вернуть маршрутизатор
}