Skip to content

Commit

Permalink
fix: several types has been audited across the project to be compatib…
Browse files Browse the repository at this point in the history
…le with new online status implementation.
  • Loading branch information
mmoehabb committed Dec 18, 2024
1 parent 92b1d4b commit 437de17
Show file tree
Hide file tree
Showing 17 changed files with 54 additions and 37 deletions.
2 changes: 1 addition & 1 deletion apps/dashboard/src/components/UserDetails/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { rolesMap } from "@/components/utils/user";
import { useFormatMessage } from "@litespace/luna/hooks/intl";

const Content: React.FC<{
user?: IUser.Self;
user?: IUser.PopulatedSelf;
tutor?: ITutor.Self;
tutorStats?: ITutor.FindTutorStatsApiResponse | null;
loading?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/components/Users/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const List: React.FC<{
page: number;
}> = ({ query, ...props }) => {
const intl = useFormatMessage();
const columnHelper = createColumnHelper<IUser.Self>();
const columnHelper = createColumnHelper<IUser.PopulatedSelf>();
const columns = useMemo(
() => [
columnHelper.accessor("id", {
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/pages/UserDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const UserDetails = () => {
return value;
}, [params.id]);

const query: UseQueryResult<IUser.Self> = useFindUserById(id);
const query: UseQueryResult<IUser.PopulatedSelf> = useFindUserById(id);

const role = useMemo(() => {
if (!query.data) return null;
Expand Down
4 changes: 2 additions & 2 deletions packages/headless/src/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { QueryKey } from "./constants";

export function useUsers(
filter?: Omit<IUser.FindUsersApiQuery, "page" | "size">
): UsePaginateResult<IUser.Self> {
): UsePaginateResult<IUser.PopulatedSelf> {
const atlas = useAtlas();

const findUsers = useCallback(
Expand All @@ -21,7 +21,7 @@ export function useUsers(

export function useFindUserById(
id: string | number
): UseQueryResult<IUser.Self> {
): UseQueryResult<IUser.PopulatedSelf> {
const atlas = useAtlas();

const findUserById = useCallback(
Expand Down
1 change: 0 additions & 1 deletion packages/models/migrations/1716146586880_setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ exports.up = (pgm) => {
role: { type: "user_role", default: null },
birth_year: { type: "INT", default: null },
gender: { type: "user_gender", default: null },
//online: { type: "BOOLEAN", notNull: true, default: false },
verified: { type: "BOOLEAN", notNull: true, default: false },
phone_number: { type: "VARCHAR(15)", default: null },
city: { type: "SMALLINT", default: null },
Expand Down
2 changes: 1 addition & 1 deletion packages/models/src/cache/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Rules } from "@/cache/rules";
import { RedisClient } from "@/cache/base";
import { Peer } from "@/cache/peer";
import { Call } from "@/cache/call";
import { OnlineStatus } from "./onlineStatus";
import { OnlineStatus } from "@/cache/onlineStatus";

export class Cache {
public tutors: Tutors;
Expand Down
6 changes: 6 additions & 0 deletions packages/models/src/cache/onlineStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export class OnlineStatus extends CacheBase {
return await this.client.hExists(this.key, this.asField(userId));
}

async isOnlineBatch(userIds: number[]): Promise<boolean[]> {
return await Promise.all(
userIds.map(async id => this.client.hExists(this.key, this.asField(id)))
);
}

private asField(userId: number): string {
return userId.toString();
}
Expand Down
4 changes: 2 additions & 2 deletions packages/models/src/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ export class Rooms {
name: users.column("name"),
image: users.column("image"),
role: users.column("role"),
//online: users.column("online"), TODO: to be removed
pinned: this.column.members("pinned"),
muted: this.column.members("muted"),
createdAt: users.column("created_at"),
Expand Down Expand Up @@ -258,10 +257,11 @@ export class Rooms {
};
}

async asPopulatedMember(row: IRoom.PopulatedMemberRow): Promise<IRoom.PopulatedMember> {
asPopulatedMember(row: IRoom.PopulatedMemberRow): IRoom.PopulatedMember {
return merge(omit(row, "createdAt", "updatedAt"), {
createdAt: row.createdAt.toISOString(),
updatedAt: row.updatedAt.toISOString(),
online: false // TODO: substitute this workaround
});
}
}
Expand Down
1 change: 0 additions & 1 deletion packages/models/src/tutors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const fullTutorFields: FullTutorFieldsMap = {
password: users.column("password"),
birthYear: users.column("birth_year"),
gender: users.column("gender"),
//online: users.column("online"), TODO: to be removed
verified: users.column("verified"),
creditScore: users.column("credit_score"),
city: users.column("city"),
Expand Down
3 changes: 0 additions & 3 deletions packages/models/src/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export class Users {
"role",
"birth_year",
"gender",
//"online", TODO: to be removed
"verified",
"city",
"credit_score",
Expand Down Expand Up @@ -60,7 +59,6 @@ export class Users {
email: payload.email,
image: payload.image,
gender: payload.gender,
//online: payload.online, TODO: to be removed
name: payload.name,
verified: payload.verified,
password: payload.password,
Expand Down Expand Up @@ -120,7 +118,6 @@ export class Users {
role,
verified,
gender,
//online, TODO: to be removed
page,
size,
orderBy,
Expand Down
2 changes: 0 additions & 2 deletions packages/models/tests/users.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ describe("Users", () => {
birthYear: 2003,
gender: IUser.Gender.Female,
verified: true,
//online: true, TODO: to be removed
creditScore: 2382001,
phoneNumber: "01018303125",
city: 2,
Expand All @@ -63,7 +62,6 @@ describe("Users", () => {
expect(updated.birthYear).to.be.eq(2003);
expect(updated.gender).to.be.eq(IUser.Gender.Female);
expect(updated.verified).to.be.eq(true);
//expect(updated.online).to.be.eq(true); TODO: to be removed
expect(updated.creditScore).to.be.eq(2382001);
expect(updated.phoneNumber).to.be.eq("01018303125");
expect(updated.city).to.be.eq(2);
Expand Down
5 changes: 2 additions & 3 deletions packages/types/src/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export type PopulatedMemberRow = {
name: IUser.Row["name"];
image: IUser.Row["image"];
role: IUser.Row["role"];
//online: IUser.Row["online"]; TODO: to be removed
createdAt: IUser.Row["created_at"];
updatedAt: IUser.Row["updated_at"];
};
Expand All @@ -51,7 +50,7 @@ export type PopulatedMember = {
name: IUser.Self["name"];
image: IUser.Self["image"];
role: IUser.Self["role"];
//online: IUser.Self["online"]; TODO: to be removed
online: boolean;
createdAt: IUser.Self["createdAt"];
updatedAt: IUser.Self["updatedAt"];
};
Expand All @@ -76,7 +75,7 @@ export type FindUserRoomsApiRecord = {
id: number;
name: string | null;
image: string | null;
//online: boolean; TODO: to be removed
online: boolean;
role: IUser.Role;
lastSeen: string;
};
Expand Down
7 changes: 3 additions & 4 deletions packages/types/src/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export type Self = {
birthYear: number | null;
gender: Gender | null;
role: Role;
//online: boolean; TODO: to be removed
verified: boolean;
creditScore: number;
city: City | null;
Expand All @@ -66,6 +65,8 @@ export type Self = {
updatedAt: string;
};

export type PopulatedSelf = Self & { online: boolean };

export type Row = {
id: number;
email: string;
Expand All @@ -75,7 +76,6 @@ export type Row = {
birth_year: number | null;
gender: Gender | null;
role: Role;
//online: boolean; TODO: to be removed
verified: boolean;
credit_score: number;
city: City | null;
Expand Down Expand Up @@ -106,7 +106,6 @@ export type UpdatePayload = {
birthYear?: number;
gender?: Gender;
verified?: boolean;
//online?: boolean; TODO: to be removed
creditScore?: number;
phoneNumber?: string;
city?: City;
Expand Down Expand Up @@ -150,7 +149,7 @@ export type LoginApiResponse = {

export type RegisterApiResponse = LoginApiResponse;

export type FindUsersApiResponse = Paginated<Self>;
export type FindUsersApiResponse = Paginated<PopulatedSelf>;

export type ResetPasswordApiResponse = LoginApiResponse;

Expand Down
16 changes: 13 additions & 3 deletions services/server/src/handlers/user.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { tutors, users, knex, lessons } from "@litespace/models";
import { ILesson, ITutor, IUser, Wss } from "@litespace/types";
import { ILesson, ITutor, IUser, Paginated, Wss } from "@litespace/types";
import {
apierror,
exists,
Expand Down Expand Up @@ -59,7 +59,7 @@ import { sendBackgroundMessage } from "@/workers";
import { WorkerMessageType } from "@/workers/messages";
import { isValidPassword } from "@litespace/sol/verification";
import { selectTutorRuleEvents } from "@/lib/events";
import { Gender } from "@litespace/types/dist/esm/user";
import { Gender, PopulatedSelf } from "@litespace/types/dist/esm/user";
import { isTutor, isTutorManager } from "@litespace/auth/dist/authorization";

const createUserPayload = zod.object({
Expand Down Expand Up @@ -316,7 +316,17 @@ async function findUsers(req: Request, res: Response, next: NextFunction) {

const query: IUser.FindUsersApiQuery = findUsersQuery.parse(req.query);
const result = await users.find(query);
const response: IUser.FindUsersApiResponse = result;

const isOnlineList = await cache.onlineStatus.isOnlineBatch(result.list.map(user => user.id));
const resList = result.list.map<PopulatedSelf>((user, i) => ({
...user,
online: isOnlineList[i],
}));

const response: IUser.FindUsersApiResponse = {
list: resList,
total: result.total
};

res.status(200).json(response);
}
Expand Down
1 change: 1 addition & 0 deletions services/server/src/lib/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export async function asFindUserRoomsApiRecord({
id: otherMember.id,
name: otherMember.name,
image: otherMember.image,
online: otherMember.online,
role: otherMember.role,
lastSeen: otherMember.updatedAt,
},
Expand Down
12 changes: 7 additions & 5 deletions services/server/src/lib/tutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ export async function constructTutorsCache(date: Dayjs): Promise<TutorsCache> {
}
);

const onlineUsers = await cache.onlineStatus.getAll();
const isOnlineList = await cache.onlineStatus.isOnlineBatch(onboardedTutors.map(t => t.id));

// restruct tutors list to match ITutor.Cache[]
const cacheTutors: ITutor.Cache[] = onboardedTutors.map((tutor) => {
const cacheTutors: ITutor.Cache[] = onboardedTutors.map((tutor, i) => {
const filteredTopics = tutorsTopics
?.filter((item) => item.userId === tutor.id)
.map((item) => item.name.ar);
Expand All @@ -84,7 +84,7 @@ export async function constructTutorsCache(date: Dayjs): Promise<TutorsCache> {
bio: tutor.bio,
about: tutor.about,
gender: tutor.gender,
online: onlineUsers[tutor.id] ? true : false,
online: isOnlineList[i] ? true : false,
notice: tutor.notice,
topics: filteredTopics,
avgRating:
Expand Down Expand Up @@ -171,7 +171,7 @@ export function orderTutors({
* - lesson count
*/
async function findTutorCacheMeta(tutorId: number) {
const [tutorTopics, avgRatings, studentCount, lessonCount] =
const [tutorTopics, avgRatings, studentCount, lessonCount, online] =
await Promise.all([
topics.findUserTopics({ users: [tutorId] }),
ratings.findAvgRatings([tutorId]),
Expand All @@ -181,13 +181,15 @@ async function findTutorCacheMeta(tutorId: number) {
canceled: false,
ratified: true,
}),
cache.onlineStatus.isOnline(tutorId),
]);

return {
topics: tutorTopics.map((topic) => topic.name.ar),
avgRating: first(avgRatings)?.avg || 0,
studentCount,
lessonCount,
online,
};
}

Expand All @@ -201,6 +203,7 @@ export async function joinTutorCache(
avgRating: cacheData.avgRating,
studentCount: cacheData.studentCount,
lessonCount: cacheData.lessonCount,
online: cacheData.online,
}
: await findTutorCacheMeta(tutor.id);

Expand All @@ -213,7 +216,6 @@ export async function joinTutorCache(
about: tutor.about,
gender: tutor.gender,
notice: tutor.notice,
online: await cache.onlineStatus.isOnline(tutor.id),
...meta,
};
}
Expand Down
21 changes: 14 additions & 7 deletions services/server/src/wss/handlers/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class Connection extends WssHandler {
if (isGhost(user)) return;

await cache.onlineStatus.addUser(user.id);
this.announceStatus(user.id, true);
this.announceStatus({ userId: user.id, online: true });

await this.joinRooms();
if (isAdmin(this.user)) this.emitServerStats();
Expand All @@ -38,21 +38,28 @@ export class Connection extends WssHandler {
if (isGhost(user)) return;

await cache.onlineStatus.removeUser(user.id);
this.announceStatus(user.id, false);
this.announceStatus({ userId: user.id, online: false });

await this.deregisterPeer();
await this.removeUserFromCalls();
});
if (error instanceof Error) stdout.error(error.message);
}

private async announceStatus(userId: number, status: boolean) {
private async announceStatus({
userId,
online,
}: {
userId: number,
online: boolean,
}) {
const userRooms = await rooms.findMemberFullRoomIds(userId);

for (const room of userRooms) {
this.broadcast(Wss.ServerEvent.UserStatusChanged, room.toString(), {
online: status,
});
this.broadcast(
Wss.ServerEvent.UserStatusChanged,
room.toString(),
{ online }
);
}
}

Expand Down

0 comments on commit 437de17

Please sign in to comment.