Files
soft/backend/src/HealthManager.WebApi/Program.cs
MingNian 435af55c4a Initial commit: HealthManager full-stack health management platform
Backend: .NET 10 + PostgreSQL + EF Core + JWT + SignalR
Frontend patient: React 19 + TypeScript + Vite (mobile H5)
Frontend doctor: React 19 + TypeScript + Vite (desktop web)
2026-05-20 16:18:56 +08:00

102 lines
3.1 KiB
C#

using System.Text;
using HealthManager.Domain.Interfaces;
using HealthManager.Application.Services;
using HealthManager.Infrastructure.Data;
using HealthManager.Infrastructure.Services;
using HealthManager.WebApi.Hubs;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Swashbuckle.AspNetCore.SwaggerGen;
var builder = WebApplication.CreateBuilder(args);
// Database
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("Default")));
// JWT
var jwtSecret = builder.Configuration["Jwt:Secret"]!;
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret)),
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hubs"))
context.Token = accessToken;
return Task.CompletedTask;
}
};
});
builder.Services.AddAuthorization();
// Services
builder.Services.AddSingleton<IJwtProvider, JwtProvider>();
builder.Services.AddScoped<AuthService>();
builder.Services.AddScoped<HealthService>();
builder.Services.AddScoped<MedicationService>();
builder.Services.AddScoped<ConsultationService>();
builder.Services.AddScoped<ReportService>();
builder.Services.AddScoped<FollowUpService>();
builder.Services.AddScoped<PatientService>();
builder.Services.AddScoped<NotificationService>();
// SignalR
builder.Services.AddSignalR();
// Swagger
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("Dev", policy =>
{
policy.WithOrigins("http://localhost:5173", "http://localhost:5174", "http://localhost:5175")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
builder.Services.AddControllers();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseCors("Dev");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapHub<ChatHub>("/hubs/chat");
// Auto-migrate and seed on startup
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
await db.Database.EnsureCreatedAsync();
await DataSeeder.SeedAsync(db);
}
app.Run();