feat(sprint7): Phase 2 — Info Board (Schwarzes Brett)

Backend:
- V13 Flyway migration: info_board_posts, post_attachments, post_read_status tables
- InfoBoardPost entity with category enum (EVENT, RULE, GENERAL, MAINTENANCE)
- PostAttachment entity (table created, upload deferred to later)
- PostReadStatus entity with composite key (post_id, member_id)
- InfoBoardPostRepository with paginated queries + unread count
- InfoBoardService: CRUD, pin/archive, mark-as-read, notification dispatch
- InfoBoardController: admin CRUD + portal read/unread endpoints
- Integration with NotificationService and AuditService

Frontend:
- info-board.ts service with React Query hooks for all endpoints
- Admin Info Board page at /info-board with create dialog, filters, pin/archive/delete
- Navigation: added 'Schwarzes Brett' to admin sidebar
- i18n: added infoBoard.* keys to de.json and en.json
- Fixed pre-existing prettier issues in notification-compose.ts
- Fixed BufferSource type issue in push-subscription.ts
This commit is contained in:
Patrick Plate
2026-06-13 19:41:20 +02:00
parent 706a6e257b
commit 4aa27cd4f9
53 changed files with 2724 additions and 28 deletions
+29
View File
@@ -743,5 +743,34 @@
"s10Title": "§ 10 Schlussbestimmungen",
"s10Content": "Es gilt das Recht der Bundesrepublik Deutschland. Gerichtsstand ist, soweit gesetzlich zulässig, der Sitz des Anbieters. Sollten einzelne Bestimmungen dieser AGB unwirksam sein, bleibt die Wirksamkeit der übrigen Bestimmungen unberührt. Änderungen der AGB werden dem Nutzer rechtzeitig mitgeteilt."
}
},
"infoBoard": {
"title": "Schwarzes Brett",
"description": "Neuigkeiten und Ankündigungen für alle Mitglieder",
"createPost": "Beitrag erstellen",
"postTitle": "Titel",
"postTitlePlaceholder": "Titel des Beitrags...",
"postContent": "Inhalt",
"postContentPlaceholder": "Schreibe deinen Beitrag...",
"category": "Kategorie",
"categories": {
"GENERAL": "Allgemein",
"EVENT": "Veranstaltung",
"RULE": "Regelung",
"MAINTENANCE": "Wartung"
},
"pinPost": "Anheften",
"archive": "Archivieren",
"delete": "Löschen",
"publish": "Veröffentlichen",
"creating": "Wird erstellt...",
"cancel": "Abbrechen",
"allCategories": "Alle Kategorien",
"showArchived": "Archiviert",
"archived": "Archiviert",
"loading": "Beiträge werden geladen...",
"noPosts": "Noch keine Beiträge vorhanden. Erstelle den ersten Beitrag!",
"confirmDelete": "Möchtest du diesen Beitrag wirklich löschen?",
"unreadCount": "{count} ungelesen"
}
}
+29
View File
@@ -688,5 +688,34 @@
"s10Title": "§ 10 Final Provisions",
"s10Content": "The law of the Federal Republic of Germany applies. The place of jurisdiction is, to the extent legally permissible, the registered office of the provider. Should individual provisions of these terms be invalid, the validity of the remaining provisions remains unaffected. Changes to these terms will be communicated to the user in good time."
}
},
"infoBoard": {
"title": "Info Board",
"description": "News and announcements for all members",
"createPost": "Create Post",
"postTitle": "Title",
"postTitlePlaceholder": "Post title...",
"postContent": "Content",
"postContentPlaceholder": "Write your post...",
"category": "Category",
"categories": {
"GENERAL": "General",
"EVENT": "Event",
"RULE": "Rule",
"MAINTENANCE": "Maintenance"
},
"pinPost": "Pin",
"archive": "Archive",
"delete": "Delete",
"publish": "Publish",
"creating": "Creating...",
"cancel": "Cancel",
"allCategories": "All Categories",
"showArchived": "Archived",
"archived": "Archived",
"loading": "Loading posts...",
"noPosts": "No posts yet. Create the first one!",
"confirmDelete": "Are you sure you want to delete this post?",
"unreadCount": "{count} unread"
}
}