-
Notifications
You must be signed in to change notification settings - Fork 169
Added Reconcilation Report Generation Fetaure #48
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?
Added Reconcilation Report Generation Fetaure #48
Conversation
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.
Pull Request Overview
This PR introduces an automated reconciliation workflow that generates AI-powered account reports and delivers them via email. The implementation uses LangGraph4j for workflow orchestration and integrates with Groq's LLM API (via LangChain4j) to generate natural-language, customer-friendly reconciliation summaries.
Key changes:
- Agentic workflow pipeline with three sequential nodes: transaction fetching, LLM-based report generation, and email delivery
- Integration with Groq LLM API for generating narrative-style reconciliation reports
- New REST endpoint (
/api/workflow/run) to trigger the workflow manually
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| application.properties.sample | Added configuration placeholders for Groq API credentials and endpoints |
| ReconState.java | Workflow state class managing account data, transactions, generated reports, and user information |
| TransactionFetchNode.java | First workflow node that retrieves transactions and user details for the logged-in account |
| ReportGenerationNode.java | Second workflow node that uses LLM to generate customer-friendly reconciliation reports |
| MailReportNode.java | Third workflow node that emails the generated report to the account holder |
| GraphBuilder.java | Orchestrator that builds and executes the three-node workflow graph |
| EmailServiceImpl.java | Added HTML email template method for reconciliation reports |
| EmailService.java | Interface method declaration for reconciliation report template |
| WorkFlowController.java | REST controller exposing the workflow execution endpoint |
| LLMConfig.java | Spring configuration for OpenAI chat model bean using Groq API settings |
| pom.xml | Added LangGraph4j and LangChain4j dependencies with version management |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| groq.api.key = your-api-key | ||
| groq.api.model = your-model | ||
| groq.api.endpoint = your-model-endpoint |
Copilot
AI
Oct 22, 2025
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.
Property definitions should not contain spaces around the '=' sign. Remove spaces to follow standard Spring Boot property file conventions: groq.api.key=your-api-key
| groq.api.key = your-api-key | |
| groq.api.model = your-model | |
| groq.api.endpoint = your-model-endpoint | |
| groq.api.key=your-api-key | |
| groq.api.model=your-model | |
| groq.api.endpoint=your-model-endpoint |
| public static final Map<String, Channel<?>> SCHEMA = Map.of( | ||
| ACCOUNT_KEY, Channels.appender(ArrayList::new), | ||
| TXNS_KEY, Channels.appender(ArrayList::new), | ||
| REPORT_KEY, Channels.appender(ArrayList::new), | ||
| USER_KEY, Channels.appender(ArrayList::new) | ||
| ); |
Copilot
AI
Oct 22, 2025
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.
Using appender channels for all keys creates unnecessary complexity since only the last value is retrieved. Consider using Channels.lastValue() or a single-value channel type for ACCOUNT_KEY, REPORT_KEY, and USER_KEY to simplify the retrieval logic and improve performance.
| ReconState.USER_KEY, Map.of( | ||
| "name", userResponse.getName(), | ||
| "email", userResponse.getEmail() | ||
| ) |
Copilot
AI
Oct 22, 2025
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.
Type mismatch: USER_KEY is typed to store UserResponse objects (line 45-47 in ReconState), but this code stores a Map<String, String>. This causes a ClassCastException in MailReportNode line 26. Store the entire userResponse object instead: ReconState.USER_KEY, userResponse
| ReconState.USER_KEY, Map.of( | |
| "name", userResponse.getName(), | |
| "email", userResponse.getEmail() | |
| ) | |
| ReconState.USER_KEY, userResponse |
| // Join the stringified transactions into one block | ||
| String txnSummary = String.join("\n", txns); | ||
|
|
||
| String prompt = """ |
Copilot
AI
Oct 22, 2025
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.
Corrected spelling of 'Reconcilation' to 'Reconciliation' in the PR title (note: appears in title, not in this code file)
| for (var item : compiled.stream(Map.of())) { | ||
| System.out.println("State after step: " + item); | ||
| } |
Copilot
AI
Oct 22, 2025
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.
Console output statements should be replaced with proper logging using SLF4J or similar framework. Add a logger instance: private static final Logger log = LoggerFactory.getLogger(GraphBuilder.class); and use log.info() or log.debug() instead.
| graphBuilder.runGraph(); | ||
| return ResponseEntity.ok("Workflow executed successfully"); | ||
| } catch (Exception e) { | ||
| e.printStackTrace(); |
Copilot
AI
Oct 22, 2025
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.
Using printStackTrace() is not recommended for production code. Replace with proper logging: inject a Logger and use log.error(\"Workflow execution failed\", e); to ensure exceptions are logged through the application's logging framework.
| import java.io.File; | ||
| import java.util.concurrent.CompletableFuture; | ||
|
|
||
| import com.webapp.bankingportal.dto.UserResponse; |
Copilot
AI
Oct 22, 2025
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.
The imported UserResponse class is not used in this file. Remove this unused import.
| import com.webapp.bankingportal.dto.UserResponse; |
|
|
||
| import java.util.concurrent.CompletableFuture; | ||
|
|
||
| import com.webapp.bankingportal.dto.UserResponse; |
Copilot
AI
Oct 22, 2025
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.
The imported UserResponse class is not used in this interface. Remove this unused import.
| import com.webapp.bankingportal.dto.UserResponse; |
📌 Title
Add Agentic Reconciliation Workflow with LLM‑Generated Reports and Email Delivery
📝 Description
This PR introduces a modular agentic workflow for automated account reconciliation in the banking portal. The workflow leverages LangGraph4j for orchestration and LangChain4j (Groq LLM endpoint) for intelligent report generation. It replaces ad‑hoc/manual reconciliation with a reusable, extensible pipeline.
🔄 Changes Introduced
Workflow Graph (GraphBuilder)
Defines a three‑node pipeline:
TransactionFetchNode → fetches transactions + user info
ReportGenerationNode → generates a natural‑language reconciliation report using Groq LLM
MailReportNode → emails the report to the account holder
LLM Integration
Configurable via application.properties (groq.api.key, groq.api.model, groq.api.endpoint)
Centralized LlmConfig bean for clean injection of OpenAiChatModel
Report Enhancements
Balance consistency check (opening + deposits – withdrawals – transfers = closing)
Narrative explanations in plain language (money‑diary style)
Alerts for large withdrawals and low balances
Weekly/monthly trend summaries
Professional, non‑technical formatting (no markdown, no IDs/codes)
Email Delivery
Uses EmailService to send reconciliation reports with a friendly, customer‑facing template
Controller
/api/workflow/run endpoint to trigger the workflow manually
⚙️ Configuration
Add the following to application.properties:
properties
LLM API
groq.api.key=your-groq-api-key
groq.api.model=openai/gpt-oss-120b
groq.api.endpoint=https://api.groq.com/openai/v1
✅ Benefits
Provides end‑to‑end reconciliation automation
Generates human‑friendly, diary‑style reports instead of raw technical logs
Modular design → easy to extend with fraud detection, compliance checks, or chatbot integration
Clean separation of concerns (fetch → generate → deliver)
🚀 Next Steps
Integrate with chatbot interface for on‑demand execution