Compare commits
2
Commits
5f28237ef0
...
3530167cc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3530167cc3 | ||
|
|
8fb5044062 |
No files matched your search
@@ -85,7 +85,7 @@ public record FaqTopic
|
||||
/// <remarks>
|
||||
/// Convenience over <see cref="Expand"/>: questions name their topic, so
|
||||
/// PocketBase returns them under the back-relation key when the query expands it
|
||||
/// (<c>faqs_via_topic</c>). The topic detail page reads them from here. They
|
||||
/// (<c>faqs_via_topic</c>). The FAQ page reads them from here. They
|
||||
/// arrive unsorted, so this orders them by <see cref="Faq.Order"/> for a stable
|
||||
/// render. Drafts are dropped: PocketBase does not apply the topic query's
|
||||
/// <c>public</c> filter to the expanded children, so this keeps
|
||||
|
||||
+2
-2
@@ -28,8 +28,8 @@ architecture. Never global.
|
||||
## AE-2: Content in PocketBase, read per request (revised)
|
||||
|
||||
**Decision:** All visible content lives in **PocketBase** (collections `pages`,
|
||||
`posts`, `events`, `faqs`); the app reads it over the REST API per request via a
|
||||
typed `PocketBaseClient`. Documents remain PDFs under `wwwroot`.
|
||||
`posts`, `events`, `faq_topics`, `faqs`); the app reads it over the REST API per
|
||||
request via a typed `PocketBaseClient`. Documents remain PDFs under `wwwroot`.
|
||||
|
||||
**Original decision (stage 1):** Content as files in the repo — Markdown with YAML
|
||||
frontmatter, events as `Content/events.yml`. The rationale then was: no DB backup,
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ and the dev overlay mounts that folder into PocketBase (`./pb/pb_migrations:/pb_
|
||||
|
||||
| File | Role |
|
||||
|---|---|
|
||||
| `collections_schema.json` | The four content collections (`pages`, `posts`, `events`, `faqs`) as PocketBase exports them. **The single source of truth for the schema** — the test fixture imports this same file. |
|
||||
| `collections_schema.json` | The five content collections (`pages`, `posts`, `events`, `faq_topics`, `faqs`) as PocketBase exports them. **The single source of truth for the schema** — the test fixture imports this same file. |
|
||||
| `<timestamp>_dev_seed.js` | The PocketBase migration. Reads the schema file, creates any missing collection, then inserts the example records. |
|
||||
|
||||
Both steps are **idempotent**: a collection is created only if it is missing, and
|
||||
|
||||
+40
-15
@@ -41,7 +41,8 @@ der passenden Collection (Button *New record*).
|
||||
| `pages` | Feste Seiten (Vorstand, Impressum, Kontakt …) | Slug, z. B. `/board` |
|
||||
| `posts` | Neuigkeiten / Beiträge | `/posts`, neueste zuerst |
|
||||
| `events` | Termine (Kalender) | `/events` und der `.ics`-Feed |
|
||||
| `faqs` | Häufige Fragen | Werden auf der FAQ-Seite gruppiert angezeigt |
|
||||
| `faq_topics` | Themen der häufigen Fragen (z. B. „Mensa und Mittagessen") | Als aufklappbare Gruppen auf `/faqs` |
|
||||
| `faqs` | Häufige Fragen | Auf `/faqs`, in der Gruppe ihres Themas |
|
||||
|
||||
Jede Collection hat als **letztes Feld `public`** (ja/nein). Nur Records mit
|
||||
`public = true` erscheinen auf der Website — so lässt sich ein Entwurf anlegen,
|
||||
@@ -54,8 +55,9 @@ Redaktion arbeitet mit **Daten**, nicht mit Struktur. Konkret:
|
||||
| Was du willst | Geht redaktionell? | Wie |
|
||||
|---|---|---|
|
||||
| Beitrag / Termin / Frage hinzufügen | **Ja** | Neuer Record in `posts` / `events` / `faqs` — erscheint sofort in der jeweiligen Liste |
|
||||
| Neues FAQ-Thema (neue Gruppe auf `/faqs`) | **Ja** | Neuer Record in `faq_topics` (siehe *Häufige Fragen*) |
|
||||
| Neue Textseite | **Ja** | Neuer Record in `pages` (siehe unten) |
|
||||
| Eine Seite mit einer Liste anteasern | **Ja** | Feld `embed` der Seite (`posts`/`events`/`faqs`) |
|
||||
| Eine Seite mit einer Liste anteasern | **Ja** | Feld `embed` der Seite (`posts`/`events`) |
|
||||
| **Neue Art von Liste** (eigene Seite mit eigener Sortierung/Gruppierung und eigener Adresse, z. B. „Protokolle") | **Nein** | Braucht Entwicklung: neue Collection **plus** Code |
|
||||
|
||||
Das heißt: **Bestehende Listen lassen sich beliebig erweitern**, aber eine *neue*
|
||||
@@ -98,9 +100,10 @@ sofort live, ohne Code und ohne Rebuild:
|
||||
`location` (`header` oder `footer`) und `order` (Reihenfolge, ab 1). Die App
|
||||
baut Kopf- und Fußnavigation daraus; nichts wird im Markup angefasst.
|
||||
- **Eingebettete Blöcke:** Das Feld `embed` (Mehrfachauswahl aus
|
||||
`faqs`/`posts`/`events`) hängt unter den Text der Seite dynamische Blöcke. So
|
||||
ist die Startseite (`home`) eine normale Seite mit `embed = [posts, events]`,
|
||||
und `/faqs` eine Seite mit `embed = [faqs]`. Leeres `embed` = reine Textseite.
|
||||
`posts`/`events`) hängt unter den Text der Seite dynamische Blöcke. So ist die
|
||||
Startseite (`home`) eine normale Seite mit `embed = [posts, events]`. Leeres
|
||||
`embed` = reine Textseite. Die FAQ-Liste ist kein `embed`: `/faqs` ist eine
|
||||
feste Ansicht (siehe *Häufige Fragen*).
|
||||
|
||||
> **Impressum und Datenschutz** hängen an ihren Slugs (`imprint`, `privacy`).
|
||||
> Diese Slugs nicht ändern — sonst laufen die rechtlich verlinkten Adressen ins
|
||||
@@ -162,16 +165,38 @@ ihrer Kalender-App abonnieren — der Feed entsteht aus denselben Records.
|
||||
|
||||
---
|
||||
|
||||
## Häufige Fragen (`faqs`)
|
||||
## Häufige Fragen (`faq_topics` und `faqs`)
|
||||
|
||||
Eine Frage hat `question`, `answer` (Markdown), `topic` und `public`. Die App
|
||||
baut die FAQ-Seite generiert: sie gruppiert die Fragen nach `topic` und zeigt den
|
||||
`topic`-Text unverändert als Gruppen-Überschrift. `topic` ist also **keine feste
|
||||
Auswahl**, sondern der Überschriftentext selbst (z. B. `Mensa und Mittagessen`) —
|
||||
eine neue Gruppe entsteht einfach, indem eine Frage einen neuen `topic`-Text
|
||||
bekommt; Fragen mit gleichem `topic` landen in derselben Gruppe. Auf Groß-/
|
||||
Kleinschreibung und Leerzeichen achten, sonst entstehen versehentlich zwei
|
||||
Gruppen. Der Rahmentext oben auf `/faqs` ist eine eigene Seite in `pages`
|
||||
Die FAQ-Seite `/faqs` besteht aus zwei Collections: **Themen** (`faq_topics`) und
|
||||
**Fragen** (`faqs`). Jedes Thema erscheint als aufklappbare Gruppe, darin seine
|
||||
Fragen. Eine Frage gehört zu genau einem Thema, das du aus einer Liste
|
||||
**auswählst** — du tippst es nicht als Text ein.
|
||||
|
||||
### Themen (`faq_topics`)
|
||||
|
||||
Ein Thema hat `title`, `slug`, `intro` (optional), `order` und `public`.
|
||||
|
||||
- `title` ist die Überschrift der Gruppe (z. B. `Mensa und Mittagessen`).
|
||||
- `intro` ist ein kurzer Einleitungstext (Markdown), der beim Aufklappen über den
|
||||
Fragen steht.
|
||||
- `order` legt die Reihenfolge der Gruppen fest (kleinere Zahl zuerst).
|
||||
- `slug` ist englisch, klein, ohne Umlaute (z. B. `lunch`) — dieselbe Regel wie
|
||||
bei Seiten. Er wird derzeit nicht angezeigt, ist aber Pflicht.
|
||||
- **Eine neue Gruppe** = ein neuer Record in `faq_topics`. Danach steht das Thema
|
||||
bei den Fragen zur Auswahl.
|
||||
|
||||
### Fragen (`faqs`)
|
||||
|
||||
Eine Frage hat `question`, `answer` (Markdown), `topic`, `order` und `public`.
|
||||
|
||||
- `topic`: das Thema aus `faq_topics` auswählen.
|
||||
- `order` legt die Reihenfolge innerhalb des Themas fest (kleinere Zahl zuerst).
|
||||
|
||||
> **Stolpersteine.** Eine Frage **ohne** `topic` erscheint nirgends auf der
|
||||
> Website. Ist ein Thema nicht `public`, verschwinden auch alle seine Fragen —
|
||||
> egal, ob diese selbst `public` sind.
|
||||
|
||||
Überschrift und Rahmentext oben auf `/faqs` sind eine eigene Seite in `pages`
|
||||
(Slug `faqs`).
|
||||
|
||||
---
|
||||
@@ -180,7 +205,7 @@ Gruppen. Der Rahmentext oben auf `/faqs` ist eine eigene Seite in `pages`
|
||||
|
||||
- **Nach dem Ändern einer Zugriffsregel** immer den Haupt-*Save* der Collection
|
||||
drücken, sonst greift die Änderung nicht.
|
||||
- Die vier Collections sind öffentlich **lesbar** (List/View offen), aber nur
|
||||
- Die fünf Collections sind öffentlich **lesbar** (List/View offen), aber nur
|
||||
eingeloggt **schreibbar** — ein Schreibversuch ohne Login wird abgewiesen. Das
|
||||
ist Absicht; nicht „vereinfachen".
|
||||
- **Backup:** Der gesamte Inhalt liegt in `pb_data`. Ein Backup dieses
|
||||
|
||||
Reference in new issue
Block a user