Improved the overall stability and speed of the app

This commit is contained in:
Tiago Ribeiro
2024-08-29 23:21:20 +01:00
parent b57e11bec4
commit 39710aaea1
17 changed files with 315 additions and 280 deletions

View File

@@ -1,58 +1,36 @@
import { app } from "@/firebase";
import { Assignment } from "@/interfaces/results";
import {
collection,
getDocs,
getFirestore,
query,
where,
} from "firebase/firestore";
import {app} from "@/firebase";
import {Assignment} from "@/interfaces/results";
import {collection, getDocs, getFirestore, query, where} from "firebase/firestore";
const db = getFirestore(app);
export const getAssignmentsByAssigner = async (
id: string,
startDate?: Date,
endDate?: Date
) => {
const { docs } = await getDocs(
query(
collection(db, "assignments"),
...[
where("assigner", "==", id),
...(startDate ? [where("startDate", ">=", startDate.toISOString())] : []),
// firebase doesnt accept compound queries so we have to filter on the server
// ...endDate ? [where("endDate", "<=", endDate)] : [],
]
)
);
if (endDate) {
return docs
.map((x) => ({ ...(x.data() as Assignment), id: x.id }))
.filter((x) => new Date(x.endDate) <= endDate) as Assignment[];
}
return docs.map((x) => ({ ...x.data(), id: x.id })) as Assignment[];
export const getAssignmentsByAssigner = async (id: string, startDate?: Date, endDate?: Date) => {
const {docs} = await getDocs(
query(
collection(db, "assignments"),
...[
where("assigner", "==", id),
...(startDate ? [where("startDate", ">=", startDate.toISOString())] : []),
// firebase doesnt accept compound queries so we have to filter on the server
// ...endDate ? [where("endDate", "<=", endDate)] : [],
],
),
);
if (endDate) {
return docs.map((x) => ({...(x.data() as Assignment), id: x.id})).filter((x) => new Date(x.endDate) <= endDate) as Assignment[];
}
return docs.map((x) => ({...x.data(), id: x.id})) as Assignment[];
};
export const getAssignments = async () => {
const {docs} = await getDocs(collection(db, "assignments"));
return docs.map((x) => ({...x.data(), id: x.id})) as Assignment[];
};
export const getAssignmentsByAssignerBetweenDates = async (
id: string,
startDate: Date,
endDate: Date
) => {
const { docs } = await getDocs(
query(collection(db, "assignments"), where("assigner", "==", id))
);
return docs.map((x) => ({ ...x.data(), id: x.id })) as Assignment[];
export const getAssignmentsByAssignerBetweenDates = async (id: string, startDate: Date, endDate: Date) => {
const {docs} = await getDocs(query(collection(db, "assignments"), where("assigner", "==", id)));
return docs.map((x) => ({...x.data(), id: x.id})) as Assignment[];
};
export const getAssignmentsByAssigners = async (
ids: string[],
startDate?: Date,
endDate?: Date
) => {
return (
await Promise.all(
ids.map((id) => getAssignmentsByAssigner(id, startDate, endDate))
)
).flat();
export const getAssignmentsByAssigners = async (ids: string[], startDate?: Date, endDate?: Date) => {
return (await Promise.all(ids.map((id) => getAssignmentsByAssigner(id, startDate, endDate)))).flat();
};

View File

@@ -1,99 +1,89 @@
import { app, adminApp } from "@/firebase";
import { getAuth } from "firebase-admin/auth";
import {app, adminApp} from "@/firebase";
import {getAuth} from "firebase-admin/auth";
import {
collection,
deleteDoc,
doc,
getDoc,
getDocs,
getFirestore,
query,
setDoc,
where,
} from "firebase/firestore";
import {
Permission,
PermissionType,
permissions,
PermissionTopic,
} from "@/interfaces/permissions";
import { v4 } from "uuid";
import {collection, deleteDoc, doc, getDoc, getDocs, getFirestore, query, setDoc, where} from "firebase/firestore";
import {Permission, PermissionType, permissions, PermissionTopic} from "@/interfaces/permissions";
import {v4} from "uuid";
const db = getFirestore(app);
async function createPermission(topic: string, type: string) {
const permData = doc(db, "permissions", v4());
const permDoc = await getDoc(permData);
if (permDoc.exists()) {
return true;
}
const permData = doc(db, "permissions", v4());
const permDoc = await getDoc(permData);
if (permDoc.exists()) {
return true;
}
await setDoc(permData, {
type,
topic,
users: [],
});
await setDoc(permData, {
type,
topic,
users: [],
});
}
interface PermissionsHelperList {
topic: string;
type: string;
topic: string;
type: string;
}
export function getPermissions(userId: string | undefined, docs: Permission[]) {
if (!userId) {
return [];
}
// the concept is like a blacklist
// if the user exists in the list, he can't access this permission
// even if his profile allows
const permissions = docs.reduce((acc: PermissionType[], doc: Permission) => {
// typescript was complaining even with the validation on the top
if (doc.users.includes(userId)) {
return acc;
}
if (!userId) {
return [];
}
// the concept is like a blacklist
// if the user exists in the list, he can't access this permission
// even if his profile allows
const permissions = docs.reduce((acc: PermissionType[], doc: Permission) => {
// typescript was complaining even with the validation on the top
if (doc.users.includes(userId)) {
return acc;
}
return [...acc, doc.type];
}, []) as PermissionType[];
return permissions;
return [...acc, doc.type];
}, []) as PermissionType[];
return permissions;
}
export async function getUserPermissions(id: string) {
const permissions = await getPermissionDocs();
return getPermissions(id, permissions);
}
export async function bootstrap() {
await permissions
.reduce((accm: PermissionsHelperList[], permissionData) => {
return [
...accm,
...permissionData.list.map((type) => ({
topic: permissionData.topic,
type,
})),
];
}, [])
.forEach(async ({ topic, type }) => {
await createPermission(topic, type);
});
await permissions
.reduce((accm: PermissionsHelperList[], permissionData) => {
return [
...accm,
...permissionData.list.map((type) => ({
topic: permissionData.topic,
type,
})),
];
}, [])
.forEach(async ({topic, type}) => {
await createPermission(topic, type);
});
}
export async function getPermissionDoc(id: string) {
const docRef = doc(db, "permissions", id);
const docSnap = await getDoc(docRef);
const docRef = doc(db, "permissions", id);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
return docSnap.data() as Permission;
}
if (docSnap.exists()) {
return docSnap.data() as Permission;
}
throw new Error("Permission not found");
throw new Error("Permission not found");
}
export async function getPermissionDocs() {
const q = query(collection(db, "permissions"));
// firebase is missing something like array-not-contains
const q = query(collection(db, "permissions"));
// firebase is missing something like array-not-contains
const snapshot = await getDocs(q);
const snapshot = await getDocs(q);
const docs = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})) as Permission[];
const docs = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})) as Permission[];
return docs;
return docs;
}

View File

@@ -5,21 +5,23 @@ import {CorporateUser, Group, User} from "@/interfaces/user";
import {getGroupsForUser} from "./groups.be";
import {uniq, uniqBy} from "lodash";
import {getUserCodes} from "./codes.be";
import moment from "moment";
const db = getFirestore(app);
export async function getUsers() {
const snapshot = await getDocs(collection(db, "users"));
return snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})) as User[];
id: doc.id,
registrationDate: moment(doc.data().registrationDate).toISOString(),
})) as unknown as User[];
}
export async function getUser(id: string) {
const userDoc = await getDoc(doc(db, "users", id));
return {...userDoc.data(), id} as User;
return {...userDoc.data(), id, registrationDate: moment(userDoc.data()?.registrationDate).toISOString()} as unknown as User;
}
export async function getSpecificUsers(ids: string[]) {
@@ -28,9 +30,10 @@ export async function getSpecificUsers(ids: string[]) {
const snapshot = await getDocs(query(collection(db, "users"), where("id", "in", ids)));
const groups = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})) as User[];
id: doc.id,
registrationDate: moment(doc.data().registrationDate).toISOString(),
})) as unknown as User[];
return groups;
}