waffensachkunde

Waffensachkunde – Lernsoftware für die Sachkundeprüfung nach § 7 WaffG. Barrierefrei, offline, EUPL-1.2.

/ app src shared kontakt.ts

4,2 KB Rohdatei
app/src/shared/kontakt.ts — 85 Zeilen
1 /**
2 * Rückmeldeweg und Betreiberangaben.
3 *
4 * ## Warum das kein Beiwerk ist
5 *
6 * Prüfschritt 9.2.2 des Barrierefreiheits-Prüfplans verlangt einen
7 * Rückmeldekanal, der **vorhanden und bedient** ist: Wer auf eine Barriere
8 * stößt, muss sie melden können und eine Antwort bekommen. Ohne diese Angabe
9 * lassen sich 9.2.2 und 9.2.3 nicht erfüllen, und Bestandteil 5 der Erklärung
10 * zur Barrierefreiheit hätte kein Ziel.
11 *
12 * Deshalb stehen die Angaben hier als Festtext und nicht in einer Datei, die
13 * zur Laufzeit gelesen wird: Ein Rückmeldeweg, der von einem IPC-Kanal oder
14 * einer Datei auf der Platte abhängt, ist genau dann weg, wenn etwas kaputt
15 * ist – also genau dann, wenn man ihn braucht.
16 *
17 * ## Warum der Text auswählbar bleibt
18 *
19 * Es lag der Wunsch vor, die Angaben unkopierbar zu machen. Das ist bewusst
20 * **nicht** umgesetzt, und zwar aus drei Gründen:
21 *
22 * 1. Als Bild verstieße es gegen WCAG 1.4.5 (Bilder eines Textes, Stufe AA) –
23 * gegen genau den Maßstab, den dieses Projekt überall anlegt. Es skalierte
24 * bei 200 % Textgröße nicht mit und wäre im Hochkontrast-Schema unbrauchbar.
25 * 2. Mit `user-select: none` bliebe der Text zwar für Bildschirmleser lesbar,
26 * aber wer eine Feinmotorik-Einschränkung hat und eine lange Adresse nicht
27 * abtippen, sondern kopieren muss, stünde ausgerechnet in dem Block vor
28 * einer Barriere, der Barrieren melden soll.
29 * 3. Der Schutz wäre ohnehin keiner. Der übliche Grund – Adress-Sammler, die
30 * Webseiten abgrasen – trifft eine lokal installierte Desktop-Anwendung
31 * nicht. Wer sie hat, hat die Zeichenkette im Paket; dieselbe Adresse steht
32 * zudem offen in `REUSE.toml` unter `SPDX-PackageSupplier` und in
33 * `app/package.json` an zwei Stellen (`author` und `bugs.email`). (Der
34 * Zusatz „jeder Commit“ stand hier früher zu Unrecht: Die Adresse in der
35 * Git-Historie stammt aus `git config user.email`, also aus einer
36 * Einstellung außerhalb dieses Pakets. Und die Behauptung, `package.json`
37 * führe nur den Namen ohne Adresse, war seit dem Nachtrag von `author`
38 * und `bugs` am 28.08.2026 falsch.)
39 *
40 * ## Warum kein `mailto:`
41 *
42 * Die Anwendung öffnet von sich aus keine Verbindung nach außen – das ist eine
43 * Zusage, die in „Über diese Software“ ausdrücklich steht. Ein `mailto:` würde
44 * das Standardprogramm des Systems starten und diese Zusage brechen. Die
45 * Adresse steht deshalb als auswählbarer Text da.
46 */
47
48 /** Antwortfrist, die zugesagt wird. Muss eingehalten werden – 9.2.2. */
49 export const RUECKMELDEFRIST = 'innerhalb eines Monats';
50
51 /**
52 * Betreiber und Rückmeldeweg.
53 *
54 * Der Kanal ist die E-Mail-Adresse – und nur sie. Das genügt: Prüfschritt
55 * 9.2.3 des Barrierefreiheits-Prüfplans verlangt einen Rückmeldekanal, der
56 * für Menschen mit Behinderungen nutzbar ist, „also mindestens E-Mail oder
57 * ein barrierefreies Formular, nicht ausschließlich Telefon“. E-Mail allein
58 * erfüllt diesen Prüfschritt; eine Telefonnummer allein täte es gerade nicht.
59 *
60 * Telefonnummer und Wohnort standen hier früher als Zugabe des Betreibers.
61 * Sie sind bewusst entfernt und gehören **nicht** zurück: Es sind private
62 * Angaben, sie sind für 9.2.2 und 9.2.3 nicht gefordert, und die Anwendung
63 * wird über den Microsoft Store an unbekannte Empfänger ausgeliefert. Der
64 * Name bleibt – er ist Urheberbenennung (EUPL, `REUSE.toml`, Herausgeber im
65 * Store) und keine private Kontaktangabe.
66 *
67 * `tests/kontakt.test.ts` hält das fest und schlägt fehl, sobald wieder eine
68 * Rufnummer oder eine Anschrift im Quelltext der Anwendung auftaucht.
69 */
70 export const KONTAKT = Object.freeze({
71 name: 'Olaf Willerding',
72 epost: 'Olaf@olaf-willerding.de',
73 frist: RUECKMELDEFRIST,
74 });
75
76 /**
77 * Wofür der Kanal da ist – ausgeschrieben, weil 9.2.2 nicht nur einen Kanal
78 * verlangt, sondern einen erkennbaren Zweck.
79 */
80 export const KONTAKT_ANLIEGEN: readonly string[] = Object.freeze([
81 'Barrieren in der Bedienung melden – etwas ist mit Tastatur, Bildschirmleser oder Vergrößerung nicht erreichbar',
82 'Fehler im Fragenkatalog oder in einer Erklärung melden',
83 'Auskunft zu den Barrierefreiheitsmerkmalen dieser Anwendung verlangen',
84 'Inhalte in einer anderen Form anfordern, wenn diese Anwendung nicht nutzbar ist',
85 ]);