Add solution, project wiring, deployment docs, and scripts
Adds the multi-project solution structure, updates the main project wiring, and includes publish/install scripts plus deployment documentation for backend and client rollout.feature/centralized-offline-canteen
parent
e3effcb416
commit
3bb82ff968
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtopiaCanteen.Shared", "UtopiaCanteen.Shared\UtopiaCanteen.Shared.csproj", "{B1B2C3D4-E5F6-7890-ABCD-EF1234567891}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtopiaCanteen.Backend", "UtopiaCanteen.Backend\UtopiaCanteen.Backend.csproj", "{B1B2C3D4-E5F6-7890-ABCD-EF1234567892}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtopiaCanteen.BackendService", "UtopiaCanteen.BackendService\UtopiaCanteen.BackendService.csproj", "{B1B2C3D4-E5F6-7890-ABCD-EF1234567893}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtopiaCanteen.Client", "UtopiaCanteen.Client\UtopiaCanteen.Client.csproj", "{B1B2C3D4-E5F6-7890-ABCD-EF1234567894}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtopiaCanteenSystem", "UtopiaCanteenSystem.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567891}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567891}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567891}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567891}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567892}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567892}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567892}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567892}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567893}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567893}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567893}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567893}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567894}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567894}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567894}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B1B2C3D4-E5F6-7890-ABCD-EF1234567894}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<EnableDefaultCompileItems>true</EnableDefaultCompileItems>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
|
@ -13,6 +14,13 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="UtopiaCanteen.Shared\**" />
|
||||
<Compile Remove="UtopiaCanteen.Backend\**" />
|
||||
<Compile Remove="UtopiaCanteen.BackendService\**" />
|
||||
<Compile Remove="UtopiaCanteen.Client\**" />
|
||||
<Page Remove="UtopiaCanteen.Client\**" />
|
||||
<ApplicationDefinition Remove="UtopiaCanteen.Client\**" />
|
||||
<ProjectReference Include="UtopiaCanteen.Shared\UtopiaCanteen.Shared.csproj" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.11" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
# Install or reinstall the Utopia Canteen backend as a Windows Service (requires Administrator).
|
||||
param(
|
||||
[string]$InstallPath = "C:\UtopiaCanteenBackend",
|
||||
[string]$ServiceName = "UtopiaCanteenBackend",
|
||||
[string]$DisplayName = "Utopia Canteen Backend",
|
||||
[ValidateSet("Debug", "Release")]
|
||||
[string]$Configuration = "Release",
|
||||
[switch]$SkipPublish,
|
||||
[switch]$AddUrlAcl,
|
||||
[string]$UrlAclUser = "Everyone"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Test-Administrator {
|
||||
$current = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$principal = New-Object Security.Principal.WindowsPrincipal($current)
|
||||
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
}
|
||||
|
||||
if (-not (Test-Administrator)) {
|
||||
Write-Error "Run this script in an elevated PowerShell (Run as administrator)."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$ScriptDir = $PSScriptRoot
|
||||
if (-not $SkipPublish) {
|
||||
& (Join-Path $ScriptDir "publish-backend.ps1") -OutputPath $InstallPath -Configuration $Configuration
|
||||
}
|
||||
|
||||
$ExePath = Join-Path $InstallPath "UtopiaCanteen.BackendService.exe"
|
||||
if (-not (Test-Path $ExePath)) {
|
||||
throw "Executable not found: $ExePath. Run publish-backend.ps1 first."
|
||||
}
|
||||
|
||||
# HttpListener on http://+:5000/ often needs a URL reservation.
|
||||
if ($AddUrlAcl) {
|
||||
Write-Host "Adding URL ACL for http://+:5000/ (user: $UrlAclUser)"
|
||||
netsh http add urlacl url=http://+:5000/ user=$UrlAclUser 2>$null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Warning "urlacl may already exist or failed (exit $LASTEXITCODE). Continue if the service binds OK."
|
||||
}
|
||||
}
|
||||
|
||||
$existing = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
||||
if ($existing) {
|
||||
Write-Host "Stopping and removing existing service: $ServiceName"
|
||||
if ($existing.Status -eq "Running") {
|
||||
Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
sc.exe delete $ServiceName | Out-Null
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
$binPath = "`"$ExePath`""
|
||||
Write-Host "Creating service $ServiceName -> $ExePath"
|
||||
sc.exe create $ServiceName binPath= $binPath start= auto DisplayName= $DisplayName
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "sc create failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
sc.exe description $ServiceName "Central canteen API, SQLite, and HRMS/UIND sync for RFID scanners."
|
||||
sc.exe failure $ServiceName reset= 86400 actions= restart/60000/restart/60000/restart/60000
|
||||
|
||||
Write-Host "Starting service..."
|
||||
sc.exe start $ServiceName
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Warning "sc start returned $LASTEXITCODE. Check Event Viewer and appsettings.json."
|
||||
} else {
|
||||
Write-Host "Service started. Health check: http://localhost:5000/api/health"
|
||||
}
|
||||
|
||||
Write-Host @"
|
||||
|
||||
Installed:
|
||||
Path: $InstallPath
|
||||
Service: $ServiceName (auto-start)
|
||||
Data: %LocalAppData%\UtopiaCanteenBackend\
|
||||
|
||||
Firewall: allow inbound TCP 5000 on this PC for scanner clients.
|
||||
|
||||
"@
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# Publish UtopiaCanteen.BackendService to a folder (default C:\UtopiaCanteenBackend).
|
||||
param(
|
||||
[string]$OutputPath = "C:\UtopiaCanteenBackend",
|
||||
[ValidateSet("Debug", "Release")]
|
||||
[string]$Configuration = "Release"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Root = Split-Path -Parent $PSScriptRoot
|
||||
$Project = Join-Path $Root "UtopiaCanteen.BackendService\UtopiaCanteen.BackendService.csproj"
|
||||
|
||||
if (-not (Test-Path $Project)) {
|
||||
throw "Project not found: $Project"
|
||||
}
|
||||
|
||||
Write-Host "Publishing backend ($Configuration) -> $OutputPath"
|
||||
dotnet publish $Project -c $Configuration -o $OutputPath --self-contained false
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "dotnet publish failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
$appsettings = Join-Path $OutputPath "appsettings.json"
|
||||
if (Test-Path $appsettings) {
|
||||
Write-Host "Edit connection strings in: $appsettings"
|
||||
}
|
||||
|
||||
Write-Host "Done. Executable: $(Join-Path $OutputPath 'UtopiaCanteen.BackendService.exe')"
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# Publish UtopiaCanteen.Client (WPF scanner) to a folder (default C:\UtopiaCanteenClient).
|
||||
param(
|
||||
[string]$OutputPath = "C:\UtopiaCanteenClient",
|
||||
[ValidateSet("Debug", "Release")]
|
||||
[string]$Configuration = "Release"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Root = Split-Path -Parent $PSScriptRoot
|
||||
$Project = Join-Path $Root "UtopiaCanteen.Client\UtopiaCanteen.Client.csproj"
|
||||
|
||||
if (-not (Test-Path $Project)) {
|
||||
throw "Project not found: $Project"
|
||||
}
|
||||
|
||||
Write-Host "Publishing client ($Configuration) -> $OutputPath"
|
||||
dotnet publish $Project -c $Configuration -o $OutputPath --self-contained false
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "dotnet publish failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
Write-Host @"
|
||||
Done. Run: $(Join-Path $OutputPath 'UtopiaCanteen.Client.exe')
|
||||
|
||||
First run: open Settings and set Backend base URL (e.g. http://192.168.1.10:5000).
|
||||
Config file: %LocalAppData%\UtopiaCanteenClient\appsettings.json
|
||||
"@
|
||||
Loading…
Reference in New Issue