Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion sources/moderations/api/src/:id/$procedures/rejected.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import { reject_form_schema } from "@~/moderations.lib/schema/rejected.form";
import { mark_moderation_as } from "@~/moderations.lib/usecase/mark_moderation_as";
import { RespondToTicket } from "@~/moderations.lib/usecase/RespondToTicket";
import { SendRejectedMessageToUser } from "@~/moderations.lib/usecase/SendRejectedMessageToUser";
import { GetModerationWithUser, UpdateModerationById } from "@~/moderations.repository";
import {
GetModerationWithUser,
UpdateModerationById,
} from "@~/moderations.repository";
import { Hono } from "hono";
import type { ContextType } from "./context";

Expand Down
33 changes: 17 additions & 16 deletions sources/moderations/api/src/:id/$procedures/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import type { Htmx_Header } from "@~/app.core/htmx";
import { Entity_Schema } from "@~/app.core/schema";
import { z_email_domain } from "@~/app.core/schema/z_email_domain";
import type { App_Context } from "@~/app.middleware/context";
import { schema } from "@~/identite-proconnect.database";
import { send_moderation_processed_email } from "@~/identite-proconnect.lib/index";
import {
ForceJoinOrganization,
Expand All @@ -16,15 +15,17 @@ import { MODERATION_EVENTS } from "@~/moderations.lib/event";
import { validate_form_schema } from "@~/moderations.lib/schema/validate.form";
import { mark_moderation_as } from "@~/moderations.lib/usecase/mark_moderation_as";
import { MemberJoinOrganization } from "@~/moderations.lib/usecase/member_join_organization";
import { GetModerationById, GetModerationWithUser } from "@~/moderations.repository";
import {
GetModerationById,
GetModerationWithUser,
} from "@~/moderations.repository";
import {
AddVerifiedDomain,
GetFicheOrganizationById,
} from "@~/organizations.lib/usecase";
import { GetMember } from "@~/users.repository";
import { GetMember, UpdateUserByIdInOrganization } from "@~/users.repository";
import { to } from "await-to-js";
import consola from "consola";
import { and, eq } from "drizzle-orm";
import { Hono } from "hono";
import { P, match } from "ts-pattern";

Expand All @@ -48,9 +49,14 @@ export default new Hono<App_Context>().patch(
mark_domain_as_verified: MarkDomainAsVerified(identite_pg_client),
});
const get_moderation_with_user = GetModerationWithUser(identite_pg);

const [moderation_error, moderation] = await to(get_moderation_with_user(id));

const update_user_by_id_in_organization = UpdateUserByIdInOrganization({
pg: identite_pg,
});

const [moderation_error, moderation] = await to(
get_moderation_with_user(id),
);

