модуль ученики импорт "стд::вывод" импорт "исх/строка" импорт "исх/спринтф" импорт "исх/массивы" импорт "исх/сеть/хттп" импорт "исх/форматы/джесон" импорт "исх/сеть/хттп/маршрутизатор" импорт "исх/картотека" импорт "исх/картотека/репозитории" импорт "исх/бюрократия" фн создать*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет { пусть оплошность := "" пусть картотека = картотека.зайти() пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность) если оплошность # "" { вернуть хттп.ответ_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"], удалить) вернуть маршрутизатор }