Skip to content

Commit 4e95562

Browse files
committed
♻️ replace direct DB query with GetModerationWithUser repository
Replace direct database query in validate controller with proper repository pattern: - Rename GetModeration to GetModerationWithUser for clarity - Use await-to-js pattern for error handling as per CONTRIBUTING.md - Properly handle NotFoundError to return 404 response - Rename error variables to avoid naming conflicts (moderation_error, domain_error, join_error) This follows the established repository pattern and improves code consistency.
1 parent 4efbab4 commit 4e95562

File tree

8 files changed

+42
-46
lines changed

8 files changed

+42
-46
lines changed

sources/moderations/api/src/:id/$procedures/processed.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { IdentiteProconnect_Pg_Context } from "@~/app.middleware/set_identi
77
import type { UserInfoVariables_Context } from "@~/app.middleware/set_userinfo";
88
import { MODERATION_EVENTS } from "@~/moderations.lib/event";
99
import { mark_moderatio_as_rejected } from "@~/moderations.lib/usecase/mark_moderatio_as_rejected";
10-
import { GetModeration } from "@~/moderations.repository";
10+
import { GetModerationWithUser } from "@~/moderations.repository";
1111
import { Hono } from "hono";
1212

1313
//
@@ -20,8 +20,8 @@ export default new Hono<
2020
async ({ text, req, notFound, var: { identite_pg, userinfo } }) => {
2121
const { id } = req.valid("param");
2222

23-
const get_moderation = await GetModeration(identite_pg);
24-
const moderation = await get_moderation(id);
23+
const get_moderation_with_user = GetModerationWithUser(identite_pg);
24+
const moderation = await get_moderation_with_user(id);
2525

2626
if (!moderation) return notFound();
2727

sources/moderations/api/src/:id/$procedures/rejected.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { reject_form_schema } from "@~/moderations.lib/schema/rejected.form";
1111
import { mark_moderation_as } from "@~/moderations.lib/usecase/mark_moderation_as";
1212
import { RespondToTicket } from "@~/moderations.lib/usecase/RespondToTicket";
1313
import { SendRejectedMessageToUser } from "@~/moderations.lib/usecase/SendRejectedMessageToUser";
14-
import { GetModeration, UpdateModerationById } from "@~/moderations.repository";
14+
import { GetModerationWithUser, UpdateModerationById } from "@~/moderations.repository";
1515
import { Hono } from "hono";
1616
import type { ContextType } from "./context";
1717

@@ -30,8 +30,8 @@ export default new Hono<ContextType>().patch(
3030
const { id: moderation_id } = req.valid("param");
3131
const { message, reason, subject } = req.valid("form");
3232

33-
const get_moderation = GetModeration(identite_pg);
34-
const moderation = await get_moderation(moderation_id);
33+
const get_moderation_with_user = GetModerationWithUser(identite_pg);
34+
const moderation = await get_moderation_with_user(moderation_id);
3535
const crisp = CrispApi(crisp_config);
3636
const update_moderation_by_id = UpdateModerationById({ pg: identite_pg });
3737
const respond_to_ticket = RespondToTicket();

sources/moderations/api/src/:id/$procedures/validate.ts

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22

33
import { zValidator } from "@hono/zod-validator";
4-
import { HTTPError } from "@~/app.core/error";
4+
import { HTTPError, NotFoundError } from "@~/app.core/error";
55
import type { Htmx_Header } from "@~/app.core/htmx";
66
import { Entity_Schema } from "@~/app.core/schema";
77
import { z_email_domain } from "@~/app.core/schema/z_email_domain";
@@ -16,7 +16,7 @@ import { MODERATION_EVENTS } from "@~/moderations.lib/event";
1616
import { validate_form_schema } from "@~/moderations.lib/schema/validate.form";
1717
import { mark_moderation_as } from "@~/moderations.lib/usecase/mark_moderation_as";
1818
import { MemberJoinOrganization } from "@~/moderations.lib/usecase/member_join_organization";
19-
import { GetModerationById } from "@~/moderations.repository";
19+
import { GetModerationById, GetModerationWithUser } from "@~/moderations.repository";
2020
import {
2121
AddVerifiedDomain,
2222
GetFicheOrganizationById,
@@ -47,18 +47,14 @@ export default new Hono<App_Context>().patch(
4747
get_organization_by_id: GetFicheOrganizationById({ pg: identite_pg }),
4848
mark_domain_as_verified: MarkDomainAsVerified(identite_pg_client),
4949
});
50-
const moderation = await identite_pg.query.moderations.findFirst({
51-
columns: {
52-
comment: true,
53-
id: true,
54-
organization_id: true,
55-
user_id: true,
56-
},
57-
with: { user: { columns: { email: true } } },
58-
where: eq(schema.moderations.id, id),
59-
});
60-
61-
if (!moderation) return notFound();
50+
const get_moderation_with_user = GetModerationWithUser(identite_pg);
51+
52+
const [moderation_error, moderation] = await to(get_moderation_with_user(id));
53+
54+
if (moderation_error) {
55+
if (moderation_error instanceof NotFoundError) return notFound();
56+
throw moderation_error;
57+
}
6258

6359
const {
6460
organization_id,
@@ -71,7 +67,7 @@ export default new Hono<App_Context>().patch(
7167

7268
//#region ✨ Add verified domain
7369
if (add_domain) {
74-
const [error] = await to(
70+
const [domain_error] = await to(
7571
add_verified_domain({
7672
organization_id,
7773
domain,
@@ -80,16 +76,16 @@ export default new Hono<App_Context>().patch(
8076
}),
8177
);
8278

83-
match(error)
79+
match(domain_error)
8480
.with(P.instanceOf(HTTPError), () => {
85-
consola.error(error);
86-
sentry.captureException(error, {
81+
consola.error(domain_error);
82+
sentry.captureException(domain_error, {
8783
data: { domain, organization_id: id },
8884
});
8985
})
9086
.with(P.instanceOf(Error), () => {
91-
consola.error(error);
92-
throw error;
87+
consola.error(domain_error);
88+
throw domain_error;
9389
});
9490
}
9591
//#endregion
@@ -109,20 +105,20 @@ export default new Hono<App_Context>().patch(
109105
}),
110106
get_moderation_by_id: GetModerationById({ pg: identite_pg }),
111107
});
112-
const [error] = await to(
108+
const [join_error] = await to(
113109
member_join_organization({ is_external, moderation_id: id }),
114110
);
115111

116-
match(error)
112+
match(join_error)
117113
.with(P.instanceOf(HTTPError), () => {
118-
consola.error(error);
119-
sentry.captureException(error, {
114+
consola.error(join_error);
115+
sentry.captureException(join_error, {
120116
data: { domain, organization_id: id },
121117
});
122118
})
123119
.with(P.instanceOf(Error), () => {
124-
consola.error(error);
125-
throw error;
120+
consola.error(join_error);
121+
throw join_error;
126122
});
127123

128124
//#endregion

sources/moderations/lib/src/context/rejected.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import type { AgentConnect_UserInfo } from "@~/app.middleware/session";
44
import type { CrispApi } from "@~/crisp.lib/api";
55
import type { IdentiteProconnect_PgDatabase } from "@~/identite-proconnect.database";
6-
import type { GetModerationDto } from "@~/moderations.repository";
6+
import type { GetModerationWithUserDto } from "@~/moderations.repository";
77
import type { RejectedMessage } from "../schema/rejected.form";
88

99
//
1010

1111
export type RejectedModeration_Context = {
1212
crisp: CrispApi;
13-
moderation: GetModerationDto;
13+
moderation: GetModerationWithUserDto;
1414
pg: IdentiteProconnect_PgDatabase;
1515
reason: string;
1616
resolve_delay: number;

sources/moderations/lib/src/usecase/mark_moderatio_as_rejected.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { AgentConnect_UserInfo } from "@~/app.middleware/session";
55
import type { IdentiteProconnect_PgDatabase } from "@~/identite-proconnect.database";
66
import {
77
UpdateModerationById,
8-
type GetModerationDto,
8+
type GetModerationWithUserDto,
99
} from "@~/moderations.repository";
1010
import { append_comment } from "../comment_message";
1111

@@ -17,7 +17,7 @@ export async function mark_moderatio_as_rejected({
1717
userinfo,
1818
reason,
1919
}: {
20-
moderation: GetModerationDto;
20+
moderation: GetModerationWithUserDto;
2121
userinfo: AgentConnect_UserInfo;
2222
pg: IdentiteProconnect_PgDatabase;
2323
reason: string;

sources/moderations/repository/src/GetModeration.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
pg,
1212
} from "@~/identite-proconnect.database/testing";
1313
import { beforeAll, beforeEach, expect, test } from "bun:test";
14-
import { GetModeration } from "./GetModeration";
14+
import { GetModerationWithUser } from "./GetModerationWithUser";
1515

1616
//
1717

@@ -25,8 +25,8 @@ test("get a moderation with minimal fields", async () => {
2525
await create_adora_pony_user(pg);
2626
const moderation_id = await create_adora_pony_moderation(pg, { type: "" });
2727

28-
const get_moderation = GetModeration(pg);
29-
const moderation = await get_moderation(moderation_id);
28+
const get_moderation_with_user = GetModerationWithUser(pg);
29+
const moderation = await get_moderation_with_user(moderation_id);
3030

3131
expect(moderation).toMatchInlineSnapshot(`
3232
{
@@ -43,7 +43,7 @@ test("get a moderation with minimal fields", async () => {
4343
});
4444

4545
test("throws NotFoundError when moderation does not exist", async () => {
46-
const get_moderation = GetModeration(pg);
46+
const get_moderation_with_user = GetModerationWithUser(pg);
4747

48-
await expect(get_moderation(999999)).rejects.toThrow("Moderation not found.");
48+
await expect(get_moderation_with_user(999999)).rejects.toThrow("Moderation not found.");
4949
});

sources/moderations/repository/src/GetModeration.ts renamed to sources/moderations/repository/src/GetModerationWithUser.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { eq } from "drizzle-orm";
99

1010
//
1111

12-
export function GetModeration(pg: IdentiteProconnect_PgDatabase) {
13-
return async function get_moderation(moderation_id: number) {
12+
export function GetModerationWithUser(pg: IdentiteProconnect_PgDatabase) {
13+
return async function get_moderation_with_user(moderation_id: number) {
1414
const moderation = await pg.query.moderations.findFirst({
1515
columns: {
1616
id: true,
@@ -29,5 +29,5 @@ export function GetModeration(pg: IdentiteProconnect_PgDatabase) {
2929
};
3030
}
3131

32-
export type GetModerationHandler = ReturnType<typeof GetModeration>;
33-
export type GetModerationDto = Awaited<ReturnType<GetModerationHandler>>;
32+
export type GetModerationWithUserHandler = ReturnType<typeof GetModerationWithUser>;
33+
export type GetModerationWithUserDto = Awaited<ReturnType<GetModerationWithUserHandler>>;

sources/moderations/repository/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22

33
export * from "./GetDuplicateModerations";
4-
export * from "./GetModeration";
4+
export * from "./GetModerationWithUser";
55
export * from "./GetModerationById";
66
export * from "./GetModerationForEmail";
77
export * from "./GetModerationsByUserId";

0 commit comments

Comments
 (0)