if (moderation_error) {
if (moderation_error instanceof NotFoundError) return notFound();
throw moderation_error;
Expand Down Expand Up @@ -125,15 +131,10 @@ export default new Hono<App_Context>().patch(

//#region ✨ Change the verification type of the user in the organization
if (verification_type) {
await identite_pg
.update(schema.users_organizations)
.set({ verification_type })
.where(
and(
eq(schema.users_organizations.user_id, user_id),
eq(schema.users_organizations.organization_id, organization_id),
),
);
await update_user_by_id_in_organization(
{ organization_id, user_id },
{ verification_type },
);
}
//#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import {
} from "@~/moderations.repository";
import { GetUserById } from "@~/users.repository";
import { get_zammad_mail } from "@~/zammad.lib/get_zammad_mail";
import { usePageRequestContext } from "./context";
import { to } from "await-to-js";
import { and, asc, eq, ilike, not, or } from "drizzle-orm";
import { raw } from "hono/html";
import { createContext, useContext } from "hono/jsx";
import { usePageRequestContext } from "./context";

//

Expand Down
4 changes: 3 additions & 1 deletion sources/moderations/repository/src/GetModeration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,7 @@ test("get a moderation with minimal fields", async () => {
test("throws NotFoundError when moderation does not exist", async () => {
const get_moderation_with_user = GetModerationWithUser(pg);

await expect(get_moderation_with_user(999999)).rejects.toThrow("Moderation not found.");
await expect(get_moderation_with_user(999999)).rejects.toThrow(
"Moderation not found.",
);
});
8 changes: 6 additions & 2 deletions sources/moderations/repository/src/GetModerationWithUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,9 @@ export function GetModerationWithUser(pg: IdentiteProconnect_PgDatabase) {
};
}

export type GetModerationWithUserHandler = ReturnType<typeof GetModerationWithUser>;
export type GetModerationWithUserDto = Awaited<ReturnType<GetModerationWithUserHandler>>;
export type GetModerationWithUserHandler = ReturnType<
typeof GetModerationWithUser
>;
export type GetModerationWithUserDto = Awaited<
ReturnType<GetModerationWithUserHandler>
>;
2 changes: 1 addition & 1 deletion sources/moderations/repository/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//

export * from "./GetDuplicateModerations";
export * from "./GetModerationWithUser";
export * from "./GetModerationById";
export * from "./GetModerationForEmail";
export * from "./GetModerationsByUserId";
export * from "./GetModerationsList";
export * from "./GetModerationWithDetails";
export * from "./GetModerationWithUser";
export * from "./RemoveUserFromOrganization";
export * from "./UpdateModerationById";
122 changes: 122 additions & 0 deletions sources/users/repository/src/UpdateUserByIdInOrganization.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//

import { schema } from "@~/identite-proconnect.database";
import {
create_adora_pony_user,
create_unicorn_organization,
} from "@~/identite-proconnect.database/seed/unicorn";
import {
empty_database,
migrate,
pg,
} from "@~/identite-proconnect.database/testing";
import { beforeAll, beforeEach, expect, setSystemTime, test } from "bun:test";
import { UpdateUserByIdInOrganization } from "./UpdateUserByIdInOrganization";

//

beforeAll(migrate);
beforeEach(empty_database);

beforeAll(() => {
setSystemTime(new Date("2222-01-01T00:00:00.000Z"));
});

//

test("updates user verification type in organization", async () => {
const organization_id = await create_unicorn_organization(pg);
const user_id = await create_adora_pony_user(pg);

// Create user-organization relationship first
await pg.insert(schema.users_organizations).values({
organization_id,
user_id,
is_external: false,
});

setSystemTime(new Date("2222-01-11T00:00:00.000Z"));

const update_user_by_id_in_organization = UpdateUserByIdInOrganization({
pg,
});

await update_user_by_id_in_organization(
{ organization_id, user_id },
{ verification_type: "verified" },
);

const result = await pg.query.users_organizations.findFirst({
where: (table, { and, eq }) =>
and(
eq(table.organization_id, organization_id),
eq(table.user_id, user_id),
),
});

expect(result).toMatchInlineSnapshot(`
{
"created_at": "1970-01-01 00:00:00+00",
"has_been_greeted": false,
"is_external": false,
"needs_official_contact_email_verification": false,
"official_contact_email_verification_sent_at": null,
"official_contact_email_verification_token": null,
"organization_id": 1,
"updated_at": "2222-01-11 00:00:00+00",
"user_id": 1,
"verification_type": "verified",
"verified_at": null,
}
`);
});

test("updates multiple fields in user organization", async () => {
const organization_id = await create_unicorn_organization(pg);
const user_id = await create_adora_pony_user(pg);

// Create user-organization relationship first
await pg.insert(schema.users_organizations).values({
organization_id,
user_id,
is_external: false,
});

setSystemTime(new Date("2222-01-11T00:00:00.000Z"));

const update_user_by_id_in_organization = UpdateUserByIdInOrganization({
pg,
});

await update_user_by_id_in_organization(
{ organization_id, user_id },
{
verification_type: "external",
is_external: true,
},
);

const result = await pg.query.users_organizations.findFirst({
where: (table, { and, eq }) =>
and(
eq(table.organization_id, organization_id),
eq(table.user_id, user_id),
),
});

expect(result).toMatchInlineSnapshot(`
{
"created_at": "1970-01-01 00:00:00+00",
"has_been_greeted": false,
"is_external": true,
"needs_official_contact_email_verification": false,
"official_contact_email_verification_sent_at": null,
"official_contact_email_verification_token": null,
"organization_id": 1,
"updated_at": "2222-01-11 00:00:00+00",
"user_id": 1,
"verification_type": "external",
"verified_at": null,
}
`);
});
35 changes: 35 additions & 0 deletions sources/users/repository/src/UpdateUserByIdInOrganization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//

import {
schema,
type IdentiteProconnect_PgDatabase,
type Writable_Users_Organizations,
} from "@~/identite-proconnect.database";
import { and, eq } from "drizzle-orm";

//

export function UpdateUserByIdInOrganization({
pg,
}: {
pg: IdentiteProconnect_PgDatabase;
}) {
return async function update_user_by_id_in_organization(
{ organization_id, user_id }: { organization_id: number; user_id: number },
values: Writable_Users_Organizations,
) {
await pg
.update(schema.users_organizations)
.set({ ...values, updated_at: new Date().toISOString() })
.where(
and(
eq(schema.users_organizations.organization_id, organization_id),
eq(schema.users_organizations.user_id, user_id),
),
);
};
}

export type UpdateUserByIdInOrganizationHandler = ReturnType<
typeof UpdateUserByIdInOrganization
>;
1 change: 1 addition & 0 deletions sources/users/repository/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from "./GetMember";
export * from "./GetUserById";
export * from "./GetUsersByOrganizationId";
export * from "./GetUsersList";
export * from "./UpdateUserByIdInOrganization";
26 changes: 0 additions & 26 deletions sources/users/repository/src/update_user_by_id_in_organization.ts

This file was deleted.