From 59c59fc4c1f3ce3a332b1b7412fdd1fef4d4fc3e Mon Sep 17 00:00:00 2001 From: scffs Date: Mon, 1 Apr 2024 13:44:08 +0700 Subject: [PATCH 1/8] refactor: rename some functions and better file structure Signed-off-by: scffs --- apps/api/src/ApiError/ApiError.ts | 30 ++++++++++++++++++ .../src/models/DiaryUser/actions/get/index.ts | 3 ++ .../actions}/get/saveOrGetDiaryUser.ts | 1 - .../DiaryUser/actions}/get/saveOrGetGroup.ts | 1 - .../SPO/actions}/saveOrGetSPO.ts | 2 +- apps/api/src/models/SPO/index.ts | 1 + .../routes/lessons/service/get/getLessons.ts | 8 ++--- ...eGradebook.ts => getFordattedGradebook.ts} | 2 +- ...izeResponse.ts => getFormattedResponse.ts} | 24 ++++++++------ ...eTimetable.ts => getFormattedTimetable.ts} | 2 +- .../routes/lessons/service/helpers/index.ts | 4 ++- apps/api/src/routes/login/handler.ts | 12 +++---- .../api/src/routes/login/service/get/index.ts | 3 -- .../routes/login/service/helpers/helpers.ts | 4 +-- apps/api/src/routes/login/service/index.ts | 8 ++--- .../routes/login/service/save/saveUserData.ts | 6 ++-- apps/api/src/routes/logout/handler.ts | 4 +-- apps/api/src/routes/organization/handler.ts | 13 +++++--- .../src/routes/performance.current/handler.ts | 2 ++ .../modules/removeNotUsedTokens.ts | 3 +- bun.lockb | Bin 251968 -> 251968 bytes 21 files changed, 86 insertions(+), 47 deletions(-) rename apps/api/src/{routes/login/service => models/DiaryUser/actions}/get/saveOrGetDiaryUser.ts (92%) mode change 100755 => 100644 rename apps/api/src/{routes/login/service => models/DiaryUser/actions}/get/saveOrGetGroup.ts (91%) mode change 100755 => 100644 rename apps/api/src/{routes/login/service/get => models/SPO/actions}/saveOrGetSPO.ts (92%) mode change 100755 => 100644 rename apps/api/src/routes/lessons/service/helpers/{structurizeGradebook.ts => getFordattedGradebook.ts} (96%) rename apps/api/src/routes/lessons/service/helpers/{structurizeResponse.ts => getFormattedResponse.ts} (76%) rename apps/api/src/routes/lessons/service/helpers/{structurizeTimetable.ts => getFormattedTimetable.ts} (84%) delete mode 100644 apps/api/src/routes/login/service/get/index.ts diff --git a/apps/api/src/ApiError/ApiError.ts b/apps/api/src/ApiError/ApiError.ts index e189c166..4badc203 100755 --- a/apps/api/src/ApiError/ApiError.ts +++ b/apps/api/src/ApiError/ApiError.ts @@ -1,3 +1,5 @@ +import { API_CODES } from './types' + export class ApiError extends Error { code: number message: string @@ -9,3 +11,31 @@ export class ApiError extends Error { Object.setPrototypeOf(this, ApiError.prototype) } } + +export class NotFoundError extends ApiError { + constructor(message: string) { + super(message, API_CODES.NOT_FOUND) + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export class UnauthorizedError extends ApiError { + constructor(message: string) { + super(message, API_CODES.UNAUTHORIZED) + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class ForbiddenError extends ApiError { + constructor(message: string) { + super(message, API_CODES.FORBIDDEN) + Object.setPrototypeOf(this, ForbiddenError.prototype) + } +} + +export class UnknownError extends ApiError { + constructor(message: string) { + super(message, API_CODES.UNKNOWN_ERROR) + Object.setPrototypeOf(this, UnknownError.prototype) + } +} diff --git a/apps/api/src/models/DiaryUser/actions/get/index.ts b/apps/api/src/models/DiaryUser/actions/get/index.ts index 95439704..9a843f7e 100644 --- a/apps/api/src/models/DiaryUser/actions/get/index.ts +++ b/apps/api/src/models/DiaryUser/actions/get/index.ts @@ -1 +1,4 @@ export * from './getUserById' + +export * from './saveOrGetDiaryUser' +export * from './saveOrGetGroup' diff --git a/apps/api/src/routes/login/service/get/saveOrGetDiaryUser.ts b/apps/api/src/models/DiaryUser/actions/get/saveOrGetDiaryUser.ts old mode 100755 new mode 100644 similarity index 92% rename from apps/api/src/routes/login/service/get/saveOrGetDiaryUser.ts rename to apps/api/src/models/DiaryUser/actions/get/saveOrGetDiaryUser.ts index b77738b6..48e2a49a --- a/apps/api/src/routes/login/service/get/saveOrGetDiaryUser.ts +++ b/apps/api/src/models/DiaryUser/actions/get/saveOrGetDiaryUser.ts @@ -4,7 +4,6 @@ import { type IDiaryUserModel } from '@models' import type { Optional } from 'sequelize' -// ВЫНЕСТИ В МОДЕЛЬ юзера export const saveOrGetDiaryUser = async ( data: Optional diff --git a/apps/api/src/routes/login/service/get/saveOrGetGroup.ts b/apps/api/src/models/DiaryUser/actions/get/saveOrGetGroup.ts old mode 100755 new mode 100644 similarity index 91% rename from apps/api/src/routes/login/service/get/saveOrGetGroup.ts rename to apps/api/src/models/DiaryUser/actions/get/saveOrGetGroup.ts index 90b29e67..808212a2 --- a/apps/api/src/routes/login/service/get/saveOrGetGroup.ts +++ b/apps/api/src/models/DiaryUser/actions/get/saveOrGetGroup.ts @@ -1,5 +1,4 @@ import { GroupModel, type IGroupModel } from '@models' -// ВЫНЕСТИ В МОДЕЛЬ группы export const saveOrGetGroup = async ( id: number, diff --git a/apps/api/src/routes/login/service/get/saveOrGetSPO.ts b/apps/api/src/models/SPO/actions/saveOrGetSPO.ts old mode 100755 new mode 100644 similarity index 92% rename from apps/api/src/routes/login/service/get/saveOrGetSPO.ts rename to apps/api/src/models/SPO/actions/saveOrGetSPO.ts index 0a39c50b..e1e1215c --- a/apps/api/src/routes/login/service/get/saveOrGetSPO.ts +++ b/apps/api/src/models/SPO/actions/saveOrGetSPO.ts @@ -1,6 +1,6 @@ import { type ISPOModel, SPOModel, type SPOModelType } from '@models' import type { Optional } from 'sequelize' -// ВЫНЕСТИ В МОДЕЛЬ СПО + export const saveOrGetSPO = async ( data: Optional ): Promise => { diff --git a/apps/api/src/models/SPO/index.ts b/apps/api/src/models/SPO/index.ts index 116e6686..6baa9d83 100755 --- a/apps/api/src/models/SPO/index.ts +++ b/apps/api/src/models/SPO/index.ts @@ -1 +1,2 @@ export * from './model' +export * from './actions/saveOrGetSPO' diff --git a/apps/api/src/routes/lessons/service/get/getLessons.ts b/apps/api/src/routes/lessons/service/get/getLessons.ts index 4032970e..c253a100 100755 --- a/apps/api/src/routes/lessons/service/get/getLessons.ts +++ b/apps/api/src/routes/lessons/service/get/getLessons.ts @@ -1,11 +1,11 @@ -import { API_CODES, API_ERRORS, ApiError } from '@api' +import { API_CODES, API_ERRORS, ApiError, ForbiddenError } from '@api' import { SERVER_URL } from '@config' import type { Day } from '@diary-spo/shared' import type { ICacheData } from '@helpers' import { ScheduleGetFromDB, daySave } from '@models' import { HeadersWithCookie } from '@utils' import { detectTerm } from 'src/models/Term/actions/other/detectTerm' -import { structurizeResponse } from '../helpers' +import { getFormattedResponse } from '../helpers' export const getLessonsService = async ( startDate: string, @@ -20,13 +20,13 @@ export const getLessonsService = async ( }) if (response.status === API_CODES.FORBIDDEN) { - throw new ApiError(API_ERRORS.USER_NOT_PERMISSION, API_CODES.FORBIDDEN) + throw new ForbiddenError(API_ERRORS.USER_NOT_PERMISSION) } if (!response.ok && !notGetFromDB) { // Получаем из базы const rawSchedule = await ScheduleGetFromDB(startDate, endDate, authData) - return structurizeResponse(rawSchedule, startDate, endDate, authData) + return getFormattedResponse(rawSchedule, startDate, endDate, authData) } // Сохраняем и отдаём diff --git a/apps/api/src/routes/lessons/service/helpers/structurizeGradebook.ts b/apps/api/src/routes/lessons/service/helpers/getFordattedGradebook.ts similarity index 96% rename from apps/api/src/routes/lessons/service/helpers/structurizeGradebook.ts rename to apps/api/src/routes/lessons/service/helpers/getFordattedGradebook.ts index fe6f8b7c..40a10257 100644 --- a/apps/api/src/routes/lessons/service/helpers/structurizeGradebook.ts +++ b/apps/api/src/routes/lessons/service/helpers/getFordattedGradebook.ts @@ -1,7 +1,7 @@ import type { Gradebook, Task } from '@diary-spo/shared' import type { ScheduleFromDB } from '@models' -export const structurizeGradebook = ( +export const getFordattedGradebook = ( rd: ScheduleFromDB ): Gradebook | undefined => { if (rd.gradebookIdFromDiary) { diff --git a/apps/api/src/routes/lessons/service/helpers/structurizeResponse.ts b/apps/api/src/routes/lessons/service/helpers/getFormattedResponse.ts similarity index 76% rename from apps/api/src/routes/lessons/service/helpers/structurizeResponse.ts rename to apps/api/src/routes/lessons/service/helpers/getFormattedResponse.ts index 6142b7e9..8204a81c 100644 --- a/apps/api/src/routes/lessons/service/helpers/structurizeResponse.ts +++ b/apps/api/src/routes/lessons/service/helpers/getFormattedResponse.ts @@ -1,17 +1,18 @@ -import { type Day, type Lesson, Task, Timetable } from '@diary-spo/shared' +import type { Day, Lesson } from '@diary-spo/shared' import type { ICacheData } from '@helpers' import type { ScheduleFromDB } from '@models' import { formatDate } from '@utils' -import { structurizeGradebook } from './structurizeGradebook' -import { structurizeTimetable } from './structurizeTimetable' -export const structurizeResponse = ( +import { getFordattedGradebook } from './getFordattedGradebook' +import { getFormattedTimetable } from './getFormattedTimetable' + +export const getFormattedResponse = ( raw: ScheduleFromDB[], startDate: string, endDate: string, authData: ICacheData ) => { - const Days: Day[] = [] + const days: Day[] = [] // Подготавливаем даты const sd = new Date(startDate) @@ -27,14 +28,17 @@ export const structurizeResponse = ( const lessons: Lesson[] = [] for (const rd of raw) { if (rd.date !== date) continue + if (rd.scheduleSubgroups.length) { let meSubgroup = false + for (const subgroup of rd.scheduleSubgroups) { if (subgroup.diaryUserId === authData.localUserId) { meSubgroup = true break } } + if (!meSubgroup) continue } @@ -43,10 +47,10 @@ export const structurizeResponse = ( const name = rd.subject.name // Градебук - const gradebook = structurizeGradebook(rd) + const gradebook = getFordattedGradebook(rd) //Подготавливаем timetable - const timetable = structurizeTimetable(rd) + const timetable = getFormattedTimetable(rd) const lesson: Lesson = { endTime, @@ -61,14 +65,14 @@ export const structurizeResponse = ( // Сортируем lessons lessons.sort((a, b) => (a.startTime > b.startTime ? 1 : -1)) - Days.push({ + days.push({ date, lessons }) } // Сортируем дни - Days.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()) + days.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()) - return Days + return days } diff --git a/apps/api/src/routes/lessons/service/helpers/structurizeTimetable.ts b/apps/api/src/routes/lessons/service/helpers/getFormattedTimetable.ts similarity index 84% rename from apps/api/src/routes/lessons/service/helpers/structurizeTimetable.ts rename to apps/api/src/routes/lessons/service/helpers/getFormattedTimetable.ts index 0a9d14f6..6bee28fa 100644 --- a/apps/api/src/routes/lessons/service/helpers/structurizeTimetable.ts +++ b/apps/api/src/routes/lessons/service/helpers/getFormattedTimetable.ts @@ -1,7 +1,7 @@ import type { Timetable } from '@diary-spo/shared' import type { ScheduleFromDB } from '@models' -export const structurizeTimetable = (rs: ScheduleFromDB): Timetable => { +export const getFormattedTimetable = (rs: ScheduleFromDB): Timetable => { const { building, name: clName, idFromDiary: id } = rs.classroom const { firstName, lastName, middleName } = rs.teacher return { diff --git a/apps/api/src/routes/lessons/service/helpers/index.ts b/apps/api/src/routes/lessons/service/helpers/index.ts index 1ee3e10e..fe762636 100644 --- a/apps/api/src/routes/lessons/service/helpers/index.ts +++ b/apps/api/src/routes/lessons/service/helpers/index.ts @@ -1 +1,3 @@ -export * from './structurizeResponse' +export * from './getFormattedResponse' +export * from './getFordattedGradebook' +export * from './getFormattedTimetable' diff --git a/apps/api/src/routes/login/handler.ts b/apps/api/src/routes/login/handler.ts index a73d1bd2..5500a623 100755 --- a/apps/api/src/routes/login/handler.ts +++ b/apps/api/src/routes/login/handler.ts @@ -1,11 +1,11 @@ -import { API_CODES, API_ERRORS, ApiError } from '@api' +import { API_ERRORS, NotFoundError, UnknownError } from '@api' import { SERVER_URL } from '@config' import { b64 } from '@diary-spo/crypto' import type { ResponseLogin, UserData } from '@diary-spo/shared' import { fetcher } from '@utils' import { offlineAuth } from './service' -import { handleResponse } from './service/helpers/helpers' -import { saveUserData } from './service/save/saveUserData' +import { handleResponse } from './service/helpers' +import { saveUserData } from './service/save' interface AuthContext { body: { @@ -37,14 +37,14 @@ const postAuth = async ({ body }: AuthContext): Promise => { const authData = await offlineAuth(login, password) if (!authData) { - throw new ApiError(API_ERRORS.USER_NOT_FOUND, API_CODES.UNAUTHORIZED) + throw new NotFoundError(API_ERRORS.USER_NOT_FOUND) } return authData } /** Неизвестная ошибка **/ case 'UNKNOWN': - throw new ApiError('Unknown auth error', API_CODES.UNKNOWN_ERROR) + throw new UnknownError('Unknown auth error') /** Сервер вернул корректные данные, сохраняем их в БД **/ default: /** @@ -52,7 +52,7 @@ const postAuth = async ({ body }: AuthContext): Promise => { * Поэтому проверяем хотя бы наличие одного обязательного поля **/ if (!parsedRes.data.tenants) { - throw new ApiError('Unreachable auth error', API_CODES.UNKNOWN_ERROR) + throw new UnknownError('Unreachable auth error') } return saveUserData(parsedRes, login, password) diff --git a/apps/api/src/routes/login/service/get/index.ts b/apps/api/src/routes/login/service/get/index.ts deleted file mode 100644 index 976938b8..00000000 --- a/apps/api/src/routes/login/service/get/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './saveOrGetDiaryUser' -export * from './saveOrGetGroup' -export * from './saveOrGetSPO' diff --git a/apps/api/src/routes/login/service/helpers/helpers.ts b/apps/api/src/routes/login/service/helpers/helpers.ts index 38df82a4..45215ad1 100755 --- a/apps/api/src/routes/login/service/helpers/helpers.ts +++ b/apps/api/src/routes/login/service/helpers/helpers.ts @@ -1,4 +1,4 @@ -import { API_CODES, ApiError } from '@api' +import { API_CODES, UnauthorizedError } from '@api' import type { ApiResponse } from '@utils' /** Обрабатывает ответ от сервера **/ @@ -11,7 +11,7 @@ export const handleResponse = ( /** Неправильные данные для авторизации **/ if (res === API_CODES.UNAUTHORIZED) { - throw new ApiError('Invalid data', API_CODES.UNAUTHORIZED) + throw new UnauthorizedError('Invalid data') } /** Сетевой город упал. Пробуем найти юзера в нашей базе **/ diff --git a/apps/api/src/routes/login/service/index.ts b/apps/api/src/routes/login/service/index.ts index f284f2f1..b16b6710 100755 --- a/apps/api/src/routes/login/service/index.ts +++ b/apps/api/src/routes/login/service/index.ts @@ -1,6 +1,7 @@ -import { API_CODES, API_ERRORS, ApiError } from '@api' +import { API_ERRORS, UnauthorizedError } from '@api' import { KEY } from '@config' -import type { ResponseLogin } from '@diary-spo/types' +import type { ResponseLogin } from '@diary-spo/shared' +import { generateToken } from '@helpers' import { DiaryUserModel, GroupModel, @@ -10,7 +11,6 @@ import { SPOModel } from '@models' import { ResponseLoginFromDiaryUser } from '@types' -import { generateToken } from '../../../helpers' type DiaryUserAuthInfo = IDiaryUserModel & { group: IGroupModel & { @@ -49,7 +49,7 @@ export const offlineAuth = async ( })) as DiaryUserAuthInfo if (!diaryUserRecord) { - throw new ApiError(API_ERRORS.USER_NOT_FOUND, API_CODES.UNAUTHORIZED) + throw new UnauthorizedError(API_ERRORS.USER_NOT_FOUND) } const groupData = diaryUserRecord.group diff --git a/apps/api/src/routes/login/service/save/saveUserData.ts b/apps/api/src/routes/login/service/save/saveUserData.ts index d5b01fff..bf8a4f2a 100755 --- a/apps/api/src/routes/login/service/save/saveUserData.ts +++ b/apps/api/src/routes/login/service/save/saveUserData.ts @@ -2,6 +2,8 @@ import { API_CODES, ApiError } from '@api' import { SERVER_URL } from '@config' import type { PersonResponse, UserData } from '@diary-spo/shared' import { generateToken } from '@helpers' +// TODO: сделать папку с утилитами может +import { saveOrGetDiaryUser, saveOrGetGroup, saveOrGetSPO } from '@models' import { ResponseLoginFromDiaryUser } from '@types' import { type ApiResponse, @@ -11,10 +13,6 @@ import { formatDate } from '@utils' import { LogError } from 'src/LogError' -// TODO: сделать папку с утилитами может -import { saveOrGetDiaryUser } from '../get/saveOrGetDiaryUser' -import { saveOrGetGroup } from '../get/saveOrGetGroup' -import { saveOrGetSPO } from '../get/saveOrGetSPO' export const saveUserData = async ( parsedRes: ApiResponse, diff --git a/apps/api/src/routes/logout/handler.ts b/apps/api/src/routes/logout/handler.ts index 2690cb5c..e4485989 100644 --- a/apps/api/src/routes/logout/handler.ts +++ b/apps/api/src/routes/logout/handler.ts @@ -1,7 +1,7 @@ -import { API_CODES, API_ERRORS, ApiError } from '@api' +import type { Context } from 'elysia' + import { getCookieFromToken } from '@helpers' import { authLogout } from '@models' -import type { Context } from 'elysia' const logoutHandler = async ({ request }: Context) => { const secret = request.headers.toJSON().secret diff --git a/apps/api/src/routes/organization/handler.ts b/apps/api/src/routes/organization/handler.ts index 461eb9c1..c85a0439 100755 --- a/apps/api/src/routes/organization/handler.ts +++ b/apps/api/src/routes/organization/handler.ts @@ -1,16 +1,18 @@ -import { API_CODES, API_ERRORS, ApiError } from '@api' -import { SERVER_URL } from '@config' import type { Organization } from '@diary-spo/shared' -import { checkSameKeys, getCookieFromToken } from '@helpers' +import type { Context } from 'elysia' +import type { Optional } from 'sequelize' + import { DiaryUserModel, GroupModel, SPOModel, type SPOModelType } from '@models' + +import { API_CODES, API_ERRORS, ApiError } from '@api' +import { SERVER_URL } from '@config' +import { getCookieFromToken } from '@helpers' import { HeadersWithCookie } from '@utils' -import type { Context } from 'elysia' -import type { Optional } from 'sequelize' const getOrganization = async ({ request @@ -41,6 +43,7 @@ const getOrganization = async ({ // Тут сохраняем в фоне, чтобы не задерживать // FIXME: это што........ + // ? const record = SPOModel.findOne({ where: { organizationId: response.organizationId diff --git a/apps/api/src/routes/performance.current/handler.ts b/apps/api/src/routes/performance.current/handler.ts index dece231b..c412cb14 100755 --- a/apps/api/src/routes/performance.current/handler.ts +++ b/apps/api/src/routes/performance.current/handler.ts @@ -1,6 +1,8 @@ import type { PerformanceCurrent } from '@diary-spo/shared' + import { getCookieFromToken } from '@helpers' import type { ContextWithID } from '@types' + import { getCurrPerformance } from './service' const getPerformanceCurrent = async ({ diff --git a/apps/api/src/worker/cookieUpdater/modules/removeNotUsedTokens.ts b/apps/api/src/worker/cookieUpdater/modules/removeNotUsedTokens.ts index 6652e005..5f3d67f1 100755 --- a/apps/api/src/worker/cookieUpdater/modules/removeNotUsedTokens.ts +++ b/apps/api/src/worker/cookieUpdater/modules/removeNotUsedTokens.ts @@ -21,7 +21,8 @@ export const removeNotUsedTokens = async (): Promise => { } for (let i = 0; i < tokens?.length; i++) { - await tokens[i].destroy() + await tokens[i] + .destroy() .then(() => { console.log(`Успешно удалил токен: ${tokens[i].token}`) }) diff --git a/bun.lockb b/bun.lockb index edd3538d2e98f52825ec6990e33ced593d1a29e5..804bc34b6eae2c73e73b35ca834c1b966e61958c 100755 GIT binary patch delta 7422 zcmZu$33yFM-#>G1uG|wuLL$;cZLL?3EBlFDTw9fps_rG0NG@)(ZR!|Sn0MJ&TiOGq! zqzp;w3hctUlQS~xHk<(L2J8ab0(8P0Aw4lJlna+m(p*=sPH#a6zH696mz#41PMNGR zN%6G8wL{?id~x>28MdT2EMx<>#I96Ou3@Z$rcCy?CuM|76R6UvL-zeI#mRjjn{(R| zrl;FuBw_6|8?7Kwd>VKw*Pa0hOM zbywhKpqP)$fjSw}Q*7xqi^YO&#y{0ho|rj_o2#2~3H;nCO*4gyYiL6&uWa9?Vs>gK zbi|)46M;wq8 zxke9H2-gIy6OpY0=IcKLb4MNnD;nf%=1%=Hwp(m0Ogg?&cPp-FqIoBRXMbZor1iIi%Cnf#l*$g z)3Q@~77O)uf%1sNBu!6@$%vg2lP0ph1RJ^ex8Z1RMhz%eFexS}nV06&&Emi~+oVi> zP&_aM~3*v*%IwLu#ZQubgPh82#SfTU-~s9h>H^9m zPC&WKkTJ;e1Y1^tIOXF#Ld!%@F28xEm`}nw*J?Z{Jm8XZajzu3go!h>lZRKfVZRX9 zv`?_>iD^6_w%u^d!;hK~$1%^<7zS}|L5nJddLs`?(#ybobA)t%;LgD5Q_(77Ca1pw z%+>aB&^+wJdQi^MLz2`13oAgogLXTDSj%a;P zi?SP|5X?K%5^&uFiU4Y+Y0!1HB!vMvX($>fQsYehP*pYny$K}Kz=0}xK<&&*`qCo& zH;vXZtFkRm$dzeov`VU}eVJA1io1tPhrIbJvC~@2t;8JHT&4~Fs&dZ30ozhl#dWUm zF0AUID*b`DHUdor>H|b5x2F^+g8Fy2K$D{7RuW8Wms^$Gd6G0x<4FxumBT>XQbHSG zX_Esv(Gr~7BVUrju_kk5TnQ9OxAYZ&qPI%yhs&)4NO^ioY@fVfB5W?)@2~d>* zKn@dnsN{3%x5}!#z}z5kw4f!isxokaBn{OhbN+ciqcz0cas?=aZh>3cQTuAEGJ2s% zDT%@WvX|CkPFW;QFw&ACsuBez56zC;u47A0)4h$EteLsEc3X#H}F zvJNBeMa^5rdqBuBi$w{iB6CDu&jjKoA>ut%

b>qF6I65jjh^@y2kV!8EalMfn6H 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 I45jk_0*;`4x&QzG delta 7415 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 F{{h5;cCr8f From d588a840b33480a743d1b1335f31c3c626ff1d06 Mon Sep 17 00:00:00 2001 From: scffs Date: Mon, 1 Apr 2024 14:04:33 +0700 Subject: [PATCH 2/8] refactor: rename some functions and better file structure Signed-off-by: scffs --- apps/api/src/models/Absence/model.ts | 4 +++- ...AbsenceType.ts => absenceTypeSaveOrGet.ts} | 2 +- .../models/AbsenceType/actions/save/index.ts | 2 +- apps/api/src/models/AcademicYear/index.ts | 2 +- apps/api/src/models/AcademicYear/model.ts | 4 +++- .../models/Ads/actions/get/adsGetFromDB.ts | 5 ++--- .../api/src/models/Ads/actions/save/saveAd.ts | 8 ++------ apps/api/src/models/Ads/model.ts | 4 +++- apps/api/src/models/Auth/model.ts | 4 +++- apps/api/src/models/Classroom/model.ts | 1 + .../DiaryUser/actions/get/getUserById.ts | 7 +++---- apps/api/src/models/DiaryUser/model.ts | 1 + .../actions/save/saveOrGetExaminationType.ts | 5 ++--- .../actions/save/saveOrGetFinalMark.ts | 3 +++ .../models/Mark/actions/delete/markDelete.ts | 3 +-- .../models/Mark/actions/save/markSaveOrGet.ts | 3 +-- .../actions/save/requiredSaveOrGet.ts | 1 + .../Schedule/actions/delete/deleteOldDays.ts | 10 ++++++---- .../Schedule/actions/get/scheduleGetFromDB.ts | 1 + .../actions/other/checkInSubgroups.ts | 1 + .../Schedule/actions/save/lessonSave.ts | 7 ++++--- .../actions/delete/deleteScheduleSubgroup.ts | 5 ++--- .../actions/save/subgroupSaveOrGet.ts | 1 + .../delete/{deleteNotIn.ts => deleteTasks.ts} | 2 +- .../src/models/Task/actions/delete/index.ts | 2 +- .../Task/actions/save/tasksSaveOrGet.ts | 4 ++-- .../Teacher/actions/save/teacherSaveOrGet.ts | 1 - .../Term/actions/get/searchCurrStartDate.ts | 1 + .../models/Term/actions/other/detectTerm.ts | 5 +++-- .../{deleteNotIn.ts => deleteThemes.ts} | 2 +- .../src/models/Theme/actions/delete/index.ts | 2 +- .../Theme/actions/save/themesSaveOrGet.ts | 4 ++-- .../finalMarks/service/get/getFinalMarks.ts | 3 +-- .../service/get/getPerformanceCurrent.ts | 4 ++-- .../service/get/getPerformanceFromDB.ts | 4 ++-- ...izeResponse.ts => getFormattedResponse.ts} | 2 +- .../service/helpers/index.ts | 2 +- .../performance.current/service/index.ts | 4 ++-- .../performance.current/service/save/index.ts | 2 +- .../{savePerfomance.ts => savePerformance.ts} | 20 +++++++++---------- 40 files changed, 79 insertions(+), 69 deletions(-) rename apps/api/src/models/AbsenceType/actions/save/{saveOrGetAbsenceType.ts => absenceTypeSaveOrGet.ts} (87%) mode change 100755 => 100644 rename apps/api/src/models/Task/actions/delete/{deleteNotIn.ts => deleteTasks.ts} (84%) mode change 100755 => 100644 rename apps/api/src/models/Theme/actions/delete/{deleteNotIn.ts => deleteThemes.ts} (77%) mode change 100755 => 100644 rename apps/api/src/routes/performance.current/service/helpers/{structurizeResponse.ts => getFormattedResponse.ts} (99%) mode change 100755 => 100644 rename apps/api/src/routes/performance.current/service/save/{savePerfomance.ts => savePerformance.ts} (91%) mode change 100755 => 100644 diff --git a/apps/api/src/models/Absence/model.ts b/apps/api/src/models/Absence/model.ts index d0f7ac43..61034c3d 100755 --- a/apps/api/src/models/Absence/model.ts +++ b/apps/api/src/models/Absence/model.ts @@ -1,8 +1,10 @@ -import { cache, enableCache, sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { cache, enableCache, sequelize } from '@db' import { AbsenceTypeModel } from '../AbsenceType' import { DiaryUserModel } from '../DiaryUser' import { ScheduleModel } from '../Schedule' + import type { IModelPrototype } from '../types' export type AbsenceModelType = { diff --git a/apps/api/src/models/AbsenceType/actions/save/saveOrGetAbsenceType.ts b/apps/api/src/models/AbsenceType/actions/save/absenceTypeSaveOrGet.ts old mode 100755 new mode 100644 similarity index 87% rename from apps/api/src/models/AbsenceType/actions/save/saveOrGetAbsenceType.ts rename to apps/api/src/models/AbsenceType/actions/save/absenceTypeSaveOrGet.ts index 2211da84..b1b71e43 --- a/apps/api/src/models/AbsenceType/actions/save/saveOrGetAbsenceType.ts +++ b/apps/api/src/models/AbsenceType/actions/save/absenceTypeSaveOrGet.ts @@ -1,7 +1,7 @@ import type { AbsenceTypesKeys } from '@diary-spo/shared' import { AbsenceTypeModel, type IAbsenceTypeModel } from '@models' -export const saveOrGetAbsenceType = async ( +export const absenceTypeSaveOrGet = async ( name: AbsenceTypesKeys ): Promise => AbsenceTypeModel.findOrCreate({ diff --git a/apps/api/src/models/AbsenceType/actions/save/index.ts b/apps/api/src/models/AbsenceType/actions/save/index.ts index dc52bcb1..4b90c742 100644 --- a/apps/api/src/models/AbsenceType/actions/save/index.ts +++ b/apps/api/src/models/AbsenceType/actions/save/index.ts @@ -1 +1 @@ -export * from './saveOrGetAbsenceType' +export * from './absenceTypeSaveOrGet' diff --git a/apps/api/src/models/AcademicYear/index.ts b/apps/api/src/models/AcademicYear/index.ts index 36678b92..9380a26d 100755 --- a/apps/api/src/models/AcademicYear/index.ts +++ b/apps/api/src/models/AcademicYear/index.ts @@ -1,2 +1,2 @@ export * from './model' -//export * from './actions' +export * from './actions' diff --git a/apps/api/src/models/AcademicYear/model.ts b/apps/api/src/models/AcademicYear/model.ts index 3f961b0e..ca0a5602 100755 --- a/apps/api/src/models/AcademicYear/model.ts +++ b/apps/api/src/models/AcademicYear/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { GroupModel } from '../Group' import { TermTypeModel } from '../TermType' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/models/Ads/actions/get/adsGetFromDB.ts b/apps/api/src/models/Ads/actions/get/adsGetFromDB.ts index d7f4a33d..38b585a1 100755 --- a/apps/api/src/models/Ads/actions/get/adsGetFromDB.ts +++ b/apps/api/src/models/Ads/actions/get/adsGetFromDB.ts @@ -1,8 +1,8 @@ import type { ICacheData } from '@helpers' import { AdsModel } from '@models' -export const adsGetFromDB = async (authData: ICacheData) => { - return AdsModel.findAll({ +export const adsGetFromDB = async (authData: ICacheData) => + AdsModel.findAll({ where: { spoId: authData.spoId }, @@ -12,4 +12,3 @@ export const adsGetFromDB = async (authData: ICacheData) => { }, order: [['date', 'DESC']] }) -} diff --git a/apps/api/src/models/Ads/actions/save/saveAd.ts b/apps/api/src/models/Ads/actions/save/saveAd.ts index a5201eed..8ad36f34 100755 --- a/apps/api/src/models/Ads/actions/save/saveAd.ts +++ b/apps/api/src/models/Ads/actions/save/saveAd.ts @@ -2,9 +2,5 @@ import type { NotificationsResponse } from '@diary-spo/shared' import { type ICacheData, retriesForError } from '@helpers' import { adSaveOrGer } from './' -export const saveAd = async ( - ad: NotificationsResponse, - authData: ICacheData -) => { - return retriesForError(adSaveOrGer, [ad, authData]) -} +export const saveAd = async (ad: NotificationsResponse, authData: ICacheData) => + retriesForError(adSaveOrGer, [ad, authData]) diff --git a/apps/api/src/models/Ads/model.ts b/apps/api/src/models/Ads/model.ts index 42aad241..19fce1c2 100755 --- a/apps/api/src/models/Ads/model.ts +++ b/apps/api/src/models/Ads/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { SPOModel } from '../SPO' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/models/Auth/model.ts b/apps/api/src/models/Auth/model.ts index 8924e5cb..841b4381 100755 --- a/apps/api/src/models/Auth/model.ts +++ b/apps/api/src/models/Auth/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { DiaryUserModel } from '../DiaryUser' import type { IModelPrototypeNoId } from '../types' diff --git a/apps/api/src/models/Classroom/model.ts b/apps/api/src/models/Classroom/model.ts index 6f48f0ad..28386683 100755 --- a/apps/api/src/models/Classroom/model.ts +++ b/apps/api/src/models/Classroom/model.ts @@ -4,6 +4,7 @@ import { SPOModel } from '../SPO' import type { IModelPrototype } from '../types' // REMOVE IT +// ? export type ClassroomModelType = { id: bigint building: string diff --git a/apps/api/src/models/DiaryUser/actions/get/getUserById.ts b/apps/api/src/models/DiaryUser/actions/get/getUserById.ts index e0638624..9d158ba1 100755 --- a/apps/api/src/models/DiaryUser/actions/get/getUserById.ts +++ b/apps/api/src/models/DiaryUser/actions/get/getUserById.ts @@ -7,15 +7,14 @@ import { export type IUserInfo = DiaryUserModelType & { group?: GroupModelType } +// не используется нигде export const getUserById = async ( id: bigint, getGroup = false -): Promise => { - // TODO: fix it - return DiaryUserModel.findOne({ +): Promise => + DiaryUserModel.findOne({ where: { id }, include: getGroup ? GroupModel : undefined }) -} diff --git a/apps/api/src/models/DiaryUser/model.ts b/apps/api/src/models/DiaryUser/model.ts index 7e1057f6..c139dae4 100755 --- a/apps/api/src/models/DiaryUser/model.ts +++ b/apps/api/src/models/DiaryUser/model.ts @@ -7,6 +7,7 @@ import { GroupModel } from '../Group' import type { IModelPrototype } from '../types' // REMOVE IT +// ? export type DiaryUserModelType = { id: bigint groupId: bigint diff --git a/apps/api/src/models/Examination/actions/save/saveOrGetExaminationType.ts b/apps/api/src/models/Examination/actions/save/saveOrGetExaminationType.ts index 2e60265e..d92cdc8e 100755 --- a/apps/api/src/models/Examination/actions/save/saveOrGetExaminationType.ts +++ b/apps/api/src/models/Examination/actions/save/saveOrGetExaminationType.ts @@ -1,8 +1,8 @@ import type { ExaminationKeys } from '@diary-spo/shared' import { ExaminationTypeModel } from '../../model' -export const saveOrGetExaminationType = async (type: ExaminationKeys) => { - return ExaminationTypeModel.findOrCreate({ +export const saveOrGetExaminationType = async (type: ExaminationKeys) => + ExaminationTypeModel.findOrCreate({ where: { name: type }, @@ -10,4 +10,3 @@ export const saveOrGetExaminationType = async (type: ExaminationKeys) => { name: type } }).then((v) => v[0]) -} diff --git a/apps/api/src/models/FinalMark/actions/save/saveOrGetFinalMark.ts b/apps/api/src/models/FinalMark/actions/save/saveOrGetFinalMark.ts index ade0870e..fdd6e5b3 100644 --- a/apps/api/src/models/FinalMark/actions/save/saveOrGetFinalMark.ts +++ b/apps/api/src/models/FinalMark/actions/save/saveOrGetFinalMark.ts @@ -6,13 +6,16 @@ export const saveOrGetFinalMark = async ( subjectId: bigint, authData: ICacheData ) => { + // why const where = { subjectId, diaryUserId: authData.localUserId } return FinalMarkModel.findOrCreate({ + // why where, defaults: { + // why ...where, markValueId } diff --git a/apps/api/src/models/Mark/actions/delete/markDelete.ts b/apps/api/src/models/Mark/actions/delete/markDelete.ts index 74b81948..95c8e591 100755 --- a/apps/api/src/models/Mark/actions/delete/markDelete.ts +++ b/apps/api/src/models/Mark/actions/delete/markDelete.ts @@ -1,11 +1,10 @@ import type { ICacheData } from '@helpers' import { MarkModel } from '@models' -export const markDelete = async (taskId: bigint, authData: ICacheData) => { +export const markDelete = async (taskId: bigint, authData: ICacheData) => MarkModel.destroy({ where: { taskId, diaryUserId: authData.localUserId } }) -} diff --git a/apps/api/src/models/Mark/actions/save/markSaveOrGet.ts b/apps/api/src/models/Mark/actions/save/markSaveOrGet.ts index 1a6b3f3b..4a22cd33 100755 --- a/apps/api/src/models/Mark/actions/save/markSaveOrGet.ts +++ b/apps/api/src/models/Mark/actions/save/markSaveOrGet.ts @@ -1,8 +1,7 @@ import type { MarkKeys } from '@diary-spo/shared' import { type ICacheData, retriesForError } from '@helpers' +import { type IScheduleModel, markValueSaveOrGet } from '@models' import { formatDate } from '@utils' -import { markValueSaveOrGet } from 'src/models/MarkValue' -import type { IScheduleModel } from 'src/models/Schedule' import { markSaveOrGetUnSafe } from './markSaveOrGetUnSafe' export const markSaveOrGet = async ( diff --git a/apps/api/src/models/Required/actions/save/requiredSaveOrGet.ts b/apps/api/src/models/Required/actions/save/requiredSaveOrGet.ts index 3a77f528..42a708e4 100755 --- a/apps/api/src/models/Required/actions/save/requiredSaveOrGet.ts +++ b/apps/api/src/models/Required/actions/save/requiredSaveOrGet.ts @@ -10,6 +10,7 @@ export const requiredSaveOrGet = async ( taskId, diaryUserId: authData.localUserId } + return RequiredModel.findOrCreate({ where, defaults: { diff --git a/apps/api/src/models/Schedule/actions/delete/deleteOldDays.ts b/apps/api/src/models/Schedule/actions/delete/deleteOldDays.ts index b45f648a..d21c2bd5 100755 --- a/apps/api/src/models/Schedule/actions/delete/deleteOldDays.ts +++ b/apps/api/src/models/Schedule/actions/delete/deleteOldDays.ts @@ -12,10 +12,12 @@ export const deleteOldDays = async ( schedules: (IScheduleModel | null)[], authModel: ICacheData ) => { - // Если расписания нет в списке id'шников в schedules - // и у расписания не тсвязанной подгруппы или подгруппа - // принадлежит текущему пользователю, то удаляем - //console.log(JSON.stringify(schedules, null, 2)) + /** + * Если расписания нет в списке id'шников в schedules + * и у расписания не тсвязанной подгруппы или подгруппа + * принадлежит текущему пользователю, то удаляем + * console.log(JSON.stringify(schedules, null, 2)) + */ const ids = [] let date = null diff --git a/apps/api/src/models/Schedule/actions/get/scheduleGetFromDB.ts b/apps/api/src/models/Schedule/actions/get/scheduleGetFromDB.ts index d47603b2..b33ba828 100755 --- a/apps/api/src/models/Schedule/actions/get/scheduleGetFromDB.ts +++ b/apps/api/src/models/Schedule/actions/get/scheduleGetFromDB.ts @@ -84,3 +84,4 @@ export const ScheduleGetFromDB = async ( ] })) as ScheduleFromDB[] } +// нужен хороший комментарий насчет этой функции (и других функций) + избавление от as diff --git a/apps/api/src/models/Schedule/actions/other/checkInSubgroups.ts b/apps/api/src/models/Schedule/actions/other/checkInSubgroups.ts index 1fb93f32..c04c45ce 100755 --- a/apps/api/src/models/Schedule/actions/other/checkInSubgroups.ts +++ b/apps/api/src/models/Schedule/actions/other/checkInSubgroups.ts @@ -9,5 +9,6 @@ export const checkInSubgroups = ( return true } } + return false } diff --git a/apps/api/src/models/Schedule/actions/save/lessonSave.ts b/apps/api/src/models/Schedule/actions/save/lessonSave.ts index c92939c6..96512060 100755 --- a/apps/api/src/models/Schedule/actions/save/lessonSave.ts +++ b/apps/api/src/models/Schedule/actions/save/lessonSave.ts @@ -6,7 +6,7 @@ import { type ITermDetectP, ScheduleModel, type ScheduleWhere, - saveOrGetAbsenceType as absenceTypeSaveOrGet, + absenceTypeSaveOrGet, deleteAbsence, deleteScheduleSubgroup, detectSubgroup, @@ -23,8 +23,10 @@ import { /** * Сохраняет и обновляет занятие в базе данных. + * @param date * @param lesson - Занятие для сохранения * @param authData - Данные, предоставленные клиентом для авторизации + * @param termPromise * @returns Promise */ export const lessonSave = async ( @@ -42,7 +44,6 @@ export const lessonSave = async ( } // Извлекаем нужные нам данные из lesson - let subjectId: Nullable = null let teacherId: Nullable = null let classroomId: Nullable = null let lessonTypeId: Nullable = null @@ -54,7 +55,7 @@ export const lessonSave = async ( const subgroup = detectSubgroup(subject) // Получаем id в базе для полученных из lesson данных - subjectId = (await retriesForError(subjectSaveOrGet, [subject], 2)).id + const subjectId = (await retriesForError(subjectSaveOrGet, [subject], 2)).id if (lesson.timetable.teacher) { const LessonTeacher = { diff --git a/apps/api/src/models/ScheduleSubgroup/actions/delete/deleteScheduleSubgroup.ts b/apps/api/src/models/ScheduleSubgroup/actions/delete/deleteScheduleSubgroup.ts index 6651bb9c..fd559de3 100755 --- a/apps/api/src/models/ScheduleSubgroup/actions/delete/deleteScheduleSubgroup.ts +++ b/apps/api/src/models/ScheduleSubgroup/actions/delete/deleteScheduleSubgroup.ts @@ -3,11 +3,10 @@ import { ScheduleSubgroupModel } from '@models' export const deleteScheduleSubgroup = async ( scheduleId: bigint, diaryUserId: bigint -) => { - return ScheduleSubgroupModel.destroy({ +) => + ScheduleSubgroupModel.destroy({ where: { scheduleId, diaryUserId } }) -} diff --git a/apps/api/src/models/Subgroup/actions/save/subgroupSaveOrGet.ts b/apps/api/src/models/Subgroup/actions/save/subgroupSaveOrGet.ts index b4e0bc1d..244752d2 100755 --- a/apps/api/src/models/Subgroup/actions/save/subgroupSaveOrGet.ts +++ b/apps/api/src/models/Subgroup/actions/save/subgroupSaveOrGet.ts @@ -8,6 +8,7 @@ export const subgroupSaveOrGet = ( name, groupId } + return SubgroupModel.findOrCreate({ where, defaults: where diff --git a/apps/api/src/models/Task/actions/delete/deleteNotIn.ts b/apps/api/src/models/Task/actions/delete/deleteTasks.ts old mode 100755 new mode 100644 similarity index 84% rename from apps/api/src/models/Task/actions/delete/deleteNotIn.ts rename to apps/api/src/models/Task/actions/delete/deleteTasks.ts index cc908dad..cf6460e4 --- a/apps/api/src/models/Task/actions/delete/deleteNotIn.ts +++ b/apps/api/src/models/Task/actions/delete/deleteTasks.ts @@ -2,7 +2,7 @@ import type { Task } from '@diary-spo/shared' import { TaskModel } from '@models' import { Op } from 'sequelize' -export const deleteTasksNotIn = async (tasks: Task[], scheduleId: bigint) => { +export const deleteTasks = async (tasks: Task[], scheduleId: bigint) => { const ids = tasks.map((v) => v.id) // Оригинальные id'шники заданий return TaskModel.destroy({ diff --git a/apps/api/src/models/Task/actions/delete/index.ts b/apps/api/src/models/Task/actions/delete/index.ts index cb3a31cb..67cce063 100644 --- a/apps/api/src/models/Task/actions/delete/index.ts +++ b/apps/api/src/models/Task/actions/delete/index.ts @@ -1 +1 @@ -export * from './deleteNotIn' +export * from './deleteTasks' diff --git a/apps/api/src/models/Task/actions/save/tasksSaveOrGet.ts b/apps/api/src/models/Task/actions/save/tasksSaveOrGet.ts index 305d32b4..b6fbe2ed 100755 --- a/apps/api/src/models/Task/actions/save/tasksSaveOrGet.ts +++ b/apps/api/src/models/Task/actions/save/tasksSaveOrGet.ts @@ -3,7 +3,7 @@ import { type ICacheData, retriesForError } from '@helpers' import { type IScheduleModel, type ITermDetectP, - deleteTasksNotIn, + deleteTasks, markSaveOrGet, requiredSaveOrGet } from '@models' @@ -23,7 +23,7 @@ export const tasksSaveOrGet = async ( // Удаляем устаревшие таски // TODO: проверить работоспособность после исправления - deleteTasksNotIn(tasks, scheduleId) + deleteTasks(tasks, scheduleId) for (const task of tasks) { const taskTypeId = ( diff --git a/apps/api/src/models/Teacher/actions/save/teacherSaveOrGet.ts b/apps/api/src/models/Teacher/actions/save/teacherSaveOrGet.ts index 65e8147f..2717d96b 100755 --- a/apps/api/src/models/Teacher/actions/save/teacherSaveOrGet.ts +++ b/apps/api/src/models/Teacher/actions/save/teacherSaveOrGet.ts @@ -1,6 +1,5 @@ import { TeacherModel, type TeacherModelType } from '@models' import { Op, type Optional } from 'sequelize' -import { LogError } from 'src/LogError' export const TeacherSaveOrGet = async ( teacher: Optional & diff --git a/apps/api/src/models/Term/actions/get/searchCurrStartDate.ts b/apps/api/src/models/Term/actions/get/searchCurrStartDate.ts index db41ce96..b1a759ea 100755 --- a/apps/api/src/models/Term/actions/get/searchCurrStartDate.ts +++ b/apps/api/src/models/Term/actions/get/searchCurrStartDate.ts @@ -1,6 +1,7 @@ import type { PerformanceCurrent } from '@diary-spo/shared' import type { ICacheData } from '@helpers' import { formatDate } from '@utils' +// с этим надо что-то делать import { getPerformanceCurrent } from 'src/routes/performance.current/service/get/getPerformanceCurrent' export const searchCurrStartDate = async (authDate: ICacheData) => { diff --git a/apps/api/src/models/Term/actions/other/detectTerm.ts b/apps/api/src/models/Term/actions/other/detectTerm.ts index 5929bbfa..d102d10f 100755 --- a/apps/api/src/models/Term/actions/other/detectTerm.ts +++ b/apps/api/src/models/Term/actions/other/detectTerm.ts @@ -2,9 +2,10 @@ import type { AcademicRecord } from '@diary-spo/shared' import { type ICacheData, updateCache } from '@helpers' import { DiaryUserModel, findActiveTerm } from '@models' import { formatDate } from '@utils' -import { saveOrGetAcademicYear } from 'src/models/AcademicYear/actions' + import { getFinalMarksFromDiary } from 'src/routes/finalMarks/service' -import { searchCurrStartDate } from '../get/searchCurrStartDate' +import { saveOrGetAcademicYear } from '../../../AcademicYear/actions' +import { searchCurrStartDate } from '../get' /** * Обновляет (если нужно) текущий семестр и отдаёт его diff --git a/apps/api/src/models/Theme/actions/delete/deleteNotIn.ts b/apps/api/src/models/Theme/actions/delete/deleteThemes.ts old mode 100755 new mode 100644 similarity index 77% rename from apps/api/src/models/Theme/actions/delete/deleteNotIn.ts rename to apps/api/src/models/Theme/actions/delete/deleteThemes.ts index 4c522d3b..c93986a5 --- a/apps/api/src/models/Theme/actions/delete/deleteNotIn.ts +++ b/apps/api/src/models/Theme/actions/delete/deleteThemes.ts @@ -1,7 +1,7 @@ import { ThemeModel } from '@models' import { Op } from 'sequelize' -export const deleteThemesNotIn = async (themes: string[], scheduleId: bigint) => +export const deleteThemes = async (themes: string[], scheduleId: bigint) => ThemeModel.destroy({ where: { [Op.and]: [ diff --git a/apps/api/src/models/Theme/actions/delete/index.ts b/apps/api/src/models/Theme/actions/delete/index.ts index cb3a31cb..30e044f8 100644 --- a/apps/api/src/models/Theme/actions/delete/index.ts +++ b/apps/api/src/models/Theme/actions/delete/index.ts @@ -1 +1 @@ -export * from './deleteNotIn' +export * from './deleteThemes' diff --git a/apps/api/src/models/Theme/actions/save/themesSaveOrGet.ts b/apps/api/src/models/Theme/actions/save/themesSaveOrGet.ts index 1cee1720..8c40cbc2 100755 --- a/apps/api/src/models/Theme/actions/save/themesSaveOrGet.ts +++ b/apps/api/src/models/Theme/actions/save/themesSaveOrGet.ts @@ -1,10 +1,10 @@ -import { ThemeModel, deleteThemesNotIn } from '@models' +import { ThemeModel, deleteThemes } from '@models' export const themesSaveOrGet = async (themes: string[], scheduleId: bigint) => { const promises = [] // Удаялем устаревшие темы - deleteThemesNotIn(themes, scheduleId) + deleteThemes(themes, scheduleId) for (const theme of themes) { const themeToSave = { diff --git a/apps/api/src/routes/finalMarks/service/get/getFinalMarks.ts b/apps/api/src/routes/finalMarks/service/get/getFinalMarks.ts index 33141683..f1ad2614 100755 --- a/apps/api/src/routes/finalMarks/service/get/getFinalMarks.ts +++ b/apps/api/src/routes/finalMarks/service/get/getFinalMarks.ts @@ -1,4 +1,3 @@ -import { API_CODES, API_ERRORS, ApiError } from '@api' import { SERVER_URL } from '@config' import type { AcademicRecord } from '@diary-spo/shared' import type { ICacheData } from '@helpers' @@ -6,7 +5,7 @@ import { HeadersWithCookie } from '@utils' export const getFinalMarksFromDiary = async (authData: ICacheData) => { const path = `${SERVER_URL}/services/students/${authData.idFromDiary}/attestation` - console.log(path) + const response = fetch(path, { headers: HeadersWithCookie(authData.cookie) }) diff --git a/apps/api/src/routes/performance.current/service/get/getPerformanceCurrent.ts b/apps/api/src/routes/performance.current/service/get/getPerformanceCurrent.ts index 01ff8bdc..891abe0c 100755 --- a/apps/api/src/routes/performance.current/service/get/getPerformanceCurrent.ts +++ b/apps/api/src/routes/performance.current/service/get/getPerformanceCurrent.ts @@ -5,8 +5,8 @@ import { HeadersWithCookie } from '@utils' export const getPerformanceCurrent = async (authData: ICacheData) => { const path = `${SERVER_URL}/services/reports/current/performance/${authData.idFromDiary}` console.log(path) - const response = fetch(path, { + + return fetch(path, { headers: HeadersWithCookie(authData.cookie) }) - return response } diff --git a/apps/api/src/routes/performance.current/service/get/getPerformanceFromDB.ts b/apps/api/src/routes/performance.current/service/get/getPerformanceFromDB.ts index 94c94ae5..cb614c50 100644 --- a/apps/api/src/routes/performance.current/service/get/getPerformanceFromDB.ts +++ b/apps/api/src/routes/performance.current/service/get/getPerformanceFromDB.ts @@ -11,7 +11,7 @@ import { detectTerm } from '@models' import { Op } from 'sequelize' -import { structurizeResponse } from '../helpers' +import { getFormattedResponse } from '../helpers' import type { IPerformanceFromDB } from '../types' export const getPerformanceFromDB = async (authData: ICacheData) => { @@ -69,5 +69,5 @@ export const getPerformanceFromDB = async (authData: ICacheData) => { } } })) as IPerformanceFromDB[] - return structurizeResponse(result, authData) + return getFormattedResponse(result, authData) } diff --git a/apps/api/src/routes/performance.current/service/helpers/structurizeResponse.ts b/apps/api/src/routes/performance.current/service/helpers/getFormattedResponse.ts old mode 100755 new mode 100644 similarity index 99% rename from apps/api/src/routes/performance.current/service/helpers/structurizeResponse.ts rename to apps/api/src/routes/performance.current/service/helpers/getFormattedResponse.ts index 6c355a66..cce4efbf --- a/apps/api/src/routes/performance.current/service/helpers/structurizeResponse.ts +++ b/apps/api/src/routes/performance.current/service/helpers/getFormattedResponse.ts @@ -11,7 +11,7 @@ import { monthNames } from '../types' -export const structurizeResponse = ( +export const getFormattedResponse = ( subjects: IPerformanceFromDB[], authData: ICacheData ) => { diff --git a/apps/api/src/routes/performance.current/service/helpers/index.ts b/apps/api/src/routes/performance.current/service/helpers/index.ts index 1ee3e10e..b09ac276 100644 --- a/apps/api/src/routes/performance.current/service/helpers/index.ts +++ b/apps/api/src/routes/performance.current/service/helpers/index.ts @@ -1 +1 @@ -export * from './structurizeResponse' +export * from './getFormattedResponse' diff --git a/apps/api/src/routes/performance.current/service/index.ts b/apps/api/src/routes/performance.current/service/index.ts index a441c49a..ccbefe18 100755 --- a/apps/api/src/routes/performance.current/service/index.ts +++ b/apps/api/src/routes/performance.current/service/index.ts @@ -2,7 +2,7 @@ import type { PerformanceCurrent } from '@diary-spo/shared' import type { ICacheData } from '@helpers' import { getPerformanceFromDB } from './get' import { getPerformanceCurrent } from './get/getPerformanceCurrent' -import { savePerfomance } from './save/savePerfomance' +import { savePerformance } from './save/savePerformance' export const getCurrPerformance = async ( authData: ICacheData @@ -17,7 +17,7 @@ export const getCurrPerformance = async ( const result = await response.json() // Сохраняем в базе - savePerfomance(result, authData) + savePerformance(result, authData) return result } diff --git a/apps/api/src/routes/performance.current/service/save/index.ts b/apps/api/src/routes/performance.current/service/save/index.ts index 2e734eae..27c28231 100644 --- a/apps/api/src/routes/performance.current/service/save/index.ts +++ b/apps/api/src/routes/performance.current/service/save/index.ts @@ -1 +1 @@ -export * from './savePerfomance' +export * from './savePerformance' diff --git a/apps/api/src/routes/performance.current/service/save/savePerfomance.ts b/apps/api/src/routes/performance.current/service/save/savePerformance.ts old mode 100755 new mode 100644 similarity index 91% rename from apps/api/src/routes/performance.current/service/save/savePerfomance.ts rename to apps/api/src/routes/performance.current/service/save/savePerformance.ts index df6bdbb6..34ba3e52 --- a/apps/api/src/routes/performance.current/service/save/savePerfomance.ts +++ b/apps/api/src/routes/performance.current/service/save/savePerformance.ts @@ -3,12 +3,12 @@ import type { ICacheData } from '@helpers' import { getLessonsService } from 'src/routes/lessons/service' import { getPerformanceFromDB } from '../get' +// разделить на разные файлы + /** * Сохраняет оценки в базе - * @param perfomance - * @param authData */ -export const savePerfomance = async ( +export const savePerformance = async ( performance: PerformanceCurrent, authData: ICacheData ) => { @@ -39,10 +39,10 @@ export const savePerfomance = async ( continue } - const isEquils = isEquilsPerformanceDays(day, dayFromDB) + const isEqual = isEqualsPerformanceDays(day, dayFromDB) // Если есть отличия, то добавляем в список на добавление/обновление - if (!isEquils && dayToUpdate.indexOf(actualDate) === -1) { + if (!isEqual && dayToUpdate.indexOf(actualDate) === -1) { dayToUpdate.push(actualDate) } } @@ -53,12 +53,12 @@ export const savePerfomance = async ( new Date(a).getTime() > new Date(b).getTime() ? 1 : -1 ) - const grouppingDates = groupping(dayToUpdate) + const groupedDates = getGroupedDates(dayToUpdate) - if (!grouppingDates) return + if (!groupedDates) return // Загружаем расписание по сгруппированным дням (это вызовет автоматическое обновление оценок) - for (const group of grouppingDates) { + for (const group of groupedDates) { await getLessonsService( String(group.startDate), String(group.endDate), @@ -88,7 +88,7 @@ type countable = { [key: string]: number } -const isEquilsPerformanceDays = ( +const isEqualsPerformanceDays = ( dayOne: DayWithMarks, dayTwo: DayWithMarks ) => { @@ -133,7 +133,7 @@ const countableDayData = (day: DayWithMarks) => { /** * Группирует даты в один запрос к серверу */ -const groupping = (dates: (string | Date)[]) => { +const getGroupedDates = (dates: (string | Date)[]) => { if (!dates.length) return null // Количество миллисекунд в дне const oneDay = 1000 * 60 * 60 * 24 From afd7dd2975ef9287753c16e75006a38566576697 Mon Sep 17 00:00:00 2001 From: okulov-sm Date: Mon, 1 Apr 2024 18:38:25 +0700 Subject: [PATCH 3/8] refactor --- apps/web/src/api/makeRequest.ts | 4 ++-- apps/web/src/{ => assets}/images/diary-ava.png | Bin apps/web/src/{ => assets}/images/winx48.webp | Bin .../Achievements/Tabs/Summary/UserInfo/index.tsx | 2 +- apps/web/src/views/Settings/Contacts.tsx | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename apps/web/src/{ => assets}/images/diary-ava.png (100%) mode change 100755 => 100644 rename apps/web/src/{ => assets}/images/winx48.webp (100%) mode change 100755 => 100644 diff --git a/apps/web/src/api/makeRequest.ts b/apps/web/src/api/makeRequest.ts index bdf7d456..cf657f92 100755 --- a/apps/web/src/api/makeRequest.ts +++ b/apps/web/src/api/makeRequest.ts @@ -24,7 +24,7 @@ const makeRequest = async ( timeout: 2000 }) - console.info('%c [makeRequest]', 'color: blueviolet', response) + // console.info('%c [makeRequest]', 'color: blueviolet', response) return response.data } catch (err) { @@ -33,7 +33,7 @@ const makeRequest = async ( return } - console.info('%c [makeRequest]', 'color: blueviolet', err) + // console.info('%c [makeRequest]', 'color: blueviolet', err) /** В случае ошибки авторизации мы не делаем запрос на другой сервер, а сразу возвращаем ответ **/ if (err?.response?.status === HTTP_STATUSES.UNAUTHORIZED) { diff --git a/apps/web/src/images/diary-ava.png b/apps/web/src/assets/images/diary-ava.png old mode 100755 new mode 100644 similarity index 100% rename from apps/web/src/images/diary-ava.png rename to apps/web/src/assets/images/diary-ava.png diff --git a/apps/web/src/images/winx48.webp b/apps/web/src/assets/images/winx48.webp old mode 100755 new mode 100644 similarity index 100% rename from apps/web/src/images/winx48.webp rename to apps/web/src/assets/images/winx48.webp diff --git a/apps/web/src/views/Achievements/Tabs/Summary/UserInfo/index.tsx b/apps/web/src/views/Achievements/Tabs/Summary/UserInfo/index.tsx index 552f7966..89525130 100644 --- a/apps/web/src/views/Achievements/Tabs/Summary/UserInfo/index.tsx +++ b/apps/web/src/views/Achievements/Tabs/Summary/UserInfo/index.tsx @@ -12,7 +12,7 @@ import { } from '@vkontakte/vkui' import type { FunctionComponent } from 'preact' import { useEffect, useState } from 'preact/compat' -import { winxAva } from '../../../../../images/config.ts' +import { winxAva } from '../../../../../config/images.ts' import './index.css' diff --git a/apps/web/src/views/Settings/Contacts.tsx b/apps/web/src/views/Settings/Contacts.tsx index 43487dfe..0e1c27c4 100755 --- a/apps/web/src/views/Settings/Contacts.tsx +++ b/apps/web/src/views/Settings/Contacts.tsx @@ -1,6 +1,6 @@ import { Icon28Users } from '@vkontakte/icons' import { Avatar, Group, Header, Link, SimpleCell } from '@vkontakte/vkui' -import { diaryAva, winxAva } from '../../images/config.ts' +import { diaryAva, winxAva } from '../../config/images.ts' const Contacts = () => { return ( From bdb1ed50ef7bfd68d04e570d3c431b7441d291bb Mon Sep 17 00:00:00 2001 From: okulov-sm Date: Mon, 1 Apr 2024 18:38:54 +0700 Subject: [PATCH 4/8] lint --- apps/web/src/config/images.ts | 4 ++++ apps/web/src/images/config.ts | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 apps/web/src/config/images.ts delete mode 100755 apps/web/src/images/config.ts diff --git a/apps/web/src/config/images.ts b/apps/web/src/config/images.ts new file mode 100644 index 00000000..91c191ba --- /dev/null +++ b/apps/web/src/config/images.ts @@ -0,0 +1,4 @@ +import diaryAva from '../assets/images/diary-ava.png' +import winxAva from '../assets/images/winx48.webp' + +export { winxAva, diaryAva } diff --git a/apps/web/src/images/config.ts b/apps/web/src/images/config.ts deleted file mode 100755 index fdd6a297..00000000 --- a/apps/web/src/images/config.ts +++ /dev/null @@ -1,4 +0,0 @@ -import diaryAva from './diary-ava.png' -import winxAva from './winx48.webp' - -export { winxAva, diaryAva } From 54c79f6ad40b9205318f10691394761fc5eb0b1c Mon Sep 17 00:00:00 2001 From: okulov-sm Date: Mon, 1 Apr 2024 18:43:34 +0700 Subject: [PATCH 5/8] rm log error --- apps/api/src/LogError/index.ts | 10 ---------- .../models/Subject/actions/save/subjectSaveOrGet.ts | 1 - apps/api/src/routes/login/service/save/saveUserData.ts | 10 +--------- 3 files changed, 1 insertion(+), 20 deletions(-) delete mode 100755 apps/api/src/LogError/index.ts diff --git a/apps/api/src/LogError/index.ts b/apps/api/src/LogError/index.ts deleted file mode 100755 index 8b7542ac..00000000 --- a/apps/api/src/LogError/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -// TODO: Сделать функцией -export class LogError extends Error { - message: string - - constructor(message: string) { - super(message) - this.message = `[${new Date().toISOString()}] => ${message}` - Object.setPrototypeOf(this, LogError.prototype) - } -} diff --git a/apps/api/src/models/Subject/actions/save/subjectSaveOrGet.ts b/apps/api/src/models/Subject/actions/save/subjectSaveOrGet.ts index 0f2776cb..d839bb35 100755 --- a/apps/api/src/models/Subject/actions/save/subjectSaveOrGet.ts +++ b/apps/api/src/models/Subject/actions/save/subjectSaveOrGet.ts @@ -1,5 +1,4 @@ import { type ISubjectModelType, SubjectModel } from '@models' -import { LogError } from 'src/LogError' export const subjectSaveOrGet = async ( subjectName: string diff --git a/apps/api/src/routes/login/service/save/saveUserData.ts b/apps/api/src/routes/login/service/save/saveUserData.ts index bf8a4f2a..ca58e977 100755 --- a/apps/api/src/routes/login/service/save/saveUserData.ts +++ b/apps/api/src/routes/login/service/save/saveUserData.ts @@ -5,14 +5,7 @@ import { generateToken } from '@helpers' // TODO: сделать папку с утилитами может import { saveOrGetDiaryUser, saveOrGetGroup, saveOrGetSPO } from '@models' import { ResponseLoginFromDiaryUser } from '@types' -import { - type ApiResponse, - cookieExtractor, - error, - fetcher, - formatDate -} from '@utils' -import { LogError } from 'src/LogError' +import { type ApiResponse, cookieExtractor, error, fetcher } from '@utils' export const saveUserData = async ( parsedRes: ApiResponse, @@ -88,6 +81,5 @@ export const saveUserData = async ( return ResponseLoginFromDiaryUser(regDiaryUser, regSPO, regGroup, token) } catch (err) { error(err) - throw new LogError('Ошибка на этапе работы с базой: ') } } From 339076d401f8ecdeb271ba1a8a356d3fb49d75bb Mon Sep 17 00:00:00 2001 From: okulov-sm Date: Mon, 1 Apr 2024 18:56:48 +0700 Subject: [PATCH 6/8] imports --- apps/api/src/models/Absence/model.ts | 1 + apps/api/src/models/AbsenceType/model.ts | 4 +++- apps/api/src/models/Classroom/model.ts | 4 +++- apps/api/src/models/DiaryUser/model.ts | 6 ++++-- apps/api/src/models/Examination/model.ts | 4 +++- apps/api/src/models/FinalMark/model.ts | 4 +++- apps/api/src/models/Group/model.ts | 4 +++- apps/api/src/models/LessonType/model.ts | 4 +++- apps/api/src/models/Mark/model.ts | 4 +++- apps/api/src/models/MarkValue/model.ts | 4 +++- apps/api/src/models/Required/model.ts | 4 +++- apps/api/src/models/SPO/model.ts | 4 +++- apps/api/src/models/Schedule/model.ts | 1 + apps/api/src/models/ScheduleSubgroup/model.ts | 4 +++- apps/api/src/models/Subgroup/model.ts | 4 +++- apps/api/src/models/Subject/model.ts | 4 +++- apps/api/src/models/Task/model.ts | 4 +++- apps/api/src/models/TaskType/model.ts | 4 +++- apps/api/src/models/Teacher/model.ts | 4 +++- apps/api/src/models/Term/model.ts | 4 +++- apps/api/src/models/TermSubject/model.ts | 4 +++- apps/api/src/models/TermSubjectExaminationType/model.ts | 4 +++- apps/api/src/models/TermType/model.ts | 4 +++- apps/api/src/models/TermUser/model.ts | 4 +++- apps/api/src/models/Theme/model.ts | 4 +++- .../routes/finalMarks/service/get/getFinalMarksFromDB.ts | 1 - 26 files changed, 72 insertions(+), 25 deletions(-) diff --git a/apps/api/src/models/Absence/model.ts b/apps/api/src/models/Absence/model.ts index 61034c3d..a57a4284 100755 --- a/apps/api/src/models/Absence/model.ts +++ b/apps/api/src/models/Absence/model.ts @@ -1,6 +1,7 @@ import { DataTypes } from 'sequelize' import { cache, enableCache, sequelize } from '@db' + import { AbsenceTypeModel } from '../AbsenceType' import { DiaryUserModel } from '../DiaryUser' import { ScheduleModel } from '../Schedule' diff --git a/apps/api/src/models/AbsenceType/model.ts b/apps/api/src/models/AbsenceType/model.ts index 981bb036..72f729e3 100755 --- a/apps/api/src/models/AbsenceType/model.ts +++ b/apps/api/src/models/AbsenceType/model.ts @@ -1,6 +1,8 @@ -import { cache, enableCache, sequelize } from '@db' import { AbsenceTypes, type AbsenceTypesKeys } from '@diary-spo/shared' import { DataTypes } from 'sequelize' + +import { cache, enableCache, sequelize } from '@db' + import type { IModelPrototype } from '../types' export type AbsenceTypeModelType = { diff --git a/apps/api/src/models/Classroom/model.ts b/apps/api/src/models/Classroom/model.ts index 28386683..95f8a139 100755 --- a/apps/api/src/models/Classroom/model.ts +++ b/apps/api/src/models/Classroom/model.ts @@ -1,5 +1,7 @@ -import { cache, enableCache, sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { cache, enableCache, sequelize } from '@db' + import { SPOModel } from '../SPO' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/models/DiaryUser/model.ts b/apps/api/src/models/DiaryUser/model.ts index c139dae4..a00012a8 100755 --- a/apps/api/src/models/DiaryUser/model.ts +++ b/apps/api/src/models/DiaryUser/model.ts @@ -1,8 +1,10 @@ +import type { Nullable } from '@diary-spo/shared' +import { DataTypes } from 'sequelize' + import { KEY } from '@config' import { sequelize } from '@db' -import type { Nullable } from '@diary-spo/shared' import { formatDate } from '@utils' -import { DataTypes } from 'sequelize' + import { GroupModel } from '../Group' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/models/Examination/model.ts b/apps/api/src/models/Examination/model.ts index 56b63276..b656b1bc 100755 --- a/apps/api/src/models/Examination/model.ts +++ b/apps/api/src/models/Examination/model.ts @@ -1,6 +1,8 @@ -import { cache, enableCache, sequelize } from '@db' import { type ExaminationKeys, Examinations } from '@diary-spo/shared' import { DataTypes } from 'sequelize' + +import { cache, enableCache, sequelize } from '@db' + import type { IModelPrototype } from '../types' export type ExaminationTypeModelType = { diff --git a/apps/api/src/models/FinalMark/model.ts b/apps/api/src/models/FinalMark/model.ts index 22ab82bb..4a3f33be 100755 --- a/apps/api/src/models/FinalMark/model.ts +++ b/apps/api/src/models/FinalMark/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { DiaryUserModel } from '../DiaryUser' import { MarkValueModel } from '../MarkValue' import { SubjectModel } from '../Subject' diff --git a/apps/api/src/models/Group/model.ts b/apps/api/src/models/Group/model.ts index 7ea5b052..6ad78b94 100755 --- a/apps/api/src/models/Group/model.ts +++ b/apps/api/src/models/Group/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { SPOModel } from '../SPO' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/models/LessonType/model.ts b/apps/api/src/models/LessonType/model.ts index 90a7de95..310bebc3 100755 --- a/apps/api/src/models/LessonType/model.ts +++ b/apps/api/src/models/LessonType/model.ts @@ -1,6 +1,8 @@ -import { cache, enableCache, sequelize } from '@db' import { LessonType, type LessonTypeKeys } from '@diary-spo/shared' import { DataTypes } from 'sequelize' + +import { cache, enableCache, sequelize } from '@db' + import type { IModelPrototype } from '../types' export type LessonTypeModelType = { diff --git a/apps/api/src/models/Mark/model.ts b/apps/api/src/models/Mark/model.ts index 031aeff4..868af715 100755 --- a/apps/api/src/models/Mark/model.ts +++ b/apps/api/src/models/Mark/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { DiaryUserModel } from '../DiaryUser' import { MarkValueModel } from '../MarkValue' import { TaskModel } from '../Task' diff --git a/apps/api/src/models/MarkValue/model.ts b/apps/api/src/models/MarkValue/model.ts index 6439a066..3c921a38 100755 --- a/apps/api/src/models/MarkValue/model.ts +++ b/apps/api/src/models/MarkValue/model.ts @@ -1,6 +1,8 @@ -import { cache, enableCache, sequelize } from '@db' import { Grade, type MarkKeys } from '@diary-spo/shared' import { DataTypes } from 'sequelize' + +import { cache, enableCache, sequelize } from '@db' + import type { IModelPrototype } from '../types' export type MarkValueModelType = { diff --git a/apps/api/src/models/Required/model.ts b/apps/api/src/models/Required/model.ts index 19af6a17..54b672b9 100755 --- a/apps/api/src/models/Required/model.ts +++ b/apps/api/src/models/Required/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { DiaryUserModel } from '../DiaryUser' import { TaskModel } from '../Task' import type { IModelPrototypeNoId } from '../types' diff --git a/apps/api/src/models/SPO/model.ts b/apps/api/src/models/SPO/model.ts index 10c3c9d1..c49d6540 100755 --- a/apps/api/src/models/SPO/model.ts +++ b/apps/api/src/models/SPO/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import type { IModelPrototype } from '../types' export type SPOModelType = { diff --git a/apps/api/src/models/Schedule/model.ts b/apps/api/src/models/Schedule/model.ts index f92643eb..a82ab10d 100755 --- a/apps/api/src/models/Schedule/model.ts +++ b/apps/api/src/models/Schedule/model.ts @@ -1,6 +1,7 @@ import { sequelize } from '@db' import type { Nullable } from '@diary-spo/shared' import { DataTypes, type Optional } from 'sequelize' + import { ClassroomModel } from '../Classroom' import { GroupModel } from '../Group' import { LessonTypeModel } from '../LessonType' diff --git a/apps/api/src/models/ScheduleSubgroup/model.ts b/apps/api/src/models/ScheduleSubgroup/model.ts index f8e29c6c..4e4c2b97 100755 --- a/apps/api/src/models/ScheduleSubgroup/model.ts +++ b/apps/api/src/models/ScheduleSubgroup/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { DiaryUserModel } from '../DiaryUser' import { ScheduleModel } from '../Schedule' import { SubgroupModel } from '../Subgroup' diff --git a/apps/api/src/models/Subgroup/model.ts b/apps/api/src/models/Subgroup/model.ts index 4c6230cd..976e1996 100755 --- a/apps/api/src/models/Subgroup/model.ts +++ b/apps/api/src/models/Subgroup/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { GroupModel } from '../Group' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/models/Subject/model.ts b/apps/api/src/models/Subject/model.ts index ef7cf48f..3a0e88f1 100755 --- a/apps/api/src/models/Subject/model.ts +++ b/apps/api/src/models/Subject/model.ts @@ -1,5 +1,7 @@ -import { cache, enableCache, sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { cache, enableCache, sequelize } from '@db' + import type { IModelPrototype } from '../types' export type SubjectModelType = { diff --git a/apps/api/src/models/Task/model.ts b/apps/api/src/models/Task/model.ts index 266ba2e6..1dfc0421 100755 --- a/apps/api/src/models/Task/model.ts +++ b/apps/api/src/models/Task/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { ScheduleModel } from '../Schedule' import { TaskTypeModel } from '../TaskType' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/models/TaskType/model.ts b/apps/api/src/models/TaskType/model.ts index 7678d3a3..7bdaf68a 100755 --- a/apps/api/src/models/TaskType/model.ts +++ b/apps/api/src/models/TaskType/model.ts @@ -1,6 +1,8 @@ -import { cache, enableCache, sequelize } from '@db' import { LessonWorkType, type LessonWorkTypeKeys } from '@diary-spo/shared' import { DataTypes } from 'sequelize' + +import { cache, enableCache, sequelize } from '@db' + import type { IModelPrototype } from '../types' export type TaskTypeModelType = { diff --git a/apps/api/src/models/Teacher/model.ts b/apps/api/src/models/Teacher/model.ts index 43c647c9..d7de9915 100755 --- a/apps/api/src/models/Teacher/model.ts +++ b/apps/api/src/models/Teacher/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { SPOModel } from '../SPO' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/models/Term/model.ts b/apps/api/src/models/Term/model.ts index 34d54fbb..760924ee 100755 --- a/apps/api/src/models/Term/model.ts +++ b/apps/api/src/models/Term/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { AcademicYearModel } from '../AcademicYear' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/models/TermSubject/model.ts b/apps/api/src/models/TermSubject/model.ts index bfc29781..584d2088 100755 --- a/apps/api/src/models/TermSubject/model.ts +++ b/apps/api/src/models/TermSubject/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { DiaryUserModel } from '../DiaryUser' import { ExaminationTypeModel } from '../Examination' import { MarkValueModel } from '../MarkValue' diff --git a/apps/api/src/models/TermSubjectExaminationType/model.ts b/apps/api/src/models/TermSubjectExaminationType/model.ts index 5888f3a5..8e6844ac 100755 --- a/apps/api/src/models/TermSubjectExaminationType/model.ts +++ b/apps/api/src/models/TermSubjectExaminationType/model.ts @@ -1,9 +1,11 @@ -import { sequelize } from '@db' import { type TermSubjectExaminationKeys, TermSubjectExaminations } from '@diary-spo/shared' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import type { IModelPrototype } from '../types' export type TermSubjectExaminationTypeModelType = { diff --git a/apps/api/src/models/TermType/model.ts b/apps/api/src/models/TermType/model.ts index f9d2f153..8536e07f 100755 --- a/apps/api/src/models/TermType/model.ts +++ b/apps/api/src/models/TermType/model.ts @@ -1,5 +1,7 @@ -import { cache, enableCache, sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { cache, enableCache, sequelize } from '@db' + import type { IModelPrototype } from '../types' export type TermTypeModelType = { diff --git a/apps/api/src/models/TermUser/model.ts b/apps/api/src/models/TermUser/model.ts index e37e7ab6..79432d95 100755 --- a/apps/api/src/models/TermUser/model.ts +++ b/apps/api/src/models/TermUser/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { DiaryUserModel } from '../DiaryUser' import { TermModel } from '../Term' import type { IModelPrototypeNoId } from '../types' diff --git a/apps/api/src/models/Theme/model.ts b/apps/api/src/models/Theme/model.ts index 43fc4a88..292872c7 100755 --- a/apps/api/src/models/Theme/model.ts +++ b/apps/api/src/models/Theme/model.ts @@ -1,5 +1,7 @@ -import { sequelize } from '@db' import { DataTypes } from 'sequelize' + +import { sequelize } from '@db' + import { ScheduleModel } from '../Schedule' import type { IModelPrototype } from '../types' diff --git a/apps/api/src/routes/finalMarks/service/get/getFinalMarksFromDB.ts b/apps/api/src/routes/finalMarks/service/get/getFinalMarksFromDB.ts index 51338e9d..91f2733a 100644 --- a/apps/api/src/routes/finalMarks/service/get/getFinalMarksFromDB.ts +++ b/apps/api/src/routes/finalMarks/service/get/getFinalMarksFromDB.ts @@ -2,7 +2,6 @@ import type { ICacheData } from '@helpers' import { AcademicYearModel, FinalMarkModel, - MarkModel, MarkValueModel, SubjectModel, TermModel, From d1866641b4576fbb634f3322399e7cd40a86cb4a Mon Sep 17 00:00:00 2001 From: scffs Date: Tue, 9 Apr 2024 16:34:56 +0700 Subject: [PATCH 7/8] update deps Signed-off-by: scffs --- apps/api/package.json | 8 ++-- apps/web/package.json | 6 +-- apps/web/src/views/LoginForm/index.tsx | 49 ++++++++++++++----------- bun.lockb | Bin 251968 -> 255208 bytes package.json | 8 ++-- 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/apps/api/package.json b/apps/api/package.json index 79ca3265..046789c6 100755 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -13,15 +13,15 @@ }, "dependencies": { "@elysiajs/cors": "^1.0.2", - "elysia": "^1.0.10", + "elysia": "^1.0.13", "elysia-compression": "^0.0.7", "elysia-helmet": "^1.0.2", - "pg": "^8.11.3", + "pg": "^8.11.5", "pg-hstore": "^2.3.4", "rand-token": "^1.0.1", "sequelize": "^6.37.2", "@diary-spo/crypto": "workspace:*", - "cache-manager": "^5.4.0", + "cache-manager": "^5.5.1", "sequelize-simple-cache": "^1.3.5", "node-rsa": "^1.1.1" }, @@ -29,6 +29,6 @@ "@types/node-rsa": "^1.1.4", "@diary-spo/shared": "workspace:*", "@elysiajs/swagger": "^1.0.3", - "@types/pg": "~8.11.2" + "@types/pg": "^8.11.5" } } diff --git a/apps/web/package.json b/apps/web/package.json index 6862a9aa..6d54d73d 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -20,18 +20,18 @@ "@vkontakte/vk-bridge": "^2.14.1", "@vkontakte/vk-bridge-react": "^1.0.1", "@vkontakte/vk-mini-apps-router": "1.4.3", - "@vkontakte/vkui": "6.0.1", + "@vkontakte/vkui": "6.0.2", "axios": "^1.6.8", "preact": "^10.20.1" }, "devDependencies": { "@diary-spo/shared": "workspace:*", - "@happy-dom/global-registrator": "^14.3.9", + "@happy-dom/global-registrator": "^14.7.1", "@preact/preset-vite": "^2.8.2", "@types/jsdom": "^21.1.6", "@vkontakte/vk-miniapps-deploy": "^0.1.7", "gh-pages": "^6.1.1", - "vite": "^5.2.7" + "vite": "^6.0.0-alpha.1" }, "browserslist": { "production": [">0.2%", "not dead", "not op_mini all"], diff --git a/apps/web/src/views/LoginForm/index.tsx b/apps/web/src/views/LoginForm/index.tsx index cb6a267f..d5d2b707 100755 --- a/apps/web/src/views/LoginForm/index.tsx +++ b/apps/web/src/views/LoginForm/index.tsx @@ -72,36 +72,41 @@ const LoginForm: FC = ({ id }) => { e.preventDefault() if (!loginPattern.test(login)) { setIsDataInvalid(true) - setIsLoading(false) return } const passwordHashed = await b64(password) - const response = await postLogin(login, passwordHashed, true) - - const data = handleResponse( - response, - () => setIsDataInvalid(true), - undefined, - setIsLoading, - showSnackbar, - false, - true - ) - - if (isApiError(data) || !data.token) { - return - } + try { + const response = await postLogin(login, passwordHashed, true) + + const data = handleResponse( + response, + () => setIsDataInvalid(true), + undefined, + setIsLoading, + showSnackbar, + false, + true + ) + + if (isApiError(data) || !data.token) { + return + } - saveData(data) + saveData(data) - showSnackbar({ - title: 'Вхожу', - subtitle: 'Подождите немного' - }) + showSnackbar({ + title: 'Вхожу', + subtitle: 'Подождите немного' + }) - await routeNavigator.replace(`/${VIEW_SCHEDULE}`) + await routeNavigator.replace(`/${VIEW_SCHEDULE}`) + } catch (error) { + console.log(error) + } finally { + setIsLoading(false) + } } const isLoginEmpty = login === '' diff --git a/bun.lockb b/bun.lockb index 804bc34b6eae2c73e73b35ca834c1b966e61958c..73ce0ccadf9fd9bbe19c3bcffb5a8852a74609bf 100755 GIT binary patch delta 45410 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 KW19REyZc{ZC1SY% delta 43663 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ΝD&PM)me#+=DuE= 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 diff --git a/package.json b/package.json index 310a6fa3..f6ee6a7d 100755 --- a/package.json +++ b/package.json @@ -3,13 +3,13 @@ "version": "3.0.0", "author": "diary-spo", "devDependencies": { - "@biomejs/biome": "^1.6.3", - "bun": "^1.0.36", - "bun-types": "^1.0.36", + "@biomejs/biome": "^1.6.4", + "bun": "^1.1.3", + "bun-types": "^1.1.3", "concurrently": "^8.2.2", "husky": "^9.0.11", "lint-staged": "^15.2.2", - "typescript": "^5.4.3" + "typescript": "^5.4.4" }, "description": "A web diary", "keywords": [], From 0b7a8c8a2c74cec714b8fae23e9d7be7f2c6ebdb Mon Sep 17 00:00:00 2001 From: scffs Date: Wed, 10 Apr 2024 00:23:51 +0700 Subject: [PATCH 8/8] little redesign Signed-off-by: scffs --- .../views/Schedule/ScheduleGroup/DailyCard/LessonCell/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/views/Schedule/ScheduleGroup/DailyCard/LessonCell/index.tsx b/apps/web/src/views/Schedule/ScheduleGroup/DailyCard/LessonCell/index.tsx index 0d8a11e2..fa3c99fd 100755 --- a/apps/web/src/views/Schedule/ScheduleGroup/DailyCard/LessonCell/index.tsx +++ b/apps/web/src/views/Schedule/ScheduleGroup/DailyCard/LessonCell/index.tsx @@ -50,6 +50,7 @@ const LessonCell: FC = ({ handleLessonClick(name, endTime, startTime, timetable, gradebook) } key={startTime} + subhead={

} subtitle={
@@ -69,7 +70,6 @@ const LessonCell: FC = ({ )}
-
{lessonTime}
{teacherInfo}
}