Fix poet image placeholder: null RImageId cast threw 500 (#4); run-local waits via HTTP

- GetPoetImageIdByUrl: missing portrait -> Guid.Empty (placeholder) instead of a null cast
- run-local.sh: wait for SQL Server with a query and for API/site via HTTP
  (pipefail+grep -q never matched; API log level hides 'Now listening' outside Development)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Anas Rashid 2026-10-05 01:03:44 +02:00
parent 3df43e4979
commit a5f0f1b74d
2 changed files with 8 additions and 6 deletions

View File

@ -152,7 +152,7 @@ namespace RMuseum.Services.Implementation
if (cat == null) if (cat == null)
return new RServiceResult<Guid>(Guid.Empty); return new RServiceResult<Guid>(Guid.Empty);
var poet = await _context.DivanPoets.Where(p => p.Id == cat.PoetId).AsNoTracking().SingleOrDefaultAsync(); var poet = await _context.DivanPoets.Where(p => p.Id == cat.PoetId).AsNoTracking().SingleOrDefaultAsync();
return new RServiceResult<Guid>((Guid)poet.RImageId); return new RServiceResult<Guid>(poet?.RImageId ?? Guid.Empty); // divan: no portrait -> placeholder (was a null cast -> 500)
} }
/// <summary> /// <summary>

View File

@ -18,12 +18,14 @@ stop() { pkill -f "dotnet RMuseum.dll" || true; pkill -f "dotnet DivanRazor.dll"
if [ "${1:-}" = stop ]; then stop; echo stopped; exit 0; fi if [ "${1:-}" = stop ]; then stop; echo stopped; exit 0; fi
# 1. SQL Server (x86-64 image; runs under Rosetta on Apple Silicon) # 1. SQL Server (x86-64 image; runs under Rosetta on Apple Silicon)
if ! docker ps --format '{{.Names}}' | grep -qx divan-mssql; then if [ -z "$(docker ps -q -f name=^divan-mssql$)" ]; then
docker start divan-mssql 2>/dev/null || docker run -d --name divan-mssql --platform linux/amd64 \ docker start divan-mssql 2>/dev/null || docker run -d --name divan-mssql --platform linux/amd64 \
-e ACCEPT_EULA=Y -e MSSQL_PID=Express -e "MSSQL_SA_PASSWORD=$SA_PASSWORD" -p 1433:1433 \ -e ACCEPT_EULA=Y -e MSSQL_PID=Express -e "MSSQL_SA_PASSWORD=$SA_PASSWORD" -p 1433:1433 \
-v divan-mssql:/var/opt/mssql --restart unless-stopped mcr.microsoft.com/mssql/server:2022-latest -v divan-mssql:/var/opt/mssql --restart unless-stopped mcr.microsoft.com/mssql/server:2022-latest
echo "waiting for SQL Server..."; until docker logs divan-mssql 2>&1 | grep -q "ready for client connections"; do sleep 3; done
fi fi
# wait until SQL Server accepts queries (also covers a container auto-started by Docker/Colima a moment ago)
echo "waiting for SQL Server..."
until docker exec divan-mssql /opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P "$SA_PASSWORD" -Q "SELECT 1" >/dev/null 2>&1; do sleep 3; done
# 2. publish (from RMuseum/: its global.json pins the SDK newer Razor compilers can't build with) # 2. publish (from RMuseum/: its global.json pins the SDK newer Razor compilers can't build with)
stop stop
@ -49,14 +51,14 @@ d['RSecurityBackend']['FirstUserEmail'] = os.environ['RSecurityBackend__FirstUse
json.dump(d, open(f, 'w', encoding='utf-8'), ensure_ascii=False, indent=2) json.dump(d, open(f, 'w', encoding='utf-8'), ensure_ascii=False, indent=2)
PY PY
ASPNETCORE_URLS=http://localhost:5100 nohup dotnet RMuseum.dll > "$RUN/logs/api.log" 2>&1 &) ASPNETCORE_URLS=http://localhost:5100 nohup dotnet RMuseum.dll > "$RUN/logs/api.log" 2>&1 &)
until grep -q "Now listening" "$RUN/logs/api.log" 2>/dev/null; do sleep 2; done # wait for the API (its log level hides "Now listening" outside Development); the first request creates/migrates the database
curl -s -o /dev/null http://localhost:5100/api/divan/poets # first request creates/migrates the database until curl -s -o /dev/null --max-time 300 http://localhost:5100/api/divan/poets; do sleep 2; done
# 4. site # 4. site
(cd "$RUN/site" && APIRoot=http://localhost:5100 GlobalAPIRoot=http://localhost:5100 SiteUrl=http://localhost:5200 \ (cd "$RUN/site" && APIRoot=http://localhost:5100 GlobalAPIRoot=http://localhost:5100 SiteUrl=http://localhost:5200 \
DataProtectionPersistPath=$RUN/keys TrackingScript="" SemanticSearchAPIRoot="" ASPNETCORE_URLS=http://localhost:5200 \ DataProtectionPersistPath=$RUN/keys TrackingScript="" SemanticSearchAPIRoot="" ASPNETCORE_URLS=http://localhost:5200 \
nohup dotnet DivanRazor.dll > "$RUN/logs/site.log" 2>&1 &) nohup dotnet DivanRazor.dll > "$RUN/logs/site.log" 2>&1 &)
until grep -q "Now listening" "$RUN/logs/site.log" 2>/dev/null; do sleep 2; done until curl -s -o /dev/null http://localhost:5200/; do sleep 2; done
# 5. optional data import (background job; ~1 hour for all 11k poems; re-running only adds what's missing) # 5. optional data import (background job; ~1 hour for all 11k poems; re-running only adds what's missing)
if [ "${1:-}" = import ]; then if [ "${1:-}" = import ]; then