System Architecture
Relevant source files
The following files were used as context for generating this wiki page:
- MercaditoMovil/MercaditoMovil.Infrastructure/Tools/Scripts/create_csvs.py
- MercaditoMovil/MercaditoMovil.Infrastructure/Repositories/CsvUserRepository.cs
- MercaditoMovil/Mercadito.Domain/Entities/User/User.cs
- MercaditoMovil/MercaditoMovil/Controllers/LoginController.cs
- MercaditoMovil/MercaditoMovil.Application/Service/AuthService.cs
- MercaditoMovil/MercaditoMovil.Application/Validators/UserValidator.cs
- MercaditoMovil/Mercadito.Domain/Interfaces/Interface1.cs
- MercaditoMovil/MercaditoMovil.Application/Features/UserManagement/IAuthService.cs
- MercaditoMovil/MercaditoMovil/Program.cs
- MercaditoMovil/MercaditoMovil/Views/Form1.cs
- MercaditoMovil/MercaditoMovil/Views/Form1.Designer.cs
The MercaditoMovil system is a .NET Windows Forms desktop application designed with a layered architecture. Its primary data persistence mechanism is a set of CSV files located in the MercaditoMovil.Infrastructure/DataFiles/ directory. The architecture separates concerns into distinct layers: Presentation (WinForms UI), Application (business logic services), Domain (entities and interfaces), and Infrastructure (data access and external tools).
A key component of the system is a Python script responsible for generating the initial dataset, including users, markets, and products. The application logic for user management, such as authentication and registration, is handled through services that interact with the data layer via repository interfaces, promoting loose coupling and testability.
Layered Architecture
The application follows a classic layered architecture pattern to separate responsibilities.
- Presentation Layer: A Windows Forms application that serves as the user interface. It is the entry point of the application.
- Sources: Program.cs, Views/Form1.cs
- Controller Layer: Acts as a bridge between the Presentation Layer (Views) and the Application Services.
- Sources: Controllers/LoginController.cs
- Application Layer: Contains the core business logic, services, and validators. It orchestrates operations by using domain entities and repository interfaces.
- Domain Layer: Defines the core business entities and the contracts (interfaces) for repositories. This layer is independent of any specific technology or infrastructure.
- Infrastructure Layer: Implements the data access logic defined by the domain interfaces, in this case, by reading from and writing to CSV files. It also contains tools for data management, like the data generation script.
The following diagram illustrates the dependency flow between the layers.
Data Persistence
The application's data is stored in CSV files. A Python script is provided to generate and populate these files with initial data.
Data Generation
A Python script, create_csvs.py, is responsible for creating a set of CSV files with mock data. This script ensures that the application has a baseline dataset to work with upon first run. It generates data for users, markets, producers, and product catalogs.
Sources: Infrastructure/Tools/Scripts/create_csvs.py:10-31, 375-381
The script creates the following files under MercaditoMovil.Infrastructure/DataFiles/:
| File Path | Description |
|---|---|
DataFiles/GeoLocations/locations.csv | (Optional) Costa Rican geographic data. |
DataFiles/Markets/markets.csv | List of available farmer's markets. |
DataFiles/People/users.csv | Application user data. |
DataFiles/Producers/producers.csv | Producer (vendor) information. |
DataFiles/Catalogs/product_catalog.csv | A master list of all possible products. |
DataFiles/Commerce/producer_products.csv | Links producers to the products they sell. |
Sources: Infrastructure/Tools/Scripts/create_csvs.py:23-31
Data Schema
The relationships between the main data entities generated by the script can be visualized as follows.
User Data Repository
The CsvUserRepository class is the concrete implementation for accessing user data. It implements the IUserRepository interface from the Domain layer.
- Reading: It uses
Microsoft.VisualBasic.FileIO.TextFieldParserfor robust parsing of CSV files, handling quoted fields correctly. TheGetByUsernamemethod performs a sequential scan of theusers.csvfile to find a matching user. - Writing: The
Addmethod appends a new user record to theusers.csvfile. It includes logic to create the directory and the file with a header row if they do not exist.
Sources: Infrastructure/Repositories/CsvUserRepository.cs:14, 34, 71
Domain Model
The core of the business domain is represented by entities and interfaces.
User Entity
The User class is a plain data object representing an application user. All its properties are strings, and the constructor ensures that any null inputs are defaulted to empty strings to prevent null reference exceptions.
The table below details the properties of the User entity.
| Property | Type | Description |
|---|---|---|
UserId | string | Unique identifier for the user (e.g., USR-XXXXXXXX). |
Username | string | The user's login name. |
Password | string | The user's password. |
FirstName | string | User's first name. |
LastName1 | string | User's first last name. |
LastName2 | string | User's second last name. |
NationalId | string | National identification number. |
Email | string | User's email address. |
Phone | string | User's phone number. |
ExactAddress | string | User's detailed street address. |
Province | string | Province of residence. |
Canton | string | Canton of residence. |
District | string | District of residence. |
MarketId | string | ID of the user's preferred market. |
Sources: Domain/Entities/User/User.cs:8-56
Authentication Flow
User authentication is a central feature, involving components from the Application, Domain, and Infrastructure layers.
Component Interaction
The authentication process relies on a clear separation of concerns, with interfaces defining the contracts between services and repositories.
Login Sequence
The user login process demonstrates the interaction between the different layers.
- The
LoginControllerreceives the username and password from the UI. - It calls the
AuthService.Loginmethod. AuthServicefirst usesUserValidatorto check for empty inputs.- If validation passes, it calls
IUserRepository.GetByUsernameto retrieve the user data from the CSV file. AuthServicethen compares the provided password with the one stored in the retrievedUserobject.- A success or failure message is returned up the call stack.
Registration Sequence
The user registration process is similar, with additional validation and a write operation.
- The
LoginControllergathers user data and callsAuthService.RegisterBasic. AuthServicecreates aUserobject.- It uses
UserValidator.ValidateRegisterto check required fields. - It checks for duplicate usernames by calling
IUserRepository.GetByUsername. - If all checks pass, it calls
IUserRepository.Addto persist the new user to the CSV file.
Sources: Controllers/LoginController.cs:28-44, Application/Service/AuthService.cs:41-61, Application/Validators/UserValidator.cs:24, Infrastructure/Repositories/CsvUserRepository.cs:71