From d894f9d6ec13e63f438c11e34e1f54716faab076 Mon Sep 17 00:00:00 2001 From: Marco Pedone Date: Mon, 10 Nov 2025 16:27:15 +0100 Subject: [PATCH] feat: enhance user management and document handling; refactor service and schema integrations --- .../migrations/24_servizio_annunci_id.up.sql | 26 +++ apps/infoalloggi/pgadmin-docker-compose.yml | 1 + .../area-riservata/documenti_personali.tsx | 198 ++++++++++++++++++ .../components/servizio/admin_conferma.tsx | 4 +- .../components/servizio/modale_contatti.tsx | 8 +- .../src/forms/FormProfilo_Account.tsx | 4 +- .../src/forms/FormProfilo_Anagrafica.tsx | 9 +- .../admin/user-view/edit-user/[userId].tsx | 20 +- .../src/pages/area-riservata/profilo.tsx | 28 +-- .../src/schemas/public/Servizio.ts | 4 - .../src/schemas/public/ServizioAnnunci.ts | 5 + .../src/schemas/public/UsersAnagrafica.ts | 5 + .../src/server/api/routers/users.ts | 17 +- .../server/controllers/servizio.controller.ts | 13 +- .../src/server/controllers/user.controller.ts | 65 +++++- .../src/server/services/user.service.ts | 72 +++---- 16 files changed, 381 insertions(+), 98 deletions(-) create mode 100644 apps/db/migrations/24_servizio_annunci_id.up.sql create mode 100644 apps/infoalloggi/src/components/area-riservata/documenti_personali.tsx diff --git a/apps/db/migrations/24_servizio_annunci_id.up.sql b/apps/db/migrations/24_servizio_annunci_id.up.sql new file mode 100644 index 0000000..f298c63 --- /dev/null +++ b/apps/db/migrations/24_servizio_annunci_id.up.sql @@ -0,0 +1,26 @@ +-- Add column only if it doesn't exist +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'servizio_annunci' + AND column_name = 'servizio_annunci_id' + ) THEN + ALTER TABLE public.servizio_annunci + ADD COLUMN servizio_annunci_id serial NOT NULL; + END IF; +END $$; + +-- Add primary key only if it doesn't exist +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conname = 'servizio_annunci_pkey' + AND conrelid = 'public.servizio_annunci'::regclass + ) THEN + ALTER TABLE public.servizio_annunci + ADD PRIMARY KEY (servizio_annunci_id); + END IF; +END $$; \ No newline at end of file diff --git a/apps/infoalloggi/pgadmin-docker-compose.yml b/apps/infoalloggi/pgadmin-docker-compose.yml index 3cbfd9d..1992277 100644 --- a/apps/infoalloggi/pgadmin-docker-compose.yml +++ b/apps/infoalloggi/pgadmin-docker-compose.yml @@ -5,6 +5,7 @@ services: environment: PGADMIN_DEFAULT_EMAIL: m.pedone98@gmail.com PGADMIN_DEFAULT_PASSWORD: rootpost + PGADMIN_CONFIG_CONSOLE_LOG_LEVEL: 10 ports: - "5050:80" volumes: diff --git a/apps/infoalloggi/src/components/area-riservata/documenti_personali.tsx b/apps/infoalloggi/src/components/area-riservata/documenti_personali.tsx new file mode 100644 index 0000000..f020011 --- /dev/null +++ b/apps/infoalloggi/src/components/area-riservata/documenti_personali.tsx @@ -0,0 +1,198 @@ +import { ExternalLink, Trash2 } from "lucide-react"; +import Link from "next/link"; +import toast from "react-hot-toast"; +import { useSession } from "~/providers/SessionProvider"; +import type { UsersStorageUserStorageId } from "~/schemas/public/UsersStorage"; +import type { UserWithAnagrafica } from "~/server/services/user.service"; +import { api } from "~/utils/api"; +import { Confirm } from "../confirm"; +import { ImageFlbk } from "../ImageWithFallback"; +import { LoadingPage } from "../loading"; +import { Button } from "../ui/button"; +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "../ui/card"; +import { UploadModal } from "../upload_modal"; + +export const DocumentiPersonali = ({ + userData, +}: { + userData: UserWithAnagrafica; +}) => { + const utils = api.useUtils(); + const { mutate, isPending } = api.users.editUserAnagrafica.useMutation({ + onSuccess: async () => { + await utils.users.getClientProfilo.invalidate({ + userId: userData.id, + }); + }, + onError: (err) => { + toast.error(`Errore aggiornamento servizio: ${err.message}`); + }, + }); + const handleUpload = ( + field: "doc_personale_fronte_ref" | "doc_personale_retro_ref", + id: UsersStorageUserStorageId, + ) => { + mutate({ + userId: userData.id, + data: { [field]: id }, + }); + }; + + const { user } = useSession(); + if (!user) return null; + if (isPending) return ; + + return ( + + + Documenti personali + +

I tuoi documenti sono necessari per usufruire del servizio.

+

+ Nel caso di un unico documento (es: scansione fronte e retro del + documento) caricarlo 2 volte. +

+
+
+ +
+
+
+

+ Documento d'identità - Fronte +

+ + {userData.doc_personale_fronte?.storageId ? ( +
+ + +
+ + + + { + mutate({ + userId: userData.id, + data: { doc_personale_fronte_ref: null }, + }); + }} + title="Elimina Documento" + > + + +
+
+ ) : ( + + userStorageIds.length > 0 && + userStorageIds[0] && + handleUpload("doc_personale_fronte_ref", userStorageIds[0]) + } + isAdmin={user.isAdmin} + maxFiles={1} + userId={userData.id} + /> + )} +
+
+
+
+

Documento d'identità - Retro

+ {userData.doc_personale_retro?.storageId ? ( +
+ + +
+ + + + { + mutate({ + userId: userData.id, + data: { doc_personale_retro_ref: null }, + }); + }} + title="Elimina Documento" + > + + +
+
+ ) : ( + + userStorageIds.length > 0 && + userStorageIds[0] && + handleUpload("doc_personale_retro_ref", userStorageIds[0]) + } + isAdmin={user.isAdmin} + maxFiles={1} + userId={userData.id} + /> + )} +
+
+
+
+ +

+ I tuoi dati saranno conservati solamente per la durata del servizio, + in conformità con la nostra{" "} + + Informativa sulla Privacy + +

+
+
+ ); +}; diff --git a/apps/infoalloggi/src/components/servizio/admin_conferma.tsx b/apps/infoalloggi/src/components/servizio/admin_conferma.tsx index 372a251..ad63693 100644 --- a/apps/infoalloggi/src/components/servizio/admin_conferma.tsx +++ b/apps/infoalloggi/src/components/servizio/admin_conferma.tsx @@ -57,7 +57,7 @@ export const AdminLavoraConferma = () => { Conferma - + Lavorazione conferma @@ -65,7 +65,7 @@ export const AdminLavoraConferma = () => { -
+
{servizio.tipologia === TipologiaPosizioneEnum.Transitorio && ( diff --git a/apps/infoalloggi/src/components/servizio/modale_contatti.tsx b/apps/infoalloggi/src/components/servizio/modale_contatti.tsx index aa8d5cd..ae1f38b 100644 --- a/apps/infoalloggi/src/components/servizio/modale_contatti.tsx +++ b/apps/infoalloggi/src/components/servizio/modale_contatti.tsx @@ -115,7 +115,7 @@ const DocCheckpoint = () => { const { t } = useTranslation(); const { userId, servizio } = useServizio(); const utils = api.useUtils(); - const { mutate, isPending } = api.servizio.updateServizio.useMutation({ + const { mutate, isPending } = api.users.editUserAnagrafica.useMutation({ onSuccess: async () => { await utils.servizio.getAllServizioAnnunci.invalidate({ userId, @@ -134,8 +134,10 @@ const DocCheckpoint = () => { id: UsersStorageUserStorageId, ) => { mutate({ - servizioId: servizio.servizio_id, - data: { [field]: id }, + userId, + data: { + [field]: id, + }, }); }; return ( diff --git a/apps/infoalloggi/src/forms/FormProfilo_Account.tsx b/apps/infoalloggi/src/forms/FormProfilo_Account.tsx index fa1aa61..5f8e3d0 100644 --- a/apps/infoalloggi/src/forms/FormProfilo_Account.tsx +++ b/apps/infoalloggi/src/forms/FormProfilo_Account.tsx @@ -66,7 +66,9 @@ export const ProfileFormAccount = ({ toast.success(t.profile.aggiornato); await utils.auth.getSession.invalidate(); await utils.users.getUser.invalidate(); - await utils.users.getClientProfilo.invalidate(); + await utils.users.getClientProfilo.invalidate({ + userId: id, + }); }, }); diff --git a/apps/infoalloggi/src/forms/FormProfilo_Anagrafica.tsx b/apps/infoalloggi/src/forms/FormProfilo_Anagrafica.tsx index 03477bb..6980321 100644 --- a/apps/infoalloggi/src/forms/FormProfilo_Anagrafica.tsx +++ b/apps/infoalloggi/src/forms/FormProfilo_Anagrafica.tsx @@ -210,15 +210,16 @@ export const ProfileFormAnagrafica = ({ toast.success(t.profile.aggiornato); await utils.auth.getSession.invalidate(); await utils.users.getUser.invalidate(); - await utils.users.getClientProfilo.invalidate(); + await utils.users.getClientProfilo.invalidate({ + userId: userData.id, + }); }, }); function onSubmit(fields: ProfileFormValues) { mutate({ - ...fields, - idanagrafica: userData.idanagrafica || undefined, - userid: userData.id, + userId: userData.id, + data: { ...fields }, }); } const nazioni_options = GetNazioni(); diff --git a/apps/infoalloggi/src/pages/area-riservata/admin/user-view/edit-user/[userId].tsx b/apps/infoalloggi/src/pages/area-riservata/admin/user-view/edit-user/[userId].tsx index 8aa48da..d12d663 100644 --- a/apps/infoalloggi/src/pages/area-riservata/admin/user-view/edit-user/[userId].tsx +++ b/apps/infoalloggi/src/pages/area-riservata/admin/user-view/edit-user/[userId].tsx @@ -1,5 +1,6 @@ import { Fingerprint, + IdCard, KeyRound, Landmark, Lock, @@ -10,6 +11,7 @@ import { import type { GetServerSideProps } from "next"; import { useRouter } from "next/router"; import toast from "react-hot-toast"; +import { DocumentiPersonali } from "~/components/area-riservata/documenti_personali"; import { AreaRiservataLayoutUserView } from "~/components/Layout"; import { LoadingPage } from "~/components/loading"; import { Status500 } from "~/components/status-page"; @@ -46,7 +48,7 @@ const EditUser: NextPageWithLayout = ({ const router = useRouter(); const utils = api.useUtils(); const { data: userData, isLoading } = api.users.getClientProfilo.useQuery({ - id: userId, + userId, }); const { mutate: delete_mutate } = api.users.deleteUser.useMutation({ onSuccess: async () => { @@ -60,7 +62,9 @@ const EditUser: NextPageWithLayout = ({ const { mutate: ban_mutate } = api.users.blockUser.useMutation({ onSuccess: async (data) => { await utils.users.getUsers.invalidate(); - await utils.users.getClientProfilo.invalidate(); + await utils.users.getClientProfilo.invalidate({ + userId, + }); if (data[0]?.isBlocked) { toast("Utente bloccato con successo", { icon: "🔒" }); } else { @@ -93,6 +97,13 @@ const EditUser: NextPageWithLayout = ({ Anagrafica + + + Documenti + = ({ + + + @@ -226,7 +240,7 @@ export const getServerSideProps = (async (context) => { const helpers = await TrpcAuthedFetchingIstance({ access_token }); if (helpers) { await helpers.trpc.users.getClientProfilo.prefetch({ - id: parsed.data, + userId: parsed.data, }); return { props: { diff --git a/apps/infoalloggi/src/pages/area-riservata/profilo.tsx b/apps/infoalloggi/src/pages/area-riservata/profilo.tsx index 16e47de..35a0b05 100644 --- a/apps/infoalloggi/src/pages/area-riservata/profilo.tsx +++ b/apps/infoalloggi/src/pages/area-riservata/profilo.tsx @@ -1,5 +1,5 @@ -import type { GetServerSideProps } from "next"; import Head from "next/head"; +import { DocumentiPersonali } from "~/components/area-riservata/documenti_personali"; import { AreaRiservataLayout } from "~/components/Layout"; import { LoadingPage } from "~/components/loading"; import { Status500 } from "~/components/status-page"; @@ -18,13 +18,14 @@ import { ProfileFormAnagrafica } from "~/forms/FormProfilo_Anagrafica"; import type { NextPageWithLayout } from "~/pages/_app"; import { useTranslation } from "~/providers/I18nProvider"; import { useEnforcedSession } from "~/providers/SessionProvider"; -import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper"; import { api } from "~/utils/api"; const Dashboard: NextPageWithLayout = () => { const { t } = useTranslation(); + const { user } = useEnforcedSession(); + const { data: userData, isLoading } = api.users.getClientProfilo.useQuery({ - id: undefined, + userId: user.id, }); const session = useEnforcedSession(); if (isLoading) return ; @@ -58,6 +59,7 @@ const Dashboard: NextPageWithLayout = () => { Account Anagrafica + Documenti @@ -106,6 +108,9 @@ const Dashboard: NextPageWithLayout = () => { + + +
@@ -116,23 +121,6 @@ const Dashboard: NextPageWithLayout = () => { }; export default Dashboard; -export const getServerSideProps = (async (context) => { - const access_token = context.req.cookies.access_token; - - const helpers = await TrpcAuthedFetchingIstance({ access_token }); - if (helpers) { - await helpers.trpc.users.getClientProfilo.prefetch({ id: undefined }); - return { - props: { - trpcState: helpers.trpc.dehydrate(), - }, - }; - } - return { - props: {}, - }; -}) satisfies GetServerSideProps; - Dashboard.getLayout = function getLayout(page) { return {page}; }; diff --git a/apps/infoalloggi/src/schemas/public/Servizio.ts b/apps/infoalloggi/src/schemas/public/Servizio.ts index 33f28db..24e3115 100644 --- a/apps/infoalloggi/src/schemas/public/Servizio.ts +++ b/apps/infoalloggi/src/schemas/public/Servizio.ts @@ -61,10 +61,6 @@ export default interface ServizioTable { isOkConsulenza: ColumnType; - doc_personale_fronte_ref: ColumnType; - - doc_personale_retro_ref: ColumnType; - doc_motivazione_ref: ColumnType; scadenza_motivazione_transitoria: ColumnType; diff --git a/apps/infoalloggi/src/schemas/public/ServizioAnnunci.ts b/apps/infoalloggi/src/schemas/public/ServizioAnnunci.ts index 6ad33ae..1b78b6c 100644 --- a/apps/infoalloggi/src/schemas/public/ServizioAnnunci.ts +++ b/apps/infoalloggi/src/schemas/public/ServizioAnnunci.ts @@ -5,8 +5,13 @@ import type { ServizioServizioId } from './Servizio'; import type { AnnunciId } from './Annunci'; import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely'; +/** Identifier type for public.servizio_annunci */ +export type ServizioAnnunciServizioAnnunciId = number & { __brand: 'public.servizio_annunci' }; + /** Represents the table public.servizio_annunci */ export default interface ServizioAnnunciTable { + servizio_annunci_id: ColumnType; + servizio_id: ColumnType; annunci_id: ColumnType; diff --git a/apps/infoalloggi/src/schemas/public/UsersAnagrafica.ts b/apps/infoalloggi/src/schemas/public/UsersAnagrafica.ts index ed37581..faa3450 100644 --- a/apps/infoalloggi/src/schemas/public/UsersAnagrafica.ts +++ b/apps/infoalloggi/src/schemas/public/UsersAnagrafica.ts @@ -2,6 +2,7 @@ // This file is automatically generated by Kanel. Do not modify manually. import type { UsersId } from './Users'; +import type { UsersStorageUserStorageId } from './UsersStorage'; import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely'; /** Identifier type for public.users_anagrafica */ @@ -48,6 +49,10 @@ export default interface UsersAnagraficaTable { codice_destinatario: ColumnType; legale_rappresentante: ColumnType; + + doc_personale_fronte_ref: ColumnType; + + doc_personale_retro_ref: ColumnType; } export type UsersAnagrafica = Selectable; diff --git a/apps/infoalloggi/src/server/api/routers/users.ts b/apps/infoalloggi/src/server/api/routers/users.ts index 8343297..e91ac8d 100644 --- a/apps/infoalloggi/src/server/api/routers/users.ts +++ b/apps/infoalloggi/src/server/api/routers/users.ts @@ -52,9 +52,14 @@ export const usersRouter = createTRPCRouter({ return await editAccountHandler({ ctx, input }); }), editUserAnagrafica: protectedProcedure - .input(z.custom()) + .input( + z.object({ + userId: zUserId, + data: z.custom(), + }), + ) .mutation(async ({ input }) => { - return await editAnagraficaHandler({ input }); + return await editAnagraficaHandler({ ...input }); }), getActiveUsersWithoutChat: adminProcedure.query(async () => { return await getActiveUserWithoutChatHandler({ db }); @@ -62,15 +67,13 @@ export const usersRouter = createTRPCRouter({ getClientProfilo: protectedProcedure .input( z.object({ - id: zUserId.optional(), + userId: zUserId, }), ) - .query(async ({ ctx, input }) => { - const userId = input.id || ctx.session.id; - + .query(async ({ input }) => { return getUserWithAnagraficaHandler({ db, - userId: userId, + userId: input.userId, }); }), getUser: protectedProcedure diff --git a/apps/infoalloggi/src/server/controllers/servizio.controller.ts b/apps/infoalloggi/src/server/controllers/servizio.controller.ts index 6aed8aa..2f92364 100644 --- a/apps/infoalloggi/src/server/controllers/servizio.controller.ts +++ b/apps/infoalloggi/src/server/controllers/servizio.controller.ts @@ -613,6 +613,11 @@ export const getAllServizioAnnunci = async (userId: UsersId) => { return await db .selectFrom("servizio") .where("user_id", "=", userId) + .leftJoin( + "users_anagrafica", + "servizio.user_id", + "users_anagrafica.userid", + ) .select((eb) => [ "servizio.servizio_id", "servizio.created_at", @@ -632,12 +637,12 @@ export const getAllServizioAnnunci = async (userId: UsersId) => { .selectFrom("users_storage") .select([ "users_storage.storageId as storageId", - "servizio.doc_personale_fronte_ref as ref", + "users_anagrafica.doc_personale_fronte_ref as ref", ]) .whereRef( "users_storage.user_storage_id", "=", - "servizio.doc_personale_fronte_ref", + "users_anagrafica.doc_personale_fronte_ref", ), ).as("doc_personale_fronte"), jsonObjectFrom( @@ -645,12 +650,12 @@ export const getAllServizioAnnunci = async (userId: UsersId) => { .selectFrom("users_storage") .select([ "users_storage.storageId as storageId", - "servizio.doc_personale_retro_ref as ref", + "users_anagrafica.doc_personale_retro_ref as ref", ]) .whereRef( "users_storage.user_storage_id", "=", - "servizio.doc_personale_retro_ref", + "users_anagrafica.doc_personale_retro_ref", ), ).as("doc_personale_retro"), jsonObjectFrom( diff --git a/apps/infoalloggi/src/server/controllers/user.controller.ts b/apps/infoalloggi/src/server/controllers/user.controller.ts index a34d6eb..1c513e8 100644 --- a/apps/infoalloggi/src/server/controllers/user.controller.ts +++ b/apps/infoalloggi/src/server/controllers/user.controller.ts @@ -3,7 +3,6 @@ import type { Users, UsersId, UsersUpdate } from "~/schemas/public/Users"; import type { UsersAnagraficaUpdate } from "~/schemas/public/UsersAnagrafica"; import type { Context } from "~/server/api/trpc"; import { db, type Querier } from "~/server/db"; -import { upsertAnagrafica } from "~/server/services/user.service"; import { checkCtxAdmin, checkCtxSession } from "~/server/utils/ctxChecker"; type EditAccountInput = { @@ -58,14 +57,66 @@ export const editAccountHandler = async ({ }; export const editAnagraficaHandler = async ({ - input, + userId, + data, }: { - input: UsersAnagraficaUpdate; + userId: UsersId; + data: UsersAnagraficaUpdate; }) => { - return await upsertAnagrafica({ - data: input, - db, - }); + try { + // biome-ignore lint/correctness/noUnusedVariables: + const { idanagrafica, userid, ...rest } = data; + if (!userId) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: "Errore interno, utente non trovato", + }); + } + + // if (anagraficaId) { + // return await db + // .updateTable("users_anagrafica") + // .set({ + // ...rest, + // }) + // .where("userid", "=", userId) + // .returningAll() + // .executeTakeFirst(); + // } + // const searched = await db + // .selectFrom("users_anagrafica") + // .select("idanagrafica") + // .where("userid", "=", userId) + // .executeTakeFirst(); + // if (searched) { + // return await db + // .updateTable("users_anagrafica") + // .set({ + // ...rest, + // }) + // .where("userid", "=", userId) + // .returningAll() + // .executeTakeFirst(); + // } + return await db + .insertInto("users_anagrafica") + .values({ + ...rest, + userid: userId, + }) + .onConflict((oc) => + oc.column("userid").doUpdateSet({ + ...rest, + }), + ) + .returningAll() + .executeTakeFirst(); + } catch (e) { + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: `Errore updateAnagrafica: ${(e as Error).message}`, + }); + } }; export const deleteUserHandler = async ({ diff --git a/apps/infoalloggi/src/server/services/user.service.ts b/apps/infoalloggi/src/server/services/user.service.ts index 7b9ebc9..eee0edb 100644 --- a/apps/infoalloggi/src/server/services/user.service.ts +++ b/apps/infoalloggi/src/server/services/user.service.ts @@ -1,6 +1,6 @@ import { TRPCError } from "@trpc/server"; +import { jsonObjectFrom } from "kysely/helpers/postgres"; import type { NewUsers, UsersId } from "~/schemas/public/Users"; -import type { UsersAnagraficaUpdate } from "~/schemas/public/UsersAnagrafica"; import type { Session } from "~/server/api/trpc"; import { db, type Querier } from "~/server/db"; @@ -125,6 +125,34 @@ export const getUserWithAnagraficaHandler = async ({ .where("id", "=", userId) .leftJoin("users_anagrafica", "users_anagrafica.userid", "users.id") .selectAll("users_anagrafica") + .select((eb) => [ + jsonObjectFrom( + eb + .selectFrom("users_storage") + .select([ + "users_storage.storageId as storageId", + "users_anagrafica.doc_personale_fronte_ref as ref", + ]) + .whereRef( + "users_storage.user_storage_id", + "=", + "users_anagrafica.doc_personale_fronte_ref", + ), + ).as("doc_personale_fronte"), + jsonObjectFrom( + eb + .selectFrom("users_storage") + .select([ + "users_storage.storageId as storageId", + "users_anagrafica.doc_personale_retro_ref as ref", + ]) + .whereRef( + "users_storage.user_storage_id", + "=", + "users_anagrafica.doc_personale_retro_ref", + ), + ).as("doc_personale_retro"), + ]) .executeTakeFirstOrThrow(); } catch (e) { throw new TRPCError({ @@ -133,45 +161,3 @@ export const getUserWithAnagraficaHandler = async ({ }); } }; - -export const upsertAnagrafica = async ({ - db, - data, -}: { - db: Querier; - data: UsersAnagraficaUpdate; -}) => { - try { - const { idanagrafica, userid, ...rest } = data; - if (!userid) { - throw new TRPCError({ - code: "BAD_REQUEST", - message: "Errore interno, utente non trovato", - }); - } - if (idanagrafica) { - return await db - .updateTable("users_anagrafica") - .set({ - ...rest, - }) - .where("userid", "=", userid) - .returningAll() - .executeTakeFirst(); - } - return await db - .insertInto("users_anagrafica") - .values({ - userid, - ...rest, - }) - .onConflict((oc) => oc.column("userid").doNothing()) - .returningAll() - .executeTakeFirst(); - } catch (e) { - throw new TRPCError({ - code: "INTERNAL_SERVER_ERROR", - message: `Errore updateAnagrafica: ${(e as Error).message}`, - }); - } -};