feat(backend): Replace Node.js API with .NET 8

This commit completes the migration of the backend service from a Node.js/Express application to an ASP.NET Core 8 Minimal API.

- Re-implemented all API endpoints in C# for improved performance and type safety.
- Updated the Gitea Actions workflow to use the `setup-dotnet` action, `dotnet publish` for building, and now caches NuGet packages.
- Modified the deployment to create an `appsettings.Production.json` file from Gitea secrets instead of a `.env` file.
- Updated the PM2 ecosystem configuration to run the application using the `dotnet` interpreter.
This commit is contained in:
2025-10-29 19:14:20 -03:00
parent f14e298c46
commit 40fd792be1
30 changed files with 1017 additions and 1077 deletions

View File

@@ -1,96 +1,74 @@
# Portfolio API Backend
# JoaoLoureiro.Portfolio Backend
This is a simple and efficient backend server built with Node.js and Express. Its primary purpose is to handle the contact form submissions from the portfolio frontend, sending emails via SMTP using Nodemailer.
This is the backend for my portfolio application. It is a simple .NET 8 API that handles sending contact messages from the frontend.
## ✨ Features
## Technologies
* **Email Service**: Securely sends emails from the contact form.
* **Input Validation**: Ensures required fields (`name`, `email`, `message`) are present and the email format is valid.
* **CORS Enabled**: Configured with CORS to only accept requests from the frontend application.
* **Specific Error Handling**: Returns structured error keys for different SMTP and server issues, allowing the frontend to display translated, user-friendly messages.
* **Health Check**: Includes a `/api/health` endpoint to easily verify if the server is running.
* .NET 8
* ASP.NET Core
* Docker
* Serilog for logging
* FluentValidation for request validation
* AutoMapper for object mapping
## 🛠️ Tech Stack
## Project Structure
* **Runtime**: [Node.js](https://nodejs.org/)
* **Framework**: [Express.js](https://expressjs.com/)
* **Email**: [Nodemailer](https://nodemailer.com/)
* **Environment Variables**: [Dotenv](https://github.com/motdotla/dotenv)
* **Cross-Origin Requests**: [CORS](https://github.com/expressjs/cors)
The solution follows a clean architecture pattern:
## 🚀 Getting Started
* `JoaoLoureiro.Portfolio.Api`: The main API project, containing the endpoint for sending emails.
* `JoaoLoureiro.Portfolio.Application`: Contains the core business logic and interfaces.
* `JoaoLoureiro.Portfolio.Domain`: Contains the domain entities.
* `JoaoLoureiro.Portfolio.Infrastructure`: Contains the implementation of services, such as the email sender.
## Getting Started
### Prerequisites
* Node.js (v18 or later)
* npm
* .NET 8 SDK
* An SMTP server for sending emails.
### Installation & Setup
### Running the application
1. Clone the repository.
2. Navigate to the `backend` directory.
3. Configure the `SmtpSettings` in `JoaoLoureiro.Portfolio.Api/appsettings.json`.
4. Run the application using the following command:
1. **Navigate to the backend directory:**
```bash
cd backend
dotnet run --project JoaoLoureiro.Portfolio.Api
```
2. **Install dependencies:**
```bash
npm install
```
## API Endpoints
3. **Create an environment file:**
Create a file named `.env` in the `backend` directory and populate it with your credentials. **Do not commit this file to version control.**
### POST /api/email/send
**.env.example**
```env
# The port for the backend server
BACKEND_PORT=3001
This endpoint accepts a contact form submission and sends it as an email.
# Your frontend URL for CORS
FRONTEND_URL=http://localhost:3000
**Request Body:**
# Nodemailer SMTP Configuration
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-email@example.com
SMTP_PASS=your-email-password
YOUR_RECEIVING_EMAIL=your-personal-email@example.com
```
```json
{
"name": "John Doe",
"email": "john.doe@example.com",
"message": "Hello, I would like to get in touch with you."
}
```
4. **Run the server:**
```bash
npm start
```
The server will start on the port defined in your `.env` file (e.g., `3001`).
**Responses:**
## 📝 API Endpoints
* `200 OK`: If the message was sent successfully.
* `400 Bad Request`: If the request is invalid.
* `500 Internal Server Error`: If an unexpected error occurs.
### Health Check
### GET /health
* **GET** `/api/health`
* **Description**: Checks the server status.
* **Success Response (200)**:
```json
{ "status": "UP", "message": "Backend is running" }
```
This endpoint returns the health of the application, including the status of the SMTP connection.
### Send Email
## Configuration
* **POST** `/api/email/send`
* **Description**: Processes and sends a contact form submission.
* **Request Body**:
```json
{
"name": "string",
"email": "string",
"message": "string"
}
```
* **Success Response (200)**:
```json
{ "message": "Message sent successfully!" }
```
* **Error Responses (4xx/5xx)**: Returns a JSON object with an `errorKey` for the frontend to translate.
```json
{ "errorKey": "smtp_auth_failed" }
```
The application is configured using the `appsettings.json` file in the `JoaoLoureiro.Portfolio.Api` project.
* `SmtpSettings`: Configuration for the SMTP server.
* `CorsOrigins`: A comma-separated list of allowed origins for CORS.
* `ProxyIP`: The IP address of a trusted proxy.
* `Serilog`: Configuration for logging.