Accessible PDF Reader – Detaillierte Projektübersicht
Zurück zur Case StudyAccessible PDF Reader
Eine Web-App, die PDFs per Frage beantwortet – mit Barrierefreiheit als Fundament.
PDF hochladen, eine Frage zum Dokument stellen, die Antwort bei Bedarf vorlesen lassen. Konzipiert von der schwierigsten Nutzung her gedacht – blinde Screenreader-Nutzer – und durchgehend barrierefrei umgesetzt.
Auf einen Blick
| Rolle | Konzept · Architektur · Frontend · Accessibility |
| Zeitraum | 2025 |
| Kontext | Uni Projekt in einer sechser Gruppe. |
| Methoden | Screenreader-Test (NVDA), End-to-End-Test mit Test-PDF |
| Tools | Python · FastAPI · OpenAI (gpt-4.1-nano) · pypdf · HTML/CSS/JS · Figma · Render · GitHub |
| Ergebnis | Lauffähige, barrierefreie App – deployt, End-to-End getestet, für RAG vorbereitet |
| Links | Live Demo · GitHub · Case Study |
Meine drei wichtigsten Beiträge
- Barrierefreiheit von der blinden Nutzung her gedacht
- Fokus-Führung, Live-Regionen nach Dringlichkeit, bewusst degradiertes Vorlesen
- Eine bewusst entkoppelte Architektur: fünf Module, jede Datei mit einer Aufgabe, plus eine klar definierte Naht für späteres RAG.
- Ein UI-Redesign in zwei Richtungen (Formular vs. Konversation), inklusive dokumentierter Zustände und eines Accessibility-Annotations-Layers.
01 Kontext Definition
Wer nutzt das – und wozu?
Primäre Zielgruppe sind blinde und sehbehinderte Menschen, die ein Dokument nicht durchlesen, sondern gezielt befragen wollen. Die Leitentscheidung: Das Erlebnis entsteht in Semantik, Ansagen und Fokus – nicht in der Optik. Sehende und sehschwache Nutzer werden als zweite Schicht mitbedient.
Im Scope
- Ein Dokument hochladen, befragen, Antwort vorlesen lassen
- Vollständige Tastatur- und Screenreader-Bedienung
Bewusst ausgeschlossen (Prototyp-Scope, keine Versäumnisse)
- Persistenz, Nutzerkonten, Mehrbenutzer-Zustand
- Mehrere Dokumente / gespeicherte Verläufe
- RAG (vorbereitet, aber bewusst noch nicht gebaut)
02 Nutzungskontextanalyse
Nutzergruppe, Persona und Aufgaben
Persona
[Platzhalter: Name, Alter, Rolle] Technik-Niveau: [Platzhalter]
[Platzhalter: Kurzbeschreibung – Situation, Ziel, Frust. Z. B. „nutzt einen Screenreader, will die Kernaussage eines PDFs erfassen, ohne es Seite für Seite durchzuhören.”]
Aufgabenmodell – Hauptaufgabe
| Benutzergruppe | Blinde / sehbehinderte Nutzer |
| Aufgabe | Eine konkrete Frage zu einem PDF beantwortet bekommen |
| Vorbedingung | Ein PDF liegt vor, Screenreader aktiv |
| Teilaufgaben | 1) PDF hochladen 2) Ladebestätigung wahrnehmen 3) Frage stellen 4) Antwort hören 5) bei Bedarf vorlesen lassen / neue Frage |
| Nachbedingung | Nutzer hat eine dokumentbasierte Antwort erhalten |
03 Anforderungsermittlung
Aus dem Nutzungskontext wurden prüfbare Anforderungen abgeleitet – mit Schwerpunkt Barrierefreiheit.
| ID | Anforderung |
|---|---|
| A1 | Jeder Zustandswechsel (geladen, wartet, Antwort, Fehler) muss für Screenreader hörbar angesagt werden. |
| A2 | Trifft die Antwort ein, muss der Fokus dorthin geführt werden. |
| A3 | Fehler müssen bestimmt (assertiv), Statusmeldungen höflich angesagt werden. |
| A4 | Die App muss vollständig per Tastatur bedienbar sein, mit sichtbarem Fokus. |
| A5 | Farbe darf nie alleiniger Bedeutungsträger sein (Symbol + Wort). |
| A6 | Kontraste ≥ 4,5:1; nutzbar bei 200 % Zoom und ab 320 px Breite. |
| A7 | Die KI darf ausschließlich auf Basis des Dokuments antworten und Fehlendes offen benennen. |
| F1 | PDF hochladen (max. 20 MB), Text extrahieren, Frage beantworten. |
04 Informationsarchitektur
Aufgaben und Module statt Screens
Die Anwendung ist bewusst entkoppelt – fünf Module, jede Datei mit genau einer Aufgabe.
| Modul | Aufgabe |
|---|---|
main.py | FastAPI-Routes, HTTP, verbindet die Module |
pdf.py | PDF-Bytes → reiner Text (pypdf) |
context.py | Kontext-Aufbereitung – Naht für späteres RAG |
ai.py | OpenAI gekapselt, vollständige Fehlerbehandlung |
config.py | Einstellungen aus .env, getippt |
Die zentrale Entwurfsentscheidung – die context.py-Naht: Die gesamte App greift nur über context.get_context(frage, pdf_text) auf den Kontext zu. Heute liefert die Funktion den Volltext (bei Bedarf gekürzt). Ein späterer RAG-Umbau (Embeddings + Vektorsuche) berührt nur diese eine Funktion – die Signatur bleibt gleich, der Rest merkt nichts.
Das Dokument wird bewusst nur im Arbeitsspeicher gehalten (ein Dokument, keine Persistenz).
05 Interaktionsdesign
Zwei Richtungen, eine Entscheidung
- Variante A (Formular): drei gestapelte Schritt-Karten (Upload → Frage → Antwort).
- Variante B (Konversation) – gewählt: Dokument-Status oben als fester Kontext, Frage/Antwort als Verlauf, Eingabe unten wie ein Chat. Begründung: passt zum mentalen Modell „ich frage ein Dokument”, erhält eine Antwort-Historie.
Zustands-Fluss
Leer ──Upload──► Geladen ──Frage──► Wartet ──► Antwort
└─────► Fehler ──Erneut──► Wartet
Ändern ──► Bestätigungs-Dialog ──Laden──► Verlauf leeren ──► Geladen
└─Abbrechen/Esc──► zurück
Die nicht-sichtbaren Entscheidungen (Fokus-Führung, Live-Region-Dringlichkeit, Dialog-Fokusfalle) sind in einem eigenen Accessibility-Annotations-Layer dokumentiert.
06 Interface Design
Ruhiges, funktionales Design-System
- Farben: warmer Grundton, dunkelgrüner Akzent (
#1B5E3F), alle Kontraste WCAG-geprüft (≥ 4,5:1, meist ≥ 7:1). Dark Mode designt. - Abstände: 4er-System (4 / 8 / 16 / 24 / 32). Radius: 8 / 12.
- Typografie: Inter (Atkinson Hyperlegible als barrierefreie Alternative geprüft).
- Alle Werte als Design-Tokens angelegt und im Code als CSS Custom Properties gespiegelt – Design-System und Code sprechen dieselbe Sprache.
![[Screenpdf.png]]
07 Frontend
Plain HTML/CSS/JS – bewusst ohne Framework
Der Kern (Barrierefreiheit) lebt in semantischem HTML, ARIA, Live-Regionen und Fokus-Steuerung – kein CSS-Framework liefert davon etwas. Umgesetzt:
- Semantisches HTML, Landmarks, Skip-Link,
<label>an jedem Feld, sichtbare Fokusringe - Live-Regionen: Verlauf höflich (
role="log"), Fehler bestimmt (role="alert"); „Antwort wird erstellt…” hält die KI-Latenz auf, „Senden” ist solange gesperrt - Antwort = Hinspringen: Fokus wandert in die Antwort, keine zusätzliche Live-Ansage
- Vorlesen bewusst degradiert: nur manueller Start, nie Auto-Play (Web Speech API)
- PDF wechseln nur mit Bestätigungsdialog (Fokus-Falle, Esc, Fokus-Rücksprung)
fetchstatt Reload; Touch-Ziele ≥ 44 px; Reflow bis 320 px / 200 % Zoom;prefers-reduced-motion
08 Test & Betrieb
End-to-End mit einer Test-PDF geprüft
| 4/4 | Testfälle bestanden |
| 5 | entkoppelte Module |
| 100 % | Antworten dokumentbasiert |
| 0 | Halluzinationen im Test |
Geprüft wurde auf vier Dinge: korrekte Fakten, korrekte Details, sauberes Abweisen einer Frage ohne Antwort im Dokument, und deutsches Vorlesen per Web Speech API. Zusätzlich ein Screenreader-Durchlauf mit NVDA.
Deployt auf Render (Web Service, uvicorn app.main:app --host 0.0.0.0 --port $PORT, API-Key als Env-Variable). Kostenschutz: OpenAI Auto-Recharge OFF.
09 Dokumentation & Präsentation
- Case Study auf der Portfolio-Seite
- Diese Projektübersicht + README im Repo
- [Platzhalter: Präsentation / weitere Artefakte, falls vorhanden]
Ergebnis & Reflexion
Was entstanden ist
- Eine lauffähige, barrierefreie App – hochladen, befragen, vorlesen
- Sauber entkoppelte Architektur, End-to-End getestet und deployt
- Ein barrierefreies UI-Redesign inkl. dokumentierter Zustände und Annotationen
Was ich gelernt habe
- [Platzhalter: 1–2 ehrliche Erkenntnisse, z. B. „Fokus-Management ist der eigentliche Kern von Screenreader-UX, nicht ARIA-Labels allein.”]
Ausblick
- RAG über die vorbereitete
context.py-Naht – ohne den Rest der App anzufassen - [Platzhalter: weitere Schritte, z. B. mehrere Dokumente / Verläufe]
Anhang
- Live Demo: https://ai-pdf-reader-q2qy.onrender.com
- GitHub: https://github.com/PixelNinja0/ai-pdf-reader
- Case Study: https://liamdahl.com/projekte/ai-pdf-reader/
Diese Seite ist eine verdichtete Übersicht. [Platzhalter: Verweis auf ausführliche Prozessdokumentation, falls vorhanden.]