News: Beiträge – Titel optional, Datumsprüfung, Bildregeln
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
434bab0b7a
commit
d320730251
2 files changed
+40
-6
No files matched your search
@@ -42,7 +42,8 @@ export function visibleUntilFor(duration, from, dateIso, now = from) {
|
||||
case '3m': return addMonths(from, 3)
|
||||
case 'open': return null
|
||||
case 'date': {
|
||||
if (typeof dateIso !== 'string' || !DATE_RE.test(dateIso) || Number.isNaN(Date.parse(dateIso))) {
|
||||
if (typeof dateIso !== 'string' || !DATE_RE.test(dateIso) || Number.isNaN(Date.parse(dateIso))
|
||||
|| new Date(`${dateIso}T00:00:00Z`).toISOString().slice(0, 10) !== dateIso) {
|
||||
throw httpError(400, 'Bitte wähle ein gültiges Datum.', 'date')
|
||||
}
|
||||
const today = berlinDay(now)
|
||||
@@ -69,8 +70,8 @@ export function validatePostInput(input) {
|
||||
const str = (v) => (typeof v === 'string' ? v.trim() : '')
|
||||
const type = src.type
|
||||
if (!TYPES.includes(type)) throw httpError(400, 'Bitte wähle eine Art von Beitrag.', 'type')
|
||||
// Der Titel ist optional (leer gespeichert)
|
||||
const title = str(src.title)
|
||||
if (!title) throw httpError(400, 'Bitte gib einen Titel ein.', 'title')
|
||||
if (title.length > TITLE_MAX) throw httpError(400, `Der Titel darf höchstens ${TITLE_MAX} Zeichen lang sein.`, 'title')
|
||||
const text = str(src.text)
|
||||
if (text.length > TEXT_MAX) throw httpError(400, `Der Text darf höchstens ${TEXT_MAX} Zeichen lang sein.`, 'text')
|
||||
@@ -111,7 +112,10 @@ async function requireImage(projectId, imageId) {
|
||||
export async function createPost({ customerId, projectId, input, now = new Date() }) {
|
||||
const v = validatePostInput(input)
|
||||
const until = visibleUntilFor(v.duration, now, v.date, now)
|
||||
if (v.imageId) await requireImage(projectId, v.imageId)
|
||||
if (v.imageId) {
|
||||
await requireImage(projectId, v.imageId)
|
||||
await claimNewsImage(projectId, v.imageId)
|
||||
}
|
||||
const iso = now.toISOString()
|
||||
const doc = await createDocument(config.collections.newsPosts, {
|
||||
customerId, projectId,
|
||||
@@ -121,7 +125,6 @@ export async function createPost({ customerId, projectId, input, now = new Date(
|
||||
visibleFrom: iso, visibleUntil: until ? until.toISOString() : null,
|
||||
takenDownAt: null, createdAt: iso, updatedAt: iso,
|
||||
})
|
||||
if (v.imageId) await claimNewsImage(projectId, v.imageId)
|
||||
return doc
|
||||
}
|
||||
|
||||
@@ -153,9 +156,16 @@ export async function updatePost({ customerId, projectId, id, input, now = new D
|
||||
const v = validatePostInput(input)
|
||||
// Relative Dauern zaehlen ab dem urspruenglichen Beginn, damit ein Bearbeiten nichts verlaengert
|
||||
const from = new Date(post.visibleFrom)
|
||||
const until = visibleUntilFor(v.duration, from, v.date, now)
|
||||
// Unverändertes Datum bleibt speicherbar, auch wenn es inzwischen unter "morgen" liegt
|
||||
const sameDate = v.duration === 'date' && post.duration === 'date' && DATE_RE.test(v.date || '')
|
||||
&& post.visibleUntil === berlinTime(v.date, 23, 59, 59, 999).toISOString()
|
||||
const until = sameDate ? new Date(post.visibleUntil) : visibleUntilFor(v.duration, from, v.date, now)
|
||||
const imageId = v.imageId || null
|
||||
if (imageId && imageId !== post.imageId) await requireImage(projectId, imageId)
|
||||
if (imageId && imageId !== post.imageId) {
|
||||
await requireImage(projectId, imageId)
|
||||
const used = (await projectPosts(projectId)).some((p) => p.$id !== id && p.imageId === imageId)
|
||||
if (used) throw httpError(400, 'Dieses Foto gehört schon zu einem anderen Beitrag.', 'imageId')
|
||||
}
|
||||
patch = {
|
||||
type: v.type, title: v.title, text: v.text, paper: v.paper, duration: v.duration,
|
||||
visibleUntil: until ? until.toISOString() : null, imageId,
|
||||
|
||||
Reference in new issue
Block a user