39 Commits

Author SHA1 Message Date
9d7d9d91cd Merge pull request 'dev' (#39) from dev into master
Some checks failed
Deploy Documentation Local / deploy-docs (push) Successful in 26s
Cleanup old test branches / cleanup_branch (push) Failing after 10s
Create Test Construct / deploy_docs (push) Failing after 19s
Create Test Construct / deploy_back (push) Failing after 19s
Create Test Construct / deploy_front (push) Failing after 22s
Create Test Construct / create_test_branch_and_build (push) Has been cancelled
Reviewed-on: #39
2025-09-02 00:57:09 +02:00
750bcc81ef Merge pull request 'workflow' (#38) from feature/docs into dev
All checks were successful
Deploy Documentation Local / deploy-docs (push) Successful in 45s
Deploy Documentation Local / deploy-docs (pull_request) Successful in 27s
Reviewed-on: #38
2025-09-02 00:55:29 +02:00
258b4ebfec --allow-unrelated-histories 2025-09-02 00:54:09 +02:00
2360630544 --allow-unrelated-histories
Some checks failed
Auto-Merge Dev / auto-merge-dev (push) Failing after 1m8s
2025-09-02 00:52:01 +02:00
1ded384fd7 workflows
Some checks failed
Auto-Merge Dev / auto-merge-dev (push) Failing after 1m18s
2025-09-02 00:46:34 +02:00
67e7fe35f9 workflow 2025-09-02 00:22:34 +02:00
a223dfc7c0 workflow
Some checks failed
Auto-Merge Dev / auto-merge-dev (push) Failing after 1m28s
2025-09-02 00:20:09 +02:00
c173cc3b3b workflow
Some checks failed
Auto-Merge Dev / auto-merge-dev (push) Failing after 1m11s
2025-09-02 00:16:26 +02:00
f121899b3b workflow
Some checks failed
Auto-Merge Dev / auto-merge-dev (push) Failing after 34s
2025-09-02 00:13:33 +02:00
523c147957 workflow
All checks were successful
Auto-Merge Dev / auto-merge-dev (push) Successful in 1m28s
2025-09-02 00:10:41 +02:00
ffe955788f Merge pull request 'feature/29' (#37) from feature/29 into master
All checks were successful
Deploy Documentation Local / deploy-docs (push) Successful in 33s
Reviewed-on: #37
2025-09-01 23:15:58 +02:00
0a2353d738 añade automapper 2025-09-01 23:14:57 +02:00
09c211a0fe proyecto preparado para DDD + CQRS 2025-09-01 23:06:17 +02:00
895e40edc0 inicio bases 2025-09-01 22:25:21 +02:00
0ba01a91fa Merge pull request 'merge master' (#11) from dev into master
Reviewed-on: #11
2025-09-01 16:56:38 +02:00
152904671a merge master 2025-09-01 16:56:24 +02:00
2ea9b4363b Merge pull request 'dev' (#10) from dev into master
Reviewed-on: #10
2025-09-01 16:55:10 +02:00
f96b5ee0d7 merge master 2025-09-01 16:55:01 +02:00
a5fdd18315 docs 2025-09-01 16:53:21 +02:00
42c30478e7 docs 2025-09-01 16:52:56 +02:00
e6ce22ca93 Merge pull request 'Actualizar .gitea/workflows/deploy-docs.yaml' (#9) from manuel-patch-1 into master
Reviewed-on: #9
2025-09-01 16:51:22 +02:00
ab5d43f50b Actualizar .gitea/workflows/deploy-docs.yaml 2025-09-01 16:51:07 +02:00
b8186644d0 Merge pull request 'docs' (#8) from dev into master
Reviewed-on: #8
2025-09-01 16:50:07 +02:00
c5072e28a6 docs 2025-09-01 16:49:56 +02:00
2012fcdee0 Merge pull request 'docs' (#7) from dev into master
Reviewed-on: #7
2025-09-01 16:48:33 +02:00
7208296a35 docs 2025-09-01 16:48:23 +02:00
6e048cc906 Merge pull request 'dev' (#5) from dev into master
Reviewed-on: #5
2025-09-01 16:41:58 +02:00
d957bfc07d docs
All checks were successful
Deploy Documentation Local / deploy-docs (push) Successful in 32s
2025-09-01 16:41:36 +02:00
be987dfbed docs
All checks were successful
Deploy Documentation Local / deploy-docs (push) Successful in 26s
2025-09-01 16:33:58 +02:00
57fe16f9ce docs 2025-09-01 16:26:26 +02:00
480ff06731 docs 2025-09-01 16:22:35 +02:00
8e3511472d docs 2025-09-01 16:20:34 +02:00
c6bdd2fe2e docs 2025-09-01 16:15:27 +02:00
4404ec6504 docs 2025-09-01 16:12:59 +02:00
52d19ed9f5 docs 2025-09-01 16:09:26 +02:00
f014199042 docs 2025-09-01 16:06:10 +02:00
393a7c031d docs 2025-09-01 16:00:10 +02:00
2c22e88e63 docs
Some checks failed
Deploy Documentation Local / deploy-docs (push) Failing after 10s
2025-09-01 15:46:45 +02:00
2d07f0feba docs 2025-09-01 15:21:22 +02:00
35 changed files with 805 additions and 43 deletions

View File

@@ -0,0 +1,35 @@
name: Cleanup old test branches
on:
schedule:
- cron: "0 12 * * *"
workflow_dispatch:
jobs:
cleanup_branch:
runs-on: windows
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Delete test branches older than 7 days
shell: powershell
run: |
# Obtener la fecha límite (7 días antes)
$limitDate = (Get-Date).AddDays(-7)
# Obtener todas las ramas remotas test/*
$branches = git branch -r | Where-Object { $_ -match 'origin/test/' }
foreach ($branch in $branches) {
$branchName = $branch.Trim() -replace '^origin/', ''
# Obtener fecha de creación de la rama (aproximación por el primer commit)
$firstCommitDate = git log $branchName --reverse --format="%ci" | Select-Object -First 1
$branchDate = Get-Date $firstCommitDate
if ($branchDate -lt $limitDate) {
Write-Host "Eliminando rama $branchName creada el $branchDate"
git push origin --delete $branchName
}
}

View File

@@ -0,0 +1,74 @@
name: Create Test Construct
run-name: Creating test construct
on:
workflow_dispatch:
inputs:
branch:
description: "Branch to build"
required: true
default: "dev"
schedule:
- cron: "0 12 * * *"
jobs:
create_test_branch_and_build:
runs-on: windows
steps:
- name: Checkout dev branch
uses: actions/checkout@v4
with:
ref: dev
- name: Create test branch with date
id: create_branch
shell: powershell
run: |
$date = Get-Date -Format "yyyyMMdd"
$branchName = "test/$date"
git checkout -b $branchName
git push origin $branchName
Write-Output "::set-output name=branch::$branchName"
deploy_docs:
needs: create_test_branch_and_build
runs-on: windows
steps:
- name: Checkout test branch
uses: actions/checkout@v4
with:
ref: ${{ steps.create_branch.outputs.branch }}
- name: Deploy documentation
uses: ./.gitea/workflows/deploy-docs.yaml
with:
branch: ${{ steps.create_branch.outputs.branch }}
deploy_back:
needs: create_test_branch_and_build
runs-on: windows
steps:
- name: Checkout test branch
uses: actions/checkout@v4
with:
ref: ${{ steps.create_branch.outputs.branch }}
- name: Deploy .net project
uses: ./.gitea/workflows/deploy-back.yaml
with:
branch: ${{ steps.create_branch.outputs.branch }}
deploy_front:
needs: create_test_branch_and_build
runs-on: windows
steps:
- name: Checkout test branch
uses: actions/checkout@v4
with:
ref: ${{ steps.create_branch.outputs.branch }}
- name: Deploy front project
uses: ./.gitea/workflows/deploy-front.yaml
with:
branch: ${{ steps.create_branch.outputs.branch }}

View File

@@ -0,0 +1,49 @@
name: Create Test Construct
run-name: Creating test construct
on:
pull_request:
types: [closed]
branches: [dev, "test/**"]
paths: ["back/**"]
workflow_dispatch:
inputs:
branch:
description: "Branch to deploy"
required: true
default: "dev"
workflow_call:
jobs:
build_and_deploy:
runs-on: windows
steps:
- name: Checkout branch
uses: actions/checkout@v4
# build .net project
- name: Build .NET Project
run: |
dotnet restore
dotnet build
# deploy .net to iis site with path = "D:\iis\es\mcvingenieros\mmorales.photo\back"
- name: Deploy .net project to iis
shell: powershell
run: |
# deploy to iis site back.mmorales.photo that has path = D:\iis\es\mcvingenieros\mmorales.photo\back\
$sourcePath = "D:\iis\es\mcvingenieros\mmorales.photo\back\bin\Release\net9.0\publish"
$destinationPath = "D:\iis\es\mcvingenieros\mmorales.photo\back\"
# Stop IIS site
Stop-WebAppPool -Name "mmorales.photo.back"
# Remove old files
Remove-Item -Path $destinationPath\* -Recurse -Force
# Copy new files
Copy-Item -Path $sourcePath\* -Destination $destinationPath -Recurse
# Start IIS site
Start-WebAppPool -Name "mmorales.photo.back"

View File

@@ -1,27 +1,21 @@
name: Deploy Documentation Local
run-name: Deploying ${{ gitea.repository }} docs locally
run-name: Deploying ${{ vars.GIT_REPOSITORY }} docs locally
on:
workflow_dispatch:
branches:
- dev
paths:
- "docs/**"
push:
branches:
- dev
paths:
- "docs/**"
branches: [dev]
paths: ["docs/**", "mkdocs.yml", ".gitea/workflows/deploy-docs-dev.yaml"]
workflow_dispatch:
inputs:
branch:
description: "Branch to deploy"
required: true
default: "dev"
jobs:
deploy-docs:
runs-on: windows # Ejecutar directamente en el host Windows
steps:
- name: Set up node
shell: powershell
run: |
nvs use latest
- name: Check out repository code
uses: actions/checkout@v4
@@ -36,15 +30,15 @@ jobs:
- name: Build documentation
run: |
cd docs
ls
mkdocs build --site-dir ../build
- name: Deploy to IIS directory
shell: powershell
run: |
$projectName = "${{ gitea.repository_name }}"
$basePath = "${{ secrets.DEPLOY_BASE_PATH }}"
$targetPath = Join-Path $basePath "dev" $projectName
$projectName = "${{ vars.GIT_REPOSITORY }}"
$basePath = Join-Path "${{ secrets.DEPLOY_BASE_PATH }}" "dev"
$targetPath = Join-Path $basePath $projectName
# Crear directorio del proyecto si no existe
if (Test-Path $targetPath) {
@@ -53,7 +47,7 @@ jobs:
New-Item -ItemType Directory -Path $targetPath -Force
# Copiar archivos construidos
Copy-Item -Path "build\*" -Destination $targetPath -Recurse -Force
Copy-Item -Path "..\build\*" -Destination $targetPath -Recurse -Force
Write-Host "Documentation deployed to: $targetPath"
@@ -74,7 +68,7 @@ jobs:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documentación - MCV Ingenieros</title>
<title>Documentacion - MCV Ingenieros</title>
<style>
* {
margin: 0;
@@ -188,8 +182,8 @@ jobs:
<body>
<div class="container">
<div class="header">
<h1>📚 Centro de Documentación</h1>
<p>MCV Ingenieros - Documentación de Proyectos</p>
<h1>Centro de Documentacion</h1>
<p>MCV Ingenieros - Documentacion de Proyectos</p>
</div>
<div class="projects">
@@ -202,10 +196,8 @@ jobs:
$htmlContent += @"
<div class="project-card">
<a href="./$folderName/" class="project-link">
<span class="project-icon">📖</span>
<h3 class="project-title">$folderName</h3>
<div class="project-meta">
<span>🕒</span>
<span>Actualizado: $lastWrite</span>
</div>
</a>
@@ -218,7 +210,7 @@ jobs:
</div>
<div class="footer">
<p>Índice generado automáticamente el $currentDate</p>
<p>Indice generado automaticamente el $currentDate</p>
<p>Powered by Gitea Actions & IIS</p>
</div>
</div>

View File

@@ -2,11 +2,20 @@ name: Deploy Documentation Local
run-name: Deploying ${{ gitea.repository }} docs locally
on:
pull_request:
types: [closed]
branches: [master]
paths: ["docs/**", "mkdocs.yml", ".gitea/workflows/deploy-docs.yaml"]
push:
branches:
- main
paths:
- "docs/**"
branches: [master]
paths: ["docs/**", "mkdocs.yml", ".gitea/workflows/deploy-docs.yaml"]
workflow_dispatch:
inputs:
branch:
description: "Branch to deploy"
required: true
default: "master"
workflow_call:
jobs:
deploy-docs:
@@ -26,13 +35,13 @@ jobs:
- name: Build documentation
run: |
cd docs
ls
mkdocs build --site-dir ../build
- name: Deploy to IIS directory
shell: powershell
run: |
$projectName = "${{ gitea.repository_name }}"
$projectName = "${{ vars.GIT_REPOSITORY }}"
$basePath = "${{ secrets.DEPLOY_BASE_PATH }}"
$targetPath = Join-Path $basePath $projectName
@@ -43,7 +52,7 @@ jobs:
New-Item -ItemType Directory -Path $targetPath -Force
# Copiar archivos construidos
Copy-Item -Path "build\*" -Destination $targetPath -Recurse -Force
Copy-Item -Path "..\build\*" -Destination $targetPath -Recurse -Force
Write-Host "Documentation deployed to: $targetPath"
@@ -54,7 +63,7 @@ jobs:
$indexPath = Join-Path $docsPath "index.html"
# Obtener todos los directorios de documentación
$docFolders = Get-ChildItem -Path $docsPath -Directory | Where-Object { $_.Name -notin @("dev", "test") } | Sort-Object Name
$docFolders = Get-ChildItem -Path $docsPath -Directory | Sort-Object Name
# Generar HTML del índice
$htmlContent = @"
@@ -63,7 +72,7 @@ jobs:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documentación - MCV Ingenieros</title>
<title>Documentacion - MCV Ingenieros</title>
<style>
* {
margin: 0;
@@ -177,8 +186,8 @@ jobs:
<body>
<div class="container">
<div class="header">
<h1>📚 Centro de Documentación</h1>
<p>MCV Ingenieros - Documentación de Proyectos</p>
<h1>Centro de Documentacion</h1>
<p>MCV Ingenieros - Documentacion de Proyectos</p>
</div>
<div class="projects">
@@ -191,10 +200,8 @@ jobs:
$htmlContent += @"
<div class="project-card">
<a href="./$folderName/" class="project-link">
<span class="project-icon">📖</span>
<h3 class="project-title">$folderName</h3>
<div class="project-meta">
<span>🕒</span>
<span>Actualizado: $lastWrite</span>
</div>
</a>
@@ -207,7 +214,7 @@ jobs:
</div>
<div class="footer">
<p>Índice generado automáticamente el $currentDate</p>
<p>Indice generado automaticamente el $currentDate</p>
<p>Powered by Gitea Actions & IIS</p>
</div>
</div>

View File

@@ -0,0 +1,48 @@
name: deploy front
run-name: Deploy Frontend
on:
pull_request:
types: [closed]
branches: [dev, "test/**"]
paths: ["front/**"]
workflow_dispatch:
inputs:
branch:
description: "Branch to deploy"
required: true
default: "dev"
workflow_call:
jobs:
build_and_deploy:
runs-on: windows
steps:
- name: Checkout branch
uses: actions/checkout@v4
# build angular
- name: Build Angular
run: |
npm install
npm run build
- name: Deploy to IIS
shell: powershell
run: |
# deploy to iis site front.mmorales.photo that has path = D:\iis\es\mcvingenieros\mmorales.photo\front\
$sourcePath = "D:\iis\es\mcvingenieros\mmorales.photo\front\dist"
$destinationPath = "D:\iis\es\mcvingenieros\mmorales.photo\front\"
# Stop IIS site
Stop-WebAppPool -Name "mmorales.photo.front"
# Remove old files
Remove-Item -Path $destinationPath\* -Recurse -Force
# Copy new files
Copy-Item -Path $sourcePath\* -Destination $destinationPath -Recurse
# Start IIS site
Start-WebAppPool -Name "mmorales.photo.front"

View File

@@ -0,0 +1,12 @@
using Microsoft.EntityFrameworkCore;
namespace back.Domain;
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
Database.EnsureCreated();
Database.Migrate();
}
}

14
back/Domain/IEntity.cs Normal file
View File

@@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace back.Domain;
public interface IEntity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
string Id
{
get;
set;
}
}

View File

@@ -0,0 +1,20 @@
using AutoMapper;
namespace back.Infrastructure;
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
//CreateMap<Users, User>()
// .ForMember(dest => dest.UserId, opt => opt.MapFrom(src => src.UserId))
// .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.FirstName))
// .ForMember(dest => dest.LastName, opt => opt.MapFrom(src => src.LastName))
// .ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email))
// .ForMember(dest => dest.BirthYear, opt => opt.MapFrom(src => src.Birthday.Year))
// .ForMember(dest => dest.BirthMonth, opt => opt.MapFrom(src => src.Birthday.Month))
// .ForMember(dest => dest.BirthDay, opt => opt.MapFrom(src => src.Birthday.Day))
// .ForMember(dest => dest.OccupationName, opt => opt.Ignore())
}
}

150
back/Program.cs Normal file
View File

@@ -0,0 +1,150 @@
using Autofac.Extensions.DependencyInjection;
using AutoMapper;
using back.Domain;
using back.Infrastructure;
using MCVIngenieros.Healthchecks;
using MediatR.Extensions.FluentValidation.AspNetCore;
using Microsoft.EntityFrameworkCore;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using Scalar.AspNetCore;
using Serilog;
namespace back;
public class Program
{
public static void Main(string[] args)
{
var configFiles = Path.Combine(AppContext.BaseDirectory, "configs");
if (!Directory.Exists(configFiles))
{
Directory.CreateDirectory(configFiles);
}
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
var configurationBuilder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{environment}.json", optional: false, reloadOnChange: true);
var configs = Directory.GetFiles(configFiles, "*.json", SearchOption.AllDirectories);
foreach (var config in configs)
{
configurationBuilder.AddJsonFile(config, optional: true, reloadOnChange: true);
}
var configuration = configurationBuilder.Build();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.MinimumLevel.Verbose()
.Enrich.FromLogContext()
.CreateLogger();
try
{
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddConfiguration(configuration);
builder.Host.UseSerilog();
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(typeof(Program).Assembly);
});
builder.Services.AddFluentValidation([typeof(Program).Assembly]);
builder.Services.AddAutoMapper(opts =>
{
opts.AddProfile<AutoMapperProfile>();
opts.AllowNullCollections = true;
opts.AllowNullDestinationValues = true;
opts.DestinationMemberNamingConvention = new PascalCaseNamingConvention();
});
builder.Services.AddHealthChecksSupport().DiscoverHealthChecks();
builder.Services.AddLogging();
builder.Logging.AddOpenTelemetry(options =>
{
options
.SetResourceBuilder(
ResourceBuilder.CreateDefault()
.AddService(AppDomain.CurrentDomain.FriendlyName))
.AddConsoleExporter();
});
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService(AppDomain.CurrentDomain.FriendlyName))
.WithTracing(tracing => tracing
.AddAspNetCoreInstrumentation()
.AddConsoleExporter())
.WithMetrics(metrics => metrics
.AddAspNetCoreInstrumentation()
.AddConsoleExporter());
builder.Services.AddDataProtection();
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy
.WithOrigins(builder.Configuration.GetSection("AllowedHosts").Get<string[]>() ?? [])
.SetIsOriginAllowedToAllowWildcardSubdomains()
.SetPreflightMaxAge(TimeSpan.FromMinutes(10))
.AllowCredentials()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
builder.Services.AddHttpContextAccessor();
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
});
builder.Services.AddDbContext<ApplicationDbContext>(opts =>
{
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
opts.UseSqlite(connectionString);
});
builder.Services.AddControllers(options =>
{
options.Filters.Add(new Microsoft.AspNetCore.Mvc.RequireHttpsAttribute());
});
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.MapScalarApiReference("/api-docs", opt =>
{
opt.WithTitle("My API Documentation");
});
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Application start-up failed");
}
finally
{
Log.CloseAndFlush();
}
}
}

View File

@@ -0,0 +1,15 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "api-docs",
"applicationUrl": "https://localhost:7157",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "mmorales.photo"
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

3
back/appsettings.json Normal file
View File

@@ -0,0 +1,3 @@
{
}

70
back/back.csproj Normal file
View File

@@ -0,0 +1,70 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="8.4.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Autofac.WebApi2" Version="6.1.1" />
<PackageReference Include="FluentValidation" Version="12.0.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />
<PackageReference Include="MCVIngenieros.Healthchecks" Version="0.0.1" />
<PackageReference Include="MediatR" Version="13.0.0" />
<PackageReference Include="MediatR.Contracts" Version="2.0.1" />
<PackageReference Include="MediatR.Extensions.Autofac.DependencyInjection" Version="13.1.0" />
<PackageReference Include="MediatR.Extensions.FluentValidation.AspNetCore" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Antiforgery" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="9.0.8" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="9.0.8" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Extensions" Version="9.0.8" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="9.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="9.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="9.0.8" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
<PackageReference Include="OpenTelemetry" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Api" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Api.ProviderBuilderExtensions" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
<PackageReference Include="Scalar.AspNetCore" Version="2.7.2" />
<PackageReference Include="Scalar.AspNetCore.Microsoft" Version="2.7.2" />
<PackageReference Include="Scalar.AspNetCore.Swashbuckle" Version="2.7.2" />
<PackageReference Include="Serilog" Version="4.3.0" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="3.0.1" />
<PackageReference Include="Serilog.Enrichers.Process" Version="3.0.0" />
<PackageReference Include="Serilog.Enrichers.Thread" Version="4.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.OpenTelemetry" Version="4.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="9.0.4" />
</ItemGroup>
<ItemGroup>
<Folder Include="Application\" />
<Folder Include="Infrastructure\" />
<Folder Include="Presentation\" />
</ItemGroup>
</Project>

25
back/back.sln Normal file
View File

@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36401.2 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "back", "back.csproj", "{C78E8225-44D3-434B-AC2A-C8F4459BB18C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C78E8225-44D3-434B-AC2A-C8F4459BB18C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C78E8225-44D3-434B-AC2A-C8F4459BB18C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C78E8225-44D3-434B-AC2A-C8F4459BB18C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C78E8225-44D3-434B-AC2A-C8F4459BB18C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D5ABA005-3E91-4220-9B2C-874C0BED7E34}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,15 @@
{
"HealthChecksConfigs": {
"CacheDuration": "00:30:00",
"Timeout": "00:00:05",
"AssembliesToScan": [
"back"
]
//"MyCheck": {
// "RetryAttempts": 2,
// "Timeout": "00:05:00",
// "RetryDelay": "00:00:10",
// "Severity": "Info"
//}
}
}

41
back/configs/serilog.json Normal file
View File

@@ -0,0 +1,41 @@
{
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.OpenTelemetry" ],
"MinimumLevel": {
"Default": "Information"
},
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "Logs/log-.txt",
"rollingInterval": "Day",
"fileSizeLimitBytes": 5242880,
"rollOnFileSizeLimit": true,
"retainedFileCountLimit": 31,
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "OpenTelemetry",
"Args": {
"endpoint": "http://localhost:4317",
"protocol": "Grpc",
"resourceAttributes": {
"service.name": "back.mmorales.photo",
"deployment.environment": "development"
}
}
}
],
"Enrich": [
"FromLogContext",
"WithThreadId",
"WithProcessId",
"WithEnvironmentName"
]
}
}

