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
SYED MUSTUFA AHMED NAQVI 2026-05-25 16:30:50 +05:00
parent e3effcb416
commit 3bb82ff968
5 changed files with 190 additions and 0 deletions

43
UtopiaCanteen.sln Normal file
View File

@ -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

View File

@ -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" />

View File

@ -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.
"@

View File

@ -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')"

View File

@ -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
"@