Stages of creating a digital product: from concept to scale
David Shergilashvili
???? Engineering Manager | ??? .NET Solution Architect | ?? Software Developer | ?? Herding Cats and Microservices
Introduction
The financial industry is constantly seeking ways to improve customer satisfaction through digital products and services. Our idea is to create an iOS and Android mobile application that offers personalized banking offers and promotions based on the user's geolocation. To successfully implement this project, we will use the Agile methodology, and the software will be developed with a microservice architecture and the latest technology stack.
Concept Formation
At the start of the project, the Product Owner conducted several brainstorming sessions with key Stakeholders. They jointly discussed financial market analysis and trends, as well as the best examples of similar applications. As a result, it was decided to focus on providing the user with the simplest and most intuitive experience possible, where personalization based on location will play a major role.
Requirements Management
Business analysts and product managers led the process of identifying and documenting requirements. All needs were reflected as User Stories in Jira, while detailed descriptions and specifications were stored in Confluence. For example:
Story-124
In order to find a favorable offer for a home loan As a bank customer
I want to see a relevant offer at a branch in my neighborhood
This requirement can be broken down into smaller, formulated tasks:
- [DEV] LocationService: determine the user's location based on GPS or IP
- [UX] display branch details on the map with a marker
- [API] filter offers by location
Product Design
Using Figma, User Experience designers created a prototype of the application's graphical interface. They developed the following main screens:
1. Home page - displays the user's current location and nearby branches or ATMs
2. Offers - provides a list of personalized offers based on location
3. Profile - this page allows editing personal information and location settings
Styled Components are used to build design components:
```jsx
const OfferCard = styled.div`
background-color: white;
border-radius: 8px;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
padding: 16px;
margin-bottom: 16px;
`;
const OfferTitle = styled.h3`
font-size: 18px;
margin-bottom: 8px;
`;
const OfferDescription = styled.p`
font-size: 14px;
color: #666;
`;
```
Building the Program Logic
The foundation of the application will be a microservice architecture, where each component functions more or less independently. We will have the following main services:
- AuthService: responsible for user authorization and authentication (e.g., using JWT tokens)
- AccountService: performs operations related to accounts and balances
- GeoService: provides information about the user's location, connects to external Geocoding APIs
- OffersService: contains business logic for creating and delivering personalized offers, depending on the previous two services
Communication between services will be carried out according to HTTP/REST or Messaging protocols (e.g., RabbitMQ). Below is an example of one of the endpoints of AccountService in ASP.NET Core:
```csharp
[HttpGet("{id}")]
public async Task<ActionResult<Account>> GetAccountById(int id)
{
var account = await _context.Accounts.FindAsync(id);
if (account == null)
{
return NotFound();
}
return Ok(account);
}
```
On the client side, we will write iOS and Android apps using React Native. For example, the component for the main screen might look like this:
```jsx
function HomeScreen() {
const [location, setLocation] = useState(null);
const [offers, setOffers] = useState([]);
useEffect(() => {
// get user's location
getLocation().then(coords => setLocation(coords));
}, []);
useEffect(() => {
if (location) {
// get offers from server
fetchOffers(location).then(data => setOffers(data));
}
}, [location]);
return (
<View>
<Text>You are at: {location?.latitude}, {location?.longitude}</Text>
{offers.map(offer => (
<OfferCard key={offer.id}>
<OfferTitle>{offer.title}</OfferTitle>
<OfferDescription>{offer.description}</OfferDescription>
</OfferCard>
))}
</View>
);
}
```
领英推荐
Continuous Integration and Testing
For quality control purposes, our CI/CD process uses a Jenkins server, which should have a Pipeline set up for the entire testing cycle. Any changes to the code (Git Push) will trigger unit tests, static analysis (SonarQube), as well as integration tests to ensure the product's readiness. For example, a unit test for GeoService:
```csharp
[Fact]
public async Task GetNearbyLocations_ValidCoordinates_ReturnsLocations()
{
// Arrange
var service = new GeoService();
var latitude = 40.7128;
var longitude = -74.0060;
// Act
var locations = await service.GetNearbyLocations(latitude, longitude);
// Assert
Assert.NotEmpty(locations);
foreach (var location in locations)
{
Assert.True(location.DistanceToUser <= 5000); // within 5 km radius
}
}
```
Staging and UAT
After the build, components are packaged into Docker images and launched in an environment similar to production - an internal Kubernetes cluster. Fragment of K8s Deployment configuration:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: account-service
spec:
replicas: 3
selector:
matchLabels:
app: account-service
template:
metadata:
labels:
app: account-service
spec:
containers:
- name: account-service
image: myrepo/account-service:v1.2
ports:
- containerPort: 80
```
At the UAT stage, real users test the product, including the QA team going through critical scenarios. Defects are recorded in Jira, for example:
Bug-451
When I try to log into the application from home (location X)
I get the error "Location cannot be detected"
The Product Owner reviews the test results and makes the final decision on readiness for release.
Release and Monitoring
After approval, the DevOps team deploys the product to the K8s production cluster, where the Pods are already connected to the real database. At this stage, the health of all components is again checked, and load tests are simulated.
Subsequently, the entire infrastructure is transferred to the management of the SRE team, which monitors the system 24/7. They will observe metrics on Grafana dashboards, such as:
- CPU and memory usage
- HTTP request performance and latency
- Log levels (Error, Warning)
- Database query delays
For example, the Prometheus Alert Manager file might contain the following:
```yaml
groups:
- name: memory_usage
rules:
- alert: high_memory_usage_on_service
expr: container_memory_usage_bytes{container_name="offers_service"} > 512000000
for: 5m
labels:
severity: critical
annotations:
summary: "High Memory Usage on {{ $labels.container_name }}"
description: "Memory usage is above 512MB for 5 minutes."
```
The operations team pays close attention to the logs, which are centrally collected in Loki and also have visualization supported by Grafana. In relevant searches, logs from all services are available, for example:
```
{container_name="authService"} |= "failed to connect to database"
```
This will allow support specialists to quickly discover the cause of the problem.
Further Product Development
The cycle does not stop after going into production. On the contrary, data collection about user behavior begins, which will be analyzed with the help of Mixpanel or Amplitude. Hypotheses about the use of features will be tested, and A/B testing will be conducted on various UX elements.
Developers are already starting new sprints with tasks taken from the Backlog. They rely on the Agile Scrum framework and constantly strive to improve the quality of the delivered product. Every Pull Request will be checked in the code review process, in order to minimize defects.
If necessary, the DevOps team is ready to scale the infrastructure, for example, with Terraform code:
```hcl
resource "aws_instance" "offers_service" {
count = 4
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "offers-service-${count.index}"
}
}
```
Conclusion
The developed example of mobile banking clearly demonstrates the importance of modern approaches in software projects. Taking into account Agile principles, all team members - developers, testers, operations engineers - were involved in the continuous cycle of creating a digital product. The CI/CD process ensured the ability to make frequent deliveries, with stable quality. While centralized logging and monitoring guaranteed the system's constant readiness.
Using a modern stack (React Native, ASP.NET Core, K8s), it became possible to create a high-performance and scalable application. Security mechanisms, such as JWT authorization, cryptography, etc., protect the user's personal information.
The focus on the user and delivering unique value to them became the main priority of the application. The effectiveness of geolocation-based services exceeds the results obtained with a unified approach. This gives us hope that such a personalized banking product will stand out in the market and earn the love and loyalty of customers.
#MobileBanking #GeolocationServices #PersonalizedOffers #AgileMethodology #MicroserviceArchitecture #ReactNative #ASPNETCore #Kubernetes #DevOps #CI/CD #QualityControl #AutomatedTesting #MonitoringAndLogging #AnalyticsAndOptimization #ContinuousDevelopment #DigitalTransformation #InnovativeApplication #UXDesign #Collaboration #MVP
C# ASP.NET | JavaScript Developer (React, Next, Angular) | Pursuing Microservices & RPA in Financial Services
6 个月Very informative, always enjoy reading your newsletter. Pick an interest on Microservices and RPA from reading the newsletter