View File

@@ -2,6 +2,10 @@
---
## Relacionado
- [Introducción](introduccion.md)
## Propósito
Crear una plataforma web que permita a fotógrafos profesionales almacenar, distribuir y colaborar con sus clientes en la gestión de imágenes digitales de manera eficiente y segura.

View File

@@ -1,5 +1,12 @@
# Galerías Fotográficas - Análisis técnico
## Relacionado
- [Introducción](introduccion.md)
- [Acta de constitución](acta-constitucion.md)
- [Decisiones de arquitectura](decisiones-arquitectura.md)
- [Documentación de la API](documentacion-api.md)
## Arquitectura del sistema
Queremos hacer un sistema modular, con componentes independientes que se puedan desarrollar, probar e implementar de forma aislada.

View File

@@ -1,5 +1,12 @@
# Galerías Fotográficas - Casos de Uso
## Relacionado
- [Introducción](introduccion.md)
- [Acta de constitución](acta-constitucion.md)
- [Análisis técnico](analisis-tecnico.md)
- [Requisitos funcionales](requisitos-funcionales.md)
## Caso de uso 1: Administrador da de alta un nuevo profesional
1. El administrador accede al sistema.

View File

@@ -1,5 +1,12 @@
# Galerías Fotográficas - Decisiones de Arquitectura
## Relacionado
- [Introducción](introduccion.md)
- [Acta de constitución](acta-constitucion.md)
- [Análisis técnico](analisis-tecnico.md)
- [Requisitos funcionales](requisitos-funcionales.md)
## ¿Por qué Angular en lugar de React?
Como producto final, se pretende vender varias plantillas frontales.

