модуль классы импорт "стд::вывод" импорт "исх/строка" импорт "исх/спринтф" импорт "исх/массивы" импорт "исх/сеть/хттп" импорт "исх/форматы/джесон" импорт "исх/сеть/хттп/маршрутизатор" импорт "исх/картотека" импорт "исх/картотека/репозитории" импорт "исх/бюрократия" фн список классов*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет { пусть оплошность := "" пусть картотека = картотека.зайти() пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность) если оплошность # "" { вернуть хттп.ответ_500() } если пользователь = пусто { вернуть хттп.ответ_401() } пусть учитель = репозитории.пользователь учитель(пользователь^.идентификатор, оплошность) пусть админ = репозитории.пользователь админ(пользователь^.идентификатор, оплошность) если учитель = пусто & ~админ { вернуть хттп.ответ_403() } пусть фильтр по учителю := -1 пусть параметр учитель = обращение.запрос-в-пути.найти("учитель") если параметр учитель # пусто { пусть номер байта := 0 строка.извлечь цел(параметр учитель^.значение, номер байта, фильтр по учителю) } иначе если ~админ { фильтр по учителю := учитель^.идентификатор } если фильтр по учителю = -1 { вернуть хттп.ответ_400() } пусть классы := картотека.запросить безопасно(` SELECT id, number, letter, creator_teacher_id FROM classes WHERE creator_teacher_id = ? `, оплошность, фильтр по учителю) пусть джесон ответ = джесон.ДжесонМногоЗначений{} цикл [номер телефона мамы]клass среди классы.значения { пусть объект = клass(:джесон.ДжесонОбъект) пусть идентификатор = объект.получить("id").число()^.значение пусть номер = объект.получить("number").число()^.значение пусть буква = объект.получить("letter").строка()^ пусть создатель = объект.получить("creator_teacher_id").число()^.значение пусть джесон клass = джесон.ДжесонОбъект{} джесон клass.вставить("идентификатор", джесон.ДжесонЧисло{ значение: идентификатор }) джесон клass.вставить("номер", джесон.ДжесонЧисло{ значение: номер }) джесон клass.вставить("буква", джесон.ДжесонСтрока{ значение: буква }) джесон клass.вставить("создатель", джесон.ДжесонЧисло{ значение: создатель }) джесон ответ.значения.добавить(джесон клass) } пусть туловище = джесон.сериализовать(джесон.ДжесонОбъект{ значения: джесон.ДжесонКлючЗначения[ джесон.ДжесонКлючЗначение{ ключ: "классы", значение: джесон ответ } ] }) вернуть хттп.ХттпОтвет{ туловище: туловище } } фн создать клass*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет { пусть оплошность := "" пусть картотека = картотека.зайти() пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность) если оплошность # "" { вернуть хттп.ответ_500() } если пользователь = пусто { вернуть хттп.ответ_401() } пусть учитель = репозитории.пользователь учитель(пользователь^.идентификатор, оплошность) если оплошность # "" { вернуть хттп.ответ_500() } если учитель = пусто { вернуть хттп.ответ_403() } пусть данные = джесон.парсить(обращение.туловище, оплошность) если оплошность # "" { вернуть хттп.ответ_400() } пусть номер := данные.получить("номер").число() пусть буква := данные.получить("буква").строка() если номер = пусто | буква = пусто { вернуть хттп.ответ_400() } пусть ответ = картотека.запросить безопасно(` INSERT INTO classes (number, letter, creator_teacher_id) VALUES (?, ?, ?) RETURNING id, number, letter, creator_teacher_id `, оплошность, номер^.значение, буква^, учитель^.идентификатор) если оплошность # "" { вернуть хттп.ответ_422() } если длина(ответ.значения) = 0 { вернуть хттп.ответ_500() } пусть созданный = ответ.значения[0](:джесон.ДжесонОбъект) пусть идентификатор = созданный.получить("id").число()^.значение пусть создан номер = созданный.получить("number").число()^.значение пусть создан буква = созданный.получить("letter").строка()^ пусть создан создатель = созданный.получить("creator_teacher_id").число()^.значение пусть тело = джесон.сериализовать(джесон.ДжесонОбъект{ значения: джесон.ДжесонКлючЗначения[ джесон.ДжесонКлючЗначение{ключ: "идентификатор", значение: джесон.ДжесонЧисло{значение: идентификатор}}, джесон.ДжесонКлючЗначение{ключ: "номер", значение: джесон.ДжесонЧисло{значение: создан номер}}, джесон.ДжесонКлючЗначение{ключ: "буква", значение: джесон.ДжесонСтрока{значение: создан буква}}, джесон.ДжесонКлючЗначение{ключ: "создатель", значение: джесон.ДжесонЧисло{значение: создан создатель}} ] }) вернуть хттп.создать ответ( хттп.ответ_201(), хттп.ХттпОтвет{туловище: тело} ) } фн удалить клass*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет { пусть оплошность := "" пусть картотека = картотека.зайти() пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность) если оплошность # "" { вернуть хттп.ответ_500() } если пользователь = пусто { вернуть хттп.ответ_401() } пусть учитель = репозитории.пользователь учитель(пользователь^.идентификатор, оплошность) пусть админ = репозитории.пользователь админ(пользователь^.идентификатор, оплошность) если оплошность # "" { вернуть хттп.ответ_500() } если учитель = пусто & ~админ { вернуть хттп.ответ_403() } если длина(параметры) < 1 { вернуть хттп.ответ_400() } пусть ид класса = параметры[0] пусть ответ := джесон.ДжесонМногоЗначений{} если админ { ответ := картотека.запросить безопасно(` DELETE FROM classes WHERE id = ? RETURNING id `, оплошность, ид класса) } иначе { ответ := картотека.запросить безопасно(` DELETE FROM classes WHERE id = ? AND creator_teacher_id = ? RETURNING id `, оплошность, ид класса, учитель^.идентификатор) } если оплошность # "" { вернуть хттп.ответ_500() } если длина(ответ.значения) = 0 { вывод.ф("Класс с id = $стр не найден или не принадлежит учителю", ид класса) вернуть хттп.ответ_404() } вернуть хттп.ответ_204() } фн добавить ученика в клass*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет { пусть оплошность := "" пусть картотека = картотека.зайти() пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность) если оплошность # "" { вернуть хттп.ответ_500() } если пользователь = пусто { вернуть хттп.ответ_401() } пусть учитель = репозитории.пользователь учитель(пользователь^.идентификатор, оплошность) пусть админ = репозитории.пользователь админ(пользователь^.идентификатор, оплошность) если оплошность # "" { вернуть хттп.ответ_500() } если учитель = пусто & ~админ { вернуть хттп.ответ_403() } если длина(параметры) < 2 { вернуть хттп.ответ_400() } пусть ид класса = параметры[0] пусть ид ученика = параметры[1] пусть клass := джесон.ДжесонМногоЗначений{} если админ { клass := картотека.запросить безопасно(` SELECT id FROM classes WHERE id = ? `, оплошность, ид класса) } иначе { клass := картотека.запросить безопасно(` SELECT id FROM classes WHERE id = ? AND creator_teacher_id = ? `, оплошность, ид класса, учитель^.идентификатор) } если оплошность # "" { вернуть хттп.ответ_500() } если длина(клass.значения) = 0 { вернуть хттп.ответ_403() } пусть ученик = картотека.запросить безопасно(` SELECT id FROM students WHERE id = ? `, оплошность, ид ученика) если оплошность # "" { вернуть хттп.ответ_500() } если длина(ученик.значения) = 0 { вернуть хттп.ответ_404() } пусть ответ = картотека.запросить безопасно(` INSERT INTO class_students (class_id, student_id) VALUES (?, ?) RETURNING id `, оплошность, ид класса, ид ученика) если оплошность # "" { вернуть хттп.ответ_422() } вернуть хттп.ответ_201() } фн удалить ученика из класса*(путь: Строка, параметры: массивы.Строки, обращение: маршрутизатор.Обращение): хттп.ХттпОтвет { пусть оплошность := "" пусть картотека = картотека.зайти() пусть пользователь = репозитории.авторизовать по паспорту(бюрократия.получить данные паспорта(обращение), оплошность) если оплошность # "" { вернуть хттп.ответ_500() } если пользователь = пусто { вернуть хттп.ответ_401() } пусть учитель = репозитории.пользователь учитель(пользователь^.идентификатор, оплошность) пусть админ = репозитории.пользователь админ(пользователь^.идентификатор, оплошность) если оплошность # "" { вернуть хттп.ответ_500() } если учитель = пусто & ~админ { вернуть хттп.ответ_403() } если длина(параметры) < 2 { вернуть хттп.ответ_400() } пусть ид класса = параметры[0] пусть ид ученика = параметры[1] пусть клass := джесон.ДжесонМногоЗначений{} если админ { клass := картотека.запросить безопасно(` SELECT id FROM classes WHERE id = ? `, оплошность, ид класса) } иначе { клass := картотека.запросить безопасно(` SELECT id FROM classes WHERE id = ? AND creator_teacher_id = ? `, оплошность, ид класса, учитель^.идентификатор) } если оплошность # "" { вернуть хттп.ответ_500() } если длина(клass.значения) = 0 { вернуть хттп.ответ_403() } пусть ответ = картотека.запросить безопасно(` DELETE FROM class_students WHERE class_id = ? AND student_id = ? RETURNING id `, оплошность, ид класса, ид ученика) если оплошность # "" { вернуть хттп.ответ_500() } если длина(ответ.значения) = 0 { вернуть хттп.ответ_404() } вернуть хттп.ответ_204() } фн добавить маршруты*(маршрутизатор: маршрутизатор.Маршрутизатор): маршрутизатор.Маршрутизатор { маршрутизатор.добавить маршрут("/api/classes", массивы.Строки["GET"], список классов) маршрутизатор.добавить маршрут("/api/classes", массивы.Строки["POST"], создать клass) маршрутизатор.добавить маршрут("/api/classes/$", массивы.Строки["DELETE"], удалить клass) маршрутизатор.добавить маршрут("/api/classes/$/students/$", массивы.Строки["POST"], добавить ученика в клass) маршрутизатор.добавить маршрут("/api/classes/$/students/$", массивы.Строки["DELETE"], удалить ученика из класса) вернуть маршрутизатор }