Estructura de la interfaz de Verticales
Introducción
Section titled “Introducción”En este proyecto manejamos una arquitectura basada en verticales. Cada vertical representa un dominio o línea de negocio con sus propias configuraciones, servicios y tipos de datos. Los servicios están tipados con TypeScript para asegurar la consistencia y evitar errores en tiempo de compilación.
Interfaces Principales
Section titled “Interfaces Principales”CommonServices
Section titled “CommonServices”Define los servicios básicos que deben estar presentes en la mayoría o todos los verticales. Cada función acepta ciertos parámetros y retorna un tipo específico.
interface CommonServices { getAllContentsPage: FunctionService<unknown>; getBlogBySlug: FunctionService<Blog, FilterParams>; getBlogs: FunctionService<Blog[], FilterParams>; getChangePassword: FunctionService< ChangePasswordResponse | unknown, ChangePasswordPayload >; getCoursePage: FunctionService<unknown>; getEpisodesBySlug: FunctionService<Episode, Slug>; getExperts: FunctionService<ExpertCardItem[], FilterParams>; getExpertsBySlug: FunctionService<Expert, FilterParams>; getForgotPassword: FunctionService< ForgotPasswordResponse | unknown, ForgotPasswordPayload >; getHomePage: FunctionService<unknown>; getLegalPages: FunctionService<LegalPagesApi, FilterParams>; getModuleCategories: FunctionService< CategoriesByModule, ModuleCategoriesParams >; getMastersPage: FunctionService<unknown>; getPartners: FunctionService<Partner[], FilterParams>; getPartnersBySlug: FunctionService<Partner, FilterParams>; getSeriesByCategory: FunctionService<FilteredSeriesByCategory, FilterParams>; getSeriesBySlug: FunctionService<Serie, FilterParams>; getSeriesPage: FunctionService<Serie, FilterParams>; getUserLogin: FunctionService<Strapi<LoginResponse>, LoginPayload>; getUserRegistration: FunctionService< Strapi<RegisteredUser>, UserRegistrationPayload >;}Notas:
- No se permite que los tipos de retorno usen
?(opcionales) para forzar la implementación. - Si un servicio no aplica a un vertical, se omite en ese vertical.
SpecificServices
Section titled “SpecificServices”Servicios específicos que solo ciertos verticales implementan, por ejemplo:
interface SpecificServices { getDentalProcedure: FunctionService<{ products: (BuyCardItem | ConsultativeCardItem)[]; }>; getPremiumPage: FunctionService<PremiumPage>; getInspiriaTalks: FunctionService<TalksCard[], FilterParams>;}Verticals
Section titled “Verticals”Representa la configuración general de un vertical.
export interface Verticals { analyticsCode?: string; developmentApi: `http://localhost:${number}`; exclusivePages?: LayoutPage[]; favicon: string; i18nDirectory: string; layoutDirectory: string; localeDirectory: string; name: string; primaryColor: string; productionApi: string; productionURL: string; secondaryColor: string; services: CommonServices & Partial<SpecificServices>; strapiService: | "inspiria" | "traumatologia" | "emergencias" | "salud mental" | "oncologia" | "pharma"; subdomain: string; verticalLogo: string; zohoConfig?: ZohoConfig;}Interfaces específicas de Verticales
Section titled “Interfaces específicas de Verticales”- Para controlar qué servicios específicos o comunes implementa cada vertical, existen interfaces derivadas que extienden la interfaz base Verticals.
- Para ello usaremos el patrón
Omitde TypeScript para excluir el camposervicesy luego definirlo con los servicios específicos requeridos. - Usaremos
PickyOmitpara definir qué servicios específicos se implementan en cada vertical.
export interface TraumatologyVertical extends Omit<Verticals, "services"> { services: CommonServices & {};}
export interface InspiriaVertical extends Omit<Verticals, "services"> { services: CommonServices & Pick< SpecificServices, "getPremiumPage" | "getDentalProcedure" | "getInspiriaTalks" >;}
export interface EmergencyVertical extends Omit<Verticals, "services"> { services: CommonServices & Pick<SpecificServices, "getPremiumPage"> & {};}
export interface OncologyVertical extends Omit<Verticals, "services"> { services: Omit< CommonServices, | "getCoursePage" | "getAllContentsPage" | "getHomePage" | "getMastersPage" | "getEpisodesBySlug" | "getSeriesByCategory" | "getSeriesBySlug" | "getSeriesPage" > & {};}
export interface MentalHealthVertical extends Omit<Verticals, "services"> { services: CommonServices & {};}
export interface PharmaVertical extends Omit<Verticals, "services"> { services: Omit< CommonServices, | "getMastersPage" | "getEpisodesBySlug" | "getSeriesByCategory" | "getSeriesBySlug" | "getSeriesPage" | "getModuleCategories" > & {};}Implementación de un Vertical Ejemplo: Pharma
Section titled “Implementación de un Vertical Ejemplo: Pharma”Este vertical es un ejemplo concreto que implementa solo CommonServices sin servicios específicos.
export const PHARMA: PharmaVertical = { name: "pharma", subdomain: "pharma", i18nDirectory: "pharma", primaryColor: "#7049bc", secondaryColor: "#00edc8", productionURL: "https://pharma.alebateducation.com/", productionApi: "https://multiverticales.alebateducation.com/", developmentApi: "http://localhost:1337", favicon: "/favicon-pharma.png", verticalLogo: "/logo-pharma.svg", strapiService: "pharma", services: { getExperts: async (lang, vertical: FilterParams) => await getExperts(lang, vertical), getExpertsBySlug: async (lang, { slug, vertical }: FilterParams) => await getExpertsBySlug(lang, { slug, vertical }), getHomePage: getPharmaHomePage, getCoursePage: getPharmaCoursePage, getPartners: async (lang, vertical: FilterParams) => await getPartners(lang, vertical), getPartnersBySlug: async (lang, { slug, vertical }: FilterParams) => await getPartnersBySlug(lang, { slug, vertical }),
getBlogs: async (lang, vertical: FilterParams) => await getBlogs(lang, vertical), getBlogBySlug: async (lang, { slug, vertical }: FilterParams) => await getBlogBySlug(lang, { slug, vertical }), getAllContentsPage: async (lang) => await getAllContents(lang), getLegalPages: async (lang) => await getLegalPages(lang), getUserRegistration: registerUserForVertical, getUserLogin: loginUserForVertical, getForgotPassword: forgotPasswordForVertical, getChangePassword: changePasswordForVertical, },
localeDirectory: "pharma", layoutDirectory: "pharma", analyticsCode: "G-L001MXFYPR",};Hemos omitido getMastersPage, getEpisodesBySlug, getSeriesByCategory, getSeriesBySlug, getSeriesPage, etc. porque no son relevantes para este vertical.
Puntos importantes:
- Se definen las URLs de producción y desarrollo.
- Se asignan los servicios implementados con funciones asincrónicas.
- Algunos servicios no implementados lanzan errores para evitar uso accidental.
- Se incluye configuración visual y de i18n (localización).
➕ Cómo agregar un nuevo vertical
Section titled “➕ Cómo agregar un nuevo vertical”- Crear una interfaz que extienda
Verticals(ejemplo:MyNewVertical). - Implementar los servicios necesarios siguiendo
CommonServicesy/oSpecificServices. - Definir la configuración visual y URLs propias.
- Registrar el vertical en la configuración general del proyecto.
Errores comunes y recomendaciones
Section titled “Errores comunes y recomendaciones”- No implementar un servicio obligatorio: Puede causar fallos en runtime. Mejor lanzar errores explícitos como en
TRAUMATOLOGY. - Usar tipos incorrectos: Siempre usar los tipos definidos para parámetros y respuestas.
- No manejar idiomas: Siempre pasar el parámetro
langpara asegurar la localización. - Usar
?en tipos de retorno: No permitido enCommonServices, para asegurar implementación.
Conclusión
Section titled “Conclusión”Este sistema tipado y modular facilita la escalabilidad y mantenimiento de verticales en el proyecto, asegurando que cada vertical implemente solo los servicios necesarios y con un contrato claro.