View File

@@ -1,5 +1,12 @@
# Galerías Fotográficas - Documentación API
## Relacionado
- [Introducción](introduccion.md)
- [Acta de constitución](acta-constitucion.md)
- [Decisiones de arquitectura](decisiones-arquitectura.md)
- [Análisis técnico](analisis-tecnico.md)
## Autenticación y autorización
POST `/auth/login` -> Inicia sesión y devuelve un token de autenticación.

51
docs/gitflow.md Normal file
View File

@@ -0,0 +1,51 @@
# Galerias Fotograficas -- Git flow
Para poder aportar al desarrollo de nuevas funcionalidades en las galerías fotográficas, todos los cambios pasan un flujo de tests al hacer push sobre cualqueir rama.
Cuando se hace push sobre una rama, se hará un merge de `dev` automaticamente. Tras este merge, se comprobará que no hayan conflictos.
Justo después, se compilará el back, el front, los tests y los documentos. En caso de que alguno de estos pasos falle, se notificará al desarrollador responsable para que pueda solucionarlo.
Una vez al dia, se realizará una revisión de las ramas en `dev` para generar una rama `staging/{date}` que se publicará con los cambios del día anterior, siempre y cuando hayan conseguido pasar todos los tests.
Para poder aportar sobre nuevas funcionalidades, se deben seguir los siguientes pasos:
1. Crear una nueva rama a partir de `dev` que se llame `feature/[nombre-de-la-funcionalidad]`.
2. Realizar los cambios necesarios en la nueva rama.
3. Hacer push de la rama al repositorio remoto.
4. Crear un Pull Request (PR) para que los cambios sean revisados e integrados en `dev`.
Una vez que el PR sea aprobado, los cambios se fusionarán en `dev`.
Se seguirá el siguiente flujo:
gitGraph
commit
branch develop
checkout develop
commit
commit
checkout develop
branch "feature/one"
checkout develop
commit
checkout "feature/one"
commit
checkout develop
branch "feature/two"
checkout develop
commit
commit
commit
checkout "feature/two"
commit
commit
merge develop
checkout develop
merge "feature/two"
checkout "feature/one"
commit
merge develop
checkout develop
merge "feature/one"
commit
checkout main
merge develop id: "release" tag: "release/{date}"

