-
-
Notifications
You must be signed in to change notification settings - Fork 8
Feature/ai content workflow #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Monorepo Setup: Initialized the base project scaffolding and configuration using create-awesome-node-app. Fixed dependency errors. Removed unnecessary package folders to simplify the demo solution. Removed extra configurations like changesets and some Turborepo settings to keep the setup straightforward. Frontend: Bootstrapped the frontend project with create vite@latest --template react-ts. Added shadcn and Tailwind CSS for styling. Backend: Bootstrapped the backend project with create-awesome-node-app. Removed unnecessary files and configurations to simplify the setup. Updated fixed versions and made changes to eslint.config.mjs. Docker & Compose: Added Dockerfiles for development purposes to assist with the review process. Added compose.yml for development and review workflows. Notes: Disabled the example test file app.e2e-spec.ts to avoid unresolved lint errors. This commit focuses on setting up the initial solution
…ment modules Removed unused `app.controller` and its test file Updated `app.module` to integrate new modules Added `campaigns` module: - `campaign.entity.ts` for Campaign entity definition - `campaigns.controller.ts` for Campaigns API endpoints - `campaigns.service.ts` for Campaigns business logic - `create-campaign.dto.ts` for Campaign creation validation Added `content-pieces` module: - `content-piece.entity.ts` for ContentPiece entity definition - `content-pieces.controller.ts` for ContentPieces API endpoints - `content-pieces.service.ts` for ContentPieces business logic - DTOs for create and update operations - `review-state.enum.ts` for review state management Added `content-piece-translations` module: - `content-piece-translation.entity.ts` for ContentPieceTranslation entity - `content-piece-translation.controller.ts` for API endpoints - `content-piece-translation.service.ts` for business logic - DTOs for create and update operations Updated `eslint.config.mjs` and `package.json` for new configurations - Add required dependencies like typeORM and class-validator - Config eslint to prevent unnecesary error messages Updated `main.ts` to reflect new application structure
GraphQL API: Added GraphQL resolvers for Campaigns, ContentPieces, and ContentPieceTranslations to enable real-time updates. Subscriptions: Configured PubSub for GraphQL subscriptions to support live updates in the frontend. Modules and Services: - Refactored CampaignsService to include pubSub.publish for event-driven updates. - Added new modules and resolvers for ContentPieceTranslations and ContentPieces. Entity Updates: - Updated Campaign, ContentPiece, and ContentPieceTranslation entities to align with the new GraphQL schema. File Renames: Renamed files in ContentPieceTranslations for consistency with naming conventions. Dependencies: Added required dependencies for GraphQL subscriptions (graphql-subscriptions, @nestjs/graphql, etc.). Configuration: - Updated eslint.config.mjs for TypeScript linting. - Updated main.ts to enable WebSocket support for subscriptions. - Removed: Deleted unused ContentPieceTranslationModule. Why: These changes enable the backend to support a GraphQL API with real-time subscriptions, allowing the frontend to receive live updates for campaigns and content pieces.
UI Components: - Added CampaignTable and CampaignRow components for displaying campaign data. - Added ContentTable and ContentRow components for displaying content pieces. - Introduced reusable UI components: table and tooltip. GraphQL Integration: - Implemented CampaignContext to manage campaign data and handle real-time updates via GraphQL subscriptions. - Added apolloClient setup for GraphQL queries and subscriptions. Pages: - Created CampaignIndex and CampaignEdit pages for campaign management. - Added ContentIndex page for managing content pieces. - Added NotFound page for handling invalid routes. Types and Validation: - Defined TypeScript types in lib/types.ts for campaigns, content pieces, and translations. - Added validators.ts for input validation. Styling: - Updated index.css for basic styling. - Removed unused App.css and react.svg. Configuration: - Updated tsconfig.app.json to include new paths and configurations. - Updated index.html for the new app structure. Why: These changes introduce a basic UI and integrate GraphQL subscriptions to enable real-time updates for campaigns and content pieces. This lays the foundation for further development and testing.
This commit introduces significant updates to the backend to support AI-powered content generation and translation workflows. The changes include: Campaigns Module: Updated the campaign.entity.ts to include relationships with content pieces. Enhanced the campaigns.controller.ts and campaigns.resolver.ts to support querying campaigns with their content and translations. Updated the campaigns.service.ts to handle campaign-related logic more effectively. Content Pieces: Modified the content-piece.entity.ts to establish relationships with translations. Added a new generate-content.dto.ts to handle AI generation requests. Updated the content-pieces.controller.ts and content-pieces.service.ts to include endpoints and logic for generating AI-powered drafts and translations. Integrated LangChain for AI model selection (OpenAI/Anthropic) in langchain.service.ts. Content Piece Translations: Updated the content-piece-translations.entity.ts to support localized translations. Enhanced the content-piece-translations.controller.ts and content-piece-translations.service.ts to manage translation entities. Added validation and DTOs for creating and updating translations. LangChain Integration: Introduced langchain.enum.ts to define supported AI models (OpenAI, Anthropic). Updated langchain.service.ts to handle AI-powered content generation and localization. These changes enable the backend to: Generate AI-powered drafts for content pieces. Provide translation/localization suggestions via AI. Manage relationships between campaigns, content pieces, and translations. Support multi-model AI workflows using LangChain.
…frontend This commit introduces significant updates to the frontend to support the AI-powered content generation and review workflow. The changes include: Core Pages: Updated ContentIndex.tsx to display campaign-specific content pieces and integrate the AI-powered draft generation feature. Updated CampaignIndex.tsx to improve the campaign listing and navigation experience. Added CampaignCreate.tsx for creating new campaigns. Removed CampaignEdit.tsx as its functionality was merged into other components. UI Enhancements: Added reusable UI components: badge.tsx, dialog.tsx, input.tsx, label.tsx, select.tsx, sonner.tsx, and spinner.tsx for consistent and modular UI elements. Updated tooltip.tsx for better user guidance. Added Header.tsx for a consistent page header across the app. Content Management: Enhanced ContentTable and ContentRow components to display content pieces with their review states and AI generation status. Added ReviewDialogForms.tsx to handle review actions (approve/reject) for content pieces. Campaign Management: Improved CampaignTable and CampaignRow components for better campaign visualization and interaction. Context and State Management: Updated CampaignContext.tsx to handle real-time updates for campaigns and content pieces. Added GenerationConfigContext.tsx to manage AI generation configurations (locale, model provider). API Integration: Added API utilities: campaign.ts, contentPiece.ts, contentPieceTranslation.ts, and util.ts for interacting with the backend. Centralized configuration in config.ts and error handling in errors.ts. Styling and Assets: Updated index.css for consistent styling across the app. Added a new favicon (favicon.png) for branding. Miscellaneous: Updated index.html and package.json to reflect the new dependencies and configurations.
…m-lock.yml updates
Hola @joaquinGam, gracias por el PR del challenge técnico! Estuve probando la solución y cubre muy bien los requisitos, se pueden crear campañas y luego con AI generar las content pieces con sus traducciones. También revisé la implementación, de la cual me gustó:
Te dejo también algunas observaciones sobre cosas que quizás se podrían mejorar, y preguntas sobre la solución. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me gusta cómo está organizada la documentación, pero quizás hubiese estado mejor eliminar o modificar un poco los otros archivos que quedaron por defecto del template de Turborepo y otras herramientas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gracias. Actualice un poco las referencias pero quise dejar documentación en referencia al uso del template y que puedan ver que lo use
|
||
if (existingTranslation) { | ||
// Update existing translation | ||
const generatedData = await this.langChainService.generateDraft(locale, 'random', modelProvider); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noté que al generar un content piece con AI, el contenido no tenía nada que ver con el nombre y descripción que le daba a la campaña, lo cual entiendo que es por estos random
que quedaron acá.
Supongo que es algo que quedó viejo, porque tenés la data acá nomás para pasarla y que genere algo relacionado.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claro! Al comienzo la idea era hacer un input en algún formulario, pero pense que quiza seria mejor simplemente utilizar la información de la campaña. Para testear rapido puse el 'random' y luego no lo actualice. Pero si, el poder recibir un parámetro era la idea
apps/frontend/src/index.css
Outdated
button { | ||
border-radius: 8px; | ||
border: 1px solid transparent; | ||
padding: 0.6em 1.2em; | ||
font-size: 1em; | ||
font-weight: 500; | ||
font-family: inherit; | ||
background-color: #1a1a1a; | ||
cursor: pointer; | ||
transition: border-color 0.25s; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me llamó un poco la atención que si bien usaste componentes de shadcn y tailwind para los estilos en general, para algunas cosas usaste css como por ejemplo acá en los botones, hubo alguna razón para eso?
Otra cosa relacionada con los botones es que tienen un problema de contraste, teniendo el background color blanco y el texto también de un tono muy claro, casi no se llegan a leer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
El tema del contraste y el css ocasional fue por lo siguiente: el css quedo viejo y bueno, no me dio tiempo a hacer la revisión de si me había quedado en algún lado.
El tema del contraste es porque al comienzo quería hacer light/dark, para simplificarlo solo implemente uno pero, luego de ya haber subido todo me percate que mi navegador fuerza el modo oscuro. Así que, el problema de accesibilidad viene por de ahí
|
||
export async function create(data: Partial<Campaign>) { | ||
try { | ||
const response = api.post<Campaign, Partial<Campaign>>('/campaigns', data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
faltaron unos await en el create y update
<Link to={`/campaigns/${campaignId}/content/new`} className="text-white underline flex flex-row"> | ||
<Plus className="mr-2" /> Create | ||
</Link> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Este boton lleva a una ruta que no existe, deberia hacer algo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
En un comienzo, iba a dejar que el usuario pueda crear su propio contenido a mano, pero luego lo descarte. El botón quedó viejo
const result = await chain.invoke({ | ||
topic, | ||
sourceLanguage, | ||
json_example: JSON.stringify({ title: 'Exciting Title', description: 'Engaging description text.' }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Si bien pasas un json_example
, el prompt no lo agrega en ningun lado
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Al comienzo le brindaba un ejemplo del json que quería, luego lo removi ya que cambie el prompt. También quedo viejo el input que se envía
…formation specific to the current campaign
Description
Please include a summary of the changes and the related issue. List any dependencies that are required for this change.
Fixes # (issue)
Type of Change
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce.
Checklist