Fix episode highlight save: preserve structured show-notes fields; v2.0.40
Publish Container / docker (push) Successful in 15m47s
Publish Container / docker (push) Successful in 15m47s
sanitizeFeaturedLinks was silently dropping showNotesSummary, showNotesThemes, showNotesScripture, showNotesQuotes, and showNotesResources on every save — only the legacy showNotes string was kept. Added sanitization for all five new fields and updated the keep-filter to include them. Also removed set -e from entrypoint.sh and made seed/merge steps non-fatal so a permissions error on the mounted data volume no longer crash-loops the container. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
c79589b311
commit
600c450eff
3 files changed
+22
-8
No files matched your search
+6
-7
@@ -1,11 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
|
||||||
|
|
||||||
DATA_DIR=${SITEFORGE_DATA_DIR:-/app/data}
|
DATA_DIR=${SITEFORGE_DATA_DIR:-/app/data}
|
||||||
SEED_DIR=/app/data-seed
|
SEED_DIR=/app/data-seed
|
||||||
|
|
||||||
# Ensure the data directory exists (in case the volume was not mounted)
|
# Ensure the data directory exists (in case the volume was not mounted)
|
||||||
mkdir -p "$DATA_DIR"
|
mkdir -p "$DATA_DIR" || true
|
||||||
|
|
||||||
# Seed each default JSON file only when missing.
|
# Seed each default JSON file only when missing.
|
||||||
# This runs on first boot or a fresh volume, but never overwrites existing data.
|
# This runs on first boot or a fresh volume, but never overwrites existing data.
|
||||||
@@ -18,7 +17,7 @@ if [ -d "$SEED_DIR" ]; then
|
|||||||
|
|
||||||
if [ ! -f "$target_file" ]; then
|
if [ ! -f "$target_file" ]; then
|
||||||
echo "[siteforge] No $base_name found. Seeding from image defaults..."
|
echo "[siteforge] No $base_name found. Seeding from image defaults..."
|
||||||
cp "$seed_file" "$target_file"
|
cp "$seed_file" "$target_file" || echo "[siteforge] Warning: could not seed $base_name — check volume permissions on $DATA_DIR"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
@@ -99,8 +98,8 @@ console.log(`[siteforge] Merged seeded platform links into ${targetFile}`)
|
|||||||
NODE
|
NODE
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_seed_platform_links "$DATA_DIR/admin-content.json" "$SEED_DIR/admin-content.json"
|
merge_seed_platform_links "$DATA_DIR/admin-content.json" "$SEED_DIR/admin-content.json" || true
|
||||||
merge_seed_platform_links "$DATA_DIR/admin-content-draft.json" "$SEED_DIR/admin-content-draft.json"
|
merge_seed_platform_links "$DATA_DIR/admin-content-draft.json" "$SEED_DIR/admin-content-draft.json" || true
|
||||||
|
|
||||||
# Backfill missing lesson releasedAt values from seeded defaults on upgrades.
|
# Backfill missing lesson releasedAt values from seeded defaults on upgrades.
|
||||||
# This keeps persistent volumes compatible with release-date access gating.
|
# This keeps persistent volumes compatible with release-date access gating.
|
||||||
@@ -207,8 +206,8 @@ console.log(`[siteforge] Backfilled missing releasedAt values in ${targetFile}`)
|
|||||||
NODE
|
NODE
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_seed_study_release_dates "$DATA_DIR/admin-content.json" "$SEED_DIR/admin-content.json"
|
merge_seed_study_release_dates "$DATA_DIR/admin-content.json" "$SEED_DIR/admin-content.json" || true
|
||||||
merge_seed_study_release_dates "$DATA_DIR/admin-content-draft.json" "$SEED_DIR/admin-content-draft.json"
|
merge_seed_study_release_dates "$DATA_DIR/admin-content-draft.json" "$SEED_DIR/admin-content-draft.json" || true
|
||||||
|
|
||||||
export SITEFORGE_DATA_DIR="$DATA_DIR"
|
export SITEFORGE_DATA_DIR="$DATA_DIR"
|
||||||
exec node server.js
|
exec node server.js
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "siteforge",
|
"name": "siteforge",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2.0.39",
|
"version": "2.0.40",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -134,6 +134,11 @@ export function sanitizeFeaturedLinks(value) {
|
|||||||
.slice(0, 30)
|
.slice(0, 30)
|
||||||
: []
|
: []
|
||||||
|
|
||||||
|
const sanitizeStringArray = (val, limit) =>
|
||||||
|
Array.isArray(val)
|
||||||
|
? val.filter(s => typeof s === 'string').map(s => s.trim()).filter(Boolean).slice(0, limit)
|
||||||
|
: []
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: typeof item.id === 'string' && item.id.trim() ? item.id.trim() : randomUUID(),
|
id: typeof item.id === 'string' && item.id.trim() ? item.id.trim() : randomUUID(),
|
||||||
title: typeof item.title === 'string' ? item.title.trim().slice(0, 140) : '',
|
title: typeof item.title === 'string' ? item.title.trim().slice(0, 140) : '',
|
||||||
@@ -142,6 +147,11 @@ export function sanitizeFeaturedLinks(value) {
|
|||||||
url: sanitizeUrl(item.url),
|
url: sanitizeUrl(item.url),
|
||||||
embedUrl: sanitizeUrl(item.embedUrl),
|
embedUrl: sanitizeUrl(item.embedUrl),
|
||||||
showNotes: typeof item.showNotes === 'string' ? item.showNotes.trim().slice(0, 10000) : '',
|
showNotes: typeof item.showNotes === 'string' ? item.showNotes.trim().slice(0, 10000) : '',
|
||||||
|
showNotesSummary: typeof item.showNotesSummary === 'string' ? item.showNotesSummary.trim().slice(0, 1000) : '',
|
||||||
|
showNotesThemes: sanitizeStringArray(item.showNotesThemes, 20),
|
||||||
|
showNotesScripture: sanitizeStringArray(item.showNotesScripture, 30),
|
||||||
|
showNotesQuotes: sanitizeStringArray(item.showNotesQuotes, 20),
|
||||||
|
showNotesResources: sanitizeStringArray(item.showNotesResources, 30),
|
||||||
discussionQuestions,
|
discussionQuestions,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -152,6 +162,11 @@ export function sanitizeFeaturedLinks(value) {
|
|||||||
item.url ||
|
item.url ||
|
||||||
item.embedUrl ||
|
item.embedUrl ||
|
||||||
item.showNotes ||
|
item.showNotes ||
|
||||||
|
item.showNotesSummary ||
|
||||||
|
item.showNotesThemes.length > 0 ||
|
||||||
|
item.showNotesScripture.length > 0 ||
|
||||||
|
item.showNotesQuotes.length > 0 ||
|
||||||
|
item.showNotesResources.length > 0 ||
|
||||||
item.discussionQuestions.length > 0,
|
item.discussionQuestions.length > 0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user