View File

@@ -1,4 +1,10 @@
# Galerías Fotográficas - Guía de Estilo
# Galerías Fotográficas - Guía de Estilo UI/UX
## Relacionado
- [Introducción](introduccion.md)
- [Acta de constitución](acta-constitucion.md)
- [Requisitos funcionales](requisitos-funcionales.md)
## Materiales

29
docs/index.md Normal file
View File

@@ -0,0 +1,29 @@
# Índice del Proyecto
## Descripción del Proyecto
Este proyecto, **Galerías Fotográficas**, proporciona una plataforma para organizar, visualizar y gestionar colecciones de fotografías. Incluye documentación sobre la finalidad del proyecto, instrucciones detalladas para la instalación y configuración, ejemplos de uso, una sección de preguntas frecuentes y canales de contacto para soporte. El objetivo es facilitar la creación y administración de galerías fotográficas de manera sencilla y eficiente.
## Contenido
- [Acta de constitución](acta-constitucion.md)
- [Análisis técnico](analisis-tecnico.md)
- [Casos de uso](casos-uso.md)
- [Decisiones de arquitectura](decisiones-arquitectura.md)
- [Documentación de la API](documentacion-api.md)
- [Guía de estilo](guia-estilo.md)
- [Introducción](introduccion.md)
- [Manual de usuario](manual-usuario.md)
- [Plan de desarrollo](plan-desarrollo.md)
- [Plan de pruebas](plan-testing.md)
- [Requisitos funcionales](requisitos-funcionales.md)

View File

@@ -2,6 +2,10 @@
---
## Relacionado
- [Acta de constitución](acta-constitucion.md)
## Que problema identificamos
Existen multiples alternativas para la distribución de imágenes digitales, como redes sociales o proveedores de almacenamiento en la nube.

View File

@@ -6,4 +6,11 @@ Guía para clientes
FAQ y resolución de problemas
Videos tutoriales (cuando aplique) -->
Videos tutoriales (cuando aplique) -->
# Galerías Fotográficas - Guía de Usuario
## Relacionado
- [Introducción](introduccion.md)
- [Acta de constitución](acta-constitucion.md)

View File

@@ -1,5 +1,12 @@
# Galerías Fotográficas - Plan de Desarrollo
## Relacionado
- [Introducción](introduccion.md)
- [Acta de constitución](acta-constitucion.md)
- [Análisis técnico](analisis-tecnico.md)
- [Requisitos funcionales](requisitos-funcionales.md)
## Fase 1 Backend: Configuración básica y autenticación
- Configuración del entorno de desarrollo.

View File

@@ -8,4 +8,13 @@ Pruebas E2E: Flujos completos de usuario
Pruebas de rendimiento: Carga de imágenes
Criterios de aceptación -->
Criterios de aceptación -->
# Galerías Fotográficas - Plan de Pruebas
## Relacionado
- [Introducción](introduccion.md)
- [Acta de constitución](acta-constitucion.md)
- [Análisis técnico](analisis-tecnico.md)
- [Requisitos funcionales](requisitos-funcionales.md)

View File

@@ -2,6 +2,13 @@
---
## Relacionado
- [Introducción](introduccion.md)
- [Acta de constitución](acta-constitucion.md)
- [Manual de usuario](manual-usuario.md)
- [Casos de uso](casos-uso.md)
## Gestión de usuarios (4 tipos: anónimo, cliente, profesional, administrador)
Existirán 4 tipos de usuarios:

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

14
mkdocs.yml Normal file
View File

@@ -0,0 +1,14 @@
site_name: Galerías Fotográficas
site_description: Documentación del proyecto de Galerías Fotográficas
nav:
- Requisitos Funcionales: requisitos-funcionales.md
- Análisis Técnico: analisis-tecnico.md
- Guía de Estilo: guia-estilo-uiux.md
- Hoja de ruta: plan-desarrollo.md
theme:
name: mkdocs
color_mode: auto
user_color_mode_toggle: true
locale: es