Group FAQs by a topic relation, ordered; drop unused FAQ teaser

This commit is contained in:
tleininger committed 2026-09-29 22:11:30 +02:00
1 parent 28944c155a
commit 2ea8856d65
14 files changed
+328 -128

No files matched your search

+17 -2
View File
@@ -27,11 +27,19 @@ migrate((app) => {
,
events: [{"end":"","location":"Aula","note":"Gäste sind willkommen. Um Anmeldung im Sekretariat wird gebeten.","public":true,"start":"2026-10-08 19:30:00.000Z","title":"Elternbeiratssitzung"},{"end":"2026-10-20 18:30:00.000Z","location":"Klassenräume","note":"Terminvergabe über das Schulportal.","public":true,"start":"2026-10-20 16:00:00.000Z","title":"Elternsprechtag"},{"end":"2026-11-22 13:00:00.000Z","location":"Schulhof","note":"Kuchenspenden willkommen.","public":true,"start":"2026-11-22 09:00:00.000Z","title":"Herbstbasar"},{"end":"2027-01-06 00:00:00.000Z","location":"","note":"","public":true,"start":"2026-12-19 00:00:00.000Z","title":"Weihnachtsferien"},{"end":"","location":"Mensa","note":"Kennenlernen bei Butterbrezeln und Kaffee.","public":true,"start":"2026-09-10 18:00:00.000Z","title":"Willkommensabend der neuen Fünftklässler"}]
,
faqs: [{"answer":"Die Anmeldung läuft über das Bestellsystem der Schule. Die Zugangsdaten erhalten Sie zu Schuljahresbeginn über die Klassenleitung.","public":true,"question":"Wie melde ich mein Kind zum Mittagessen an?","topic":"Mensa und Mittagessen"},{"answer":"Ein Mittagessen kostet aktuell **4,20 €**. Für Familien mit Anspruch auf Leistungen nach dem Bildungs- und Teilhabepaket ist das Essen kostenfrei – sprechen Sie das Sekretariat an.","public":true,"question":"Was kostet ein Mittagessen?","topic":"Mensa und Mittagessen"},{"answer":"Ja, täglich steht mindestens ein vegetarisches Gericht zur Wahl.","public":true,"question":"Gibt es vegetarische Gerichte?","topic":"Mensa und Mittagessen"},{"answer":"Schließfächer werden über einen externen Anbieter gemietet. Das Anmeldeformular liegt bei den [Downloads](/downloads).","public":true,"question":"Wie bekommt mein Kind ein Schließfach?","topic":"Schließfächer"},{"answer":"Die Miete beträgt rund 15 € pro Schuljahr zuzüglich einer Kaution, die bei Rückgabe erstattet wird.","public":true,"question":"Was kostet die Miete?","topic":"Schließfächer"},{"answer":"Wenden Sie sich an den Anbieter; die Kontaktdaten stehen auf dem Mietvertrag. Bei Fragen hilft auch der [Elternbeirat](/contact).","public":true,"question":"Der Schlüssel ist verloren – was nun?","topic":"Schließfächer"},{"answer":"Der Eltern-Euro ist ein **freiwilliger** Beitrag, mit dem kleinere Anschaffungen für die Klassen unkompliziert finanziert werden – etwa Bastelmaterial oder Ausflüge.","public":true,"question":"Was ist der Eltern-Euro?","topic":"Eltern-Euro"},{"answer":"Nein. Der Beitrag ist ausdrücklich freiwillig, und niemand wird bei Nichtzahlung benachteiligt.","public":true,"question":"Ist der Beitrag verpflichtend?","topic":"Eltern-Euro"},{"answer":"Ob Schulfest, Basar oder eine helfende Hand bei Ausflügen – über jede Unterstützung freuen wir uns. Melden Sie sich einfach über die [Kontaktseite](/contact).","public":true,"question":"Wie kann ich mich engagieren?","topic":"Elternarbeit und Mitmachen"},{"answer":"Nein. Viele Aufgaben erledigen Eltern, die einfach mithelfen möchten, ganz ohne Amt.","public":true,"question":"Muss ich in den Elternbeirat gewählt sein, um zu helfen?","topic":"Elternarbeit und Mitmachen"}]
// Topics own the grouping and the order of the FAQ page; a question links to
// its topic below via the "topic" relation, resolved by slug at seed time.
faq_topics: [{"title":"Elternarbeit","slug":"elternarbeit","intro":"","order":1,"public":true},{"title":"Eltern-Euro","slug":"eltern-euro","intro":"","order":2,"public":true},{"title":"Mensa und Mittagessen","slug":"mensa","intro":"","order":3,"public":true},{"title":"Schließfächer","slug":"schliessfach","intro":"","order":4,"public":true}]
,
// "topic" is a slug here, not a relation id: the record loader below resolves it
// to the faq_topics id, since the ids are only known once the topics are saved.
faqs: [{"answer":"Die Anmeldung läuft über das Bestellsystem der Schule. Die Zugangsdaten erhalten Sie zu Schuljahresbeginn über die Klassenleitung.","public":true,"question":"Wie melde ich mein Kind zum Mittagessen an?","topic":"mensa","order":1},{"answer":"Ein Mittagessen kostet aktuell **4,20 €**. Für Familien mit Anspruch auf Leistungen nach dem Bildungs- und Teilhabepaket ist das Essen kostenfrei – sprechen Sie das Sekretariat an.","public":true,"question":"Was kostet ein Mittagessen?","topic":"mensa","order":2},{"answer":"Ja, täglich steht mindestens ein vegetarisches Gericht zur Wahl.","public":true,"question":"Gibt es vegetarische Gerichte?","topic":"mensa","order":3},{"answer":"Schließfächer werden über einen externen Anbieter gemietet. Das Anmeldeformular liegt bei den [Downloads](/downloads).","public":true,"question":"Wie bekommt mein Kind ein Schließfach?","topic":"schliessfach","order":1},{"answer":"Die Miete beträgt rund 15 € pro Schuljahr zuzüglich einer Kaution, die bei Rückgabe erstattet wird.","public":true,"question":"Was kostet die Miete?","topic":"schliessfach","order":2},{"answer":"Wenden Sie sich an den Anbieter; die Kontaktdaten stehen auf dem Mietvertrag. Bei Fragen hilft auch der [Elternbeirat](/contact).","public":true,"question":"Der Schlüssel ist verloren – was nun?","topic":"schliessfach","order":3},{"answer":"Der Eltern-Euro ist ein **freiwilliger** Beitrag, mit dem kleinere Anschaffungen für die Klassen unkompliziert finanziert werden – etwa Bastelmaterial oder Ausflüge.","public":true,"question":"Was ist der Eltern-Euro?","topic":"eltern-euro","order":1},{"answer":"Nein. Der Beitrag ist ausdrücklich freiwillig, und niemand wird bei Nichtzahlung benachteiligt.","public":true,"question":"Ist der Beitrag verpflichtend?","topic":"eltern-euro","order":2},{"answer":"Ob Schulfest, Basar oder eine helfende Hand bei Ausflügen – über jede Unterstützung freuen wir uns. Melden Sie sich einfach über die [Kontaktseite](/contact).","public":true,"question":"Wie kann ich mich engagieren?","topic":"elternarbeit","order":1},{"answer":"Nein. Viele Aufgaben erledigen Eltern, die einfach mithelfen möchten, ganz ohne Amt.","public":true,"question":"Muss ich in den Elternbeirat gewählt sein, um zu helfen?","topic":"elternarbeit","order":2}]
,
}
// Phase 1: schema. Create any collection that is not present yet.
// Phase 1: schema. Create any collection that is not present yet. The schema
// file lists faq_topics before faqs, so the target of the faqs "topic" relation
// exists by the time faqs is created.
for (const name of Object.keys(schema)) {
try {
app.findCollectionByNameOrId(name)
@@ -42,13 +50,20 @@ migrate((app) => {
// Phase 2: records. Fill a collection only while it is still empty, so a
// populated volume (or, should this ever run there, production) is untouched.
// faqs are seeded after faq_topics (object key order), so the slug->id map is
// populated before a faq resolves its "topic" against it.
const faqTopicIdBySlug = {}
for (const [name, rows] of Object.entries(records)) {
if (app.countRecords(name) > 0) continue
const collection = app.findCollectionByNameOrId(name)
for (const data of rows) {
// A faq's "topic" is a topic slug in this seed; swap it for the real id.
if (name === "faqs") data = { ...data, topic: faqTopicIdBySlug[data.topic] }
const record = new Record(collection)
record.load(data)
app.save(record)
// Remember each topic's id so the faqs seeded afterwards can point at it.
if (name === "faq_topics") faqTopicIdBySlug[data.slug] = record.id
}
}
}, (app) => {
+130 -18
View File
@@ -309,7 +309,7 @@
"help": "",
"hidden": false,
"id": "select1203373331",
"maxSelect": 3,
"maxSelect": 2,
"name": "embed",
"presentable": false,
"required": false,
@@ -317,8 +317,7 @@
"type": "select",
"values": [
"posts",
"events",
"faqs"
"events"
]
},
{
@@ -337,6 +336,107 @@
"updated": "2026-09-23 11:25:35.648Z",
"system": false
},
"faq_topics": {
"id": "pbc_529028860",
"listRule": "",
"viewRule": "",
"createRule": null,
"updateRule": null,
"deleteRule": null,
"name": "faq_topics",
"type": "base",
"fields": [
{
"autogeneratePattern": "[a-z0-9]{15}",
"help": "",
"hidden": false,
"id": "text3208210256",
"max": 15,
"min": 15,
"name": "id",
"pattern": "^[a-z0-9]+$",
"presentable": false,
"primaryKey": true,
"required": true,
"system": true,
"type": "text"
},
{
"autogeneratePattern": "",
"help": "",
"hidden": false,
"id": "text724990059",
"max": 0,
"min": 0,
"name": "title",
"pattern": "",
"presentable": false,
"primaryKey": false,
"required": true,
"system": false,
"type": "text"
},
{
"autogeneratePattern": "",
"help": "",
"hidden": false,
"id": "text2560465762",
"max": 0,
"min": 0,
"name": "slug",
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
"presentable": false,
"primaryKey": false,
"required": true,
"system": false,
"type": "text"
},
{
"autogeneratePattern": "",
"help": "",
"hidden": false,
"id": "text436585760",
"max": 0,
"min": 0,
"name": "intro",
"pattern": "",
"presentable": false,
"primaryKey": false,
"required": false,
"system": false,
"type": "text"
},
{
"help": "",
"hidden": false,
"id": "number4113142680",
"max": null,
"min": null,
"name": "order",
"onlyInt": true,
"presentable": false,
"required": false,
"system": false,
"type": "number"
},
{
"help": "",
"hidden": false,
"id": "bool1001664029",
"name": "public",
"presentable": false,
"required": false,
"system": false,
"type": "bool"
}
],
"indexes": [
"CREATE UNIQUE INDEX `idx_faq_topics_slug` ON `faq_topics` (`slug`)"
],
"created": "2026-09-23 11:59:13.899Z",
"updated": "2026-09-23 11:59:13.899Z",
"system": false
},
"faqs": {
"id": "pbc_2923026773",
"listRule": "",
@@ -392,21 +492,6 @@
"system": false,
"type": "text"
},
{
"autogeneratePattern": "",
"help": "",
"hidden": false,
"id": "select2638274075",
"max": 0,
"min": 0,
"name": "topic",
"pattern": "",
"presentable": false,
"primaryKey": false,
"required": true,
"system": false,
"type": "text"
},
{
"help": "",
"hidden": false,
@@ -416,6 +501,33 @@
"required": false,
"system": false,
"type": "bool"
},
{
"cascadeDelete": false,
"collectionId": "pbc_529028860",
"help": "",
"hidden": false,
"id": "relation3340346911",
"maxSelect": 1,
"minSelect": 0,
"name": "topic",
"presentable": false,
"required": false,
"system": false,
"type": "relation"
},
{
"help": "",
"hidden": false,
"id": "number4113142680",
"max": null,
"min": null,
"name": "order",
"onlyInt": true,
"presentable": false,
"required": false,
"system": false,
"type": "number"
}
],
"indexes": [],