refactor: reorganize imports in course route and update middleware for course tags endpoint

This commit is contained in:
Rotimi Best
2026-03-12 22:16:51 +01:00
parent 4fe4fc168d
commit 420409722a
5 changed files with 30 additions and 14 deletions
+7 -7
View File
@@ -25,33 +25,33 @@ import {
getCourseProgress,
updateCourse
} from '@api/services/course/course';
import { enrollInCourse } from '@api/services/course/invite';
import { getCourseTags, replaceCourseTags } from '@api/services/tag';
import { createRateLimiter } from '@api/middlewares/rate-limiter';
import { extractClientIp } from '@api/utils/redis/key-generators';
import { Hono } from '@api/utils/hono';
import { attendanceRouter } from '@api/routes/course/attendance';
import { authMiddleware } from '@api/middlewares/auth';
import { cloneCourse } from '@api/services/course/clone';
import { contentRouter } from '@api/routes/course/content';
import { courseMemberMiddleware } from '@api/middlewares/course-member';
import { courseTeamMemberMiddleware } from '@api/middlewares/course-team-member';
import { contentRouter } from '@api/routes/course/content';
import { createRateLimiter } from '@api/middlewares/rate-limiter';
import { enrollInCourse } from '@api/services/course/invite';
import { exerciseRouter } from '@api/routes/course/exercise';
import { extractClientIp } from '@api/utils/redis/key-generators';
import { generateCertificate } from '@api/utils/certificate';
import { generateCoursePdf } from '@api/utils/course';
import { handleError } from '@api/utils/errors';
import { invitesRouter } from '@api/routes/course/invite';
import { katexRouter } from '@api/routes/course/katex';
import { lessonRouter } from '@api/routes/course/lesson';
import { markRouter } from '@api/routes/course/mark';
import { sectionRouter } from '@api/routes/course/section';
import { membersRouter } from '@api/routes/course/people';
import { invitesRouter } from '@api/routes/course/invite';
import { newsfeedRouter } from '@api/routes/course/newsfeed';
import { orgAdminMiddleware } from '@api/middlewares/org-admin';
import { orgMemberMiddleware } from '@api/middlewares/org-member';
import { paymentRequestRouter } from '@api/routes/course/payment-request';
import { presignRouter } from '@api/routes/course/presign';
import { sectionRouter } from '@api/routes/course/section';
import { submissionRouter } from '@api/routes/course/submission';
import { zValidator } from '@hono/zod-validator';
@@ -157,7 +157,7 @@ export const courseRouter = new Hono()
* GET /course/:courseId/tags
* Gets tags assigned to a course (organization admin only)
*/
.get('/:courseId/tags', authMiddleware, orgAdminMiddleware, zValidator('param', ZCourseTagParam), async (c) => {
.get('/:courseId/tags', authMiddleware, orgMemberMiddleware, zValidator('param', ZCourseTagParam), async (c) => {
try {
const orgId = c.req.header('cio-org-id')!;
const { courseId } = c.req.valid('param');
+2 -2
View File
@@ -50,9 +50,9 @@ export async function getAccountData(userId: string): Promise<GetAccountDataResu
roleId: ROLE.STUDENT,
verified: true
});
organizations = await getOrganizationByProfileId(userId);
}
organizations = await getOrganizationByProfileId(userId);
}
}
+11 -4
View File
@@ -1,20 +1,23 @@
import * as schema from '@cio/db/schema';
import { AppError, ErrorCodes } from '@api/utils/errors';
import { and, eq, isNull } from 'drizzle-orm';
import {
checkEmailsExistInOrg,
createOrganizationMembers,
createOrganizationInvite,
createOrganizationInviteAudit,
createOrganizationMembers,
getOrganizationById,
getOrganizationInviteByTokenHash,
revokeActiveOrganizationInvitesByEmails
} from '@cio/db/queries/organization';
import { ROLE } from '@cio/utils/constants';
import crypto from 'node:crypto';
import { db } from '@cio/db/drizzle';
import { getDashboardBaseUrl } from '@api/config/dashboard-url';
import { markUserAndProfileEmailVerified } from '@cio/db/queries/auth/profile';
import { sendEmail } from '@cio/email';
import { ROLE } from '@cio/utils/constants';
import * as schema from '@cio/db/schema';
import crypto from 'node:crypto';
type OrganizationInviteStatus = 'ACTIVE' | 'EXPIRED' | 'REVOKED' | 'ACCEPTED';
@@ -302,6 +305,8 @@ export async function acceptOrganizationInvite(token: string, user: TAuthUser, c
}
if (status === 'ACCEPTED') {
await markUserAndProfileEmailVerified(user.id, tx);
return {
organization: row.organization,
roleId: row.invite.roleId,
@@ -366,6 +371,8 @@ export async function acceptOrganizationInvite(token: string, user: TAuthUser, c
}
}
await markUserAndProfileEmailVerified(user.id, tx);
const [acceptedInvite] = await tx
.update(schema.organizationInvite)
.set({
@@ -4,6 +4,7 @@ import { and, eq } from 'drizzle-orm';
import { User } from 'better-auth';
import { db } from '@db/drizzle';
import { markUserAndProfileEmailVerified } from '@db/queries/auth';
const DEFAULT_STUDENT_ROLE_ID = 3;
@@ -60,6 +61,8 @@ export async function ensureOrgMembership(
updatedAt: new Date().toISOString()
})
.where(eq(schema.organizationInvite.id, invite.id));
await markUserAndProfileEmailVerified(userId, tx);
});
console.debug('User joined org via invite:', orgId);
+7 -1
View File
@@ -515,6 +515,12 @@ export async function getExerciseWithRelationsOptimized(
*/
export async function syncOptionIdSequence(dbClient: DbOrTxClient = db): Promise<void> {
await dbClient.execute(
sql`SELECT setval(pg_get_serial_sequence('option', 'id'), COALESCE((SELECT MAX(id) FROM "option"), 0))`
sql`
SELECT setval(
pg_get_serial_sequence('option', 'id'),
COALESCE((SELECT MAX(id) FROM "option"), 1),
EXISTS(SELECT 1 FROM "option")
)
`
);
}