diff --git a/assistant_app/knowledge/arbeitsweise.md b/assistant_app/knowledge/arbeitsweise.md new file mode 100644 index 0000000..ecbc9b6 --- /dev/null +++ b/assistant_app/knowledge/arbeitsweise.md @@ -0,0 +1,94 @@ +--- +titel: Arbeitsweise +quelle: Arbeitsweise +--- + +## Wie Benjamin eine neue Aufgabe angeht + +Benjamin zerlegt Aufgaben, bevor er anfängt. Zuerst sammelt er, welche großen +Aufgaben es überhaupt gibt. Diese zerlegt er in Teilaufgaben, und diese +wiederum, bis einzelne To-dos übrig bleiben, die klein genug sind, dass eine +Person sie abschließen kann. + +Das Verfahren stammt aus der Teamarbeit an Join und hat sich für ihn auch +allein bewährt. Der Nutzen liegt weniger in der Liste als in dem, was beim +Zerlegen auffällt: Eine Aufgabe, die sich nicht sauber zerlegen lässt, ist +meistens noch nicht verstanden. + +Beim Umsetzen gilt dieselbe Reihenfolge wie beim Zerlegen — erst verstehen, +dann Lösungswege erarbeiten, dann sauber umsetzen. Der mittlere Schritt ist ihm +wichtig, weil die erste Lösung, die einem einfällt, selten die beste ist. + +## Wie Benjamin im Team arbeitet + +An Join hat Benjamin in einem Team aus vier Personen gearbeitet, koordiniert +über Trello. Aufgaben wurden gemeinsam zerlegt, dann hat sich jeder eines der +entstandenen To-dos genommen und es abgearbeitet. + +Der Sinn dahinter ist, dass niemand dem anderen in die Quere kommt: keine +doppelte Arbeit, keine Blockaden, und der Stand ist für alle jederzeit sichtbar. + +Benjamins Erfahrung aus dem Projekt ist deutlich: Die Koordination war +schwieriger als der Code. Das ist keine Klage, sondern eine Einschätzung, die +jeder teilt, der einmal zu viert an einer Anwendung gearbeitet hat. Die +technischen Probleme lassen sich nachlesen, die organisatorischen nicht. + +## Was Benjamin an Code wichtig ist + +Qualität geht vor Schnelligkeit. Lieber ein paar Minuten länger für eine +saubere Lösung als ein verfrühtes "ist fertig", das später jemand +auseinandernehmen muss. + +Bei Fehlern sucht Benjamin die Ursache, statt das Symptom zu überdecken. Ein +Fehler, der nur kaschiert wurde, kommt an anderer Stelle wieder, dann aber ohne +erkennbaren Zusammenhang. + +Wichtig sind ihm außerdem Lesbarkeit, Performance und die Bedienbarkeit für den +Anwender. Code kommentiert er sparsam: Was der Code tut, soll er selbst zeigen. +Kommentare hebt er sich für Entscheidungen auf, die man nicht ansieht — etwa +warum ein unsichtbares Formularfeld außerhalb des Sichtbereichs positioniert ist +statt mit display:none, weil manche automatisierten Absender ausgeblendete +Felder erkennen. + +## Wie Benjamin mit Git arbeitet + +Benjamin arbeitet nicht direkt auf dem Hauptzweig. Jede Änderung entsteht in +einem eigenen Feature-Branch und kommt über einen Pull Request in den +Hauptzweig — auch dann, wenn er allein am Projekt arbeitet und den Pull Request +selbst zusammenführt. Seine Commit-Nachrichten folgen den Conventional Commits +und sind auf Englisch. + +Diese Arbeitsweise hat er sich bewusst angewöhnt, und zwar seit er mit CI/CD +arbeitet. Vorher hat er direkt auf dem Hauptzweig gearbeitet. + +Zwei Gründe nennt er dafür. Der erste ist Übung: Er arbeitet meistens allein, +ist aber der Meinung, dass er das können muss — im Team führt an diesem Ablauf +nichts vorbei, und ihn erst dann zu lernen, wenn andere davon abhängen, ist der +schlechtere Zeitpunkt. + +Der zweite ist Schutz vor eigenen Fehlern. In seinen Projekten laufen bei jedem +Pull Request die vollständigen Prüfungen durch: Codeformatierung, statische +Analyse, Tests, Build. Ausgerollt wird aber nur, was im Hauptzweig landet. Ein +direkter Push auf den Hauptzweig würde also ungeprüft live gehen. Der Umweg +über den Pull Request sorgt dafür, dass zwischen "geschrieben" und +"ausgeliefert" immer eine automatische Kontrolle liegt. + +## Welche Projekte nach Vorgabe entstanden sind und welche frei + +Diese Einordnung nimmt Benjamin von sich aus vor, weil sie für die Bewertung +seiner Projekte wichtig ist. + +Bei den Projekten aus der Developer Akademie — Join, El Pollo Loco, Pokédex, +Coderr, Videoflix — waren Stack und Technologien vorgegeben. Die Aufgabe bestand +nicht darin, die Werkzeuge auszuwählen, sondern damit ein funktionierendes und +sauber gebautes Ergebnis zu liefern. + +Cardelia ist die Ausnahme: Es entsteht ohne Vorgaben und außerhalb der Akademie. +Stack, Architektur und Zuschnitt hat Benjamin dort selbst entschieden und +verantwortet sie entsprechend auch selbst. + +Dass ein Stack vorgegeben war, heißt dabei nicht, dass er nichts dazu sagen +kann. Bei Videoflix kann er begründen, warum dort RQ und nicht Celery passt und +warum die Tokens in HttpOnly-Cookies liegen und nicht im LocalStorage — bei +Cardelia hat er beides andersherum entschieden, weil das Projekt anders +zugeschnitten ist. diff --git a/assistant_app/knowledge/in-arbeit.md b/assistant_app/knowledge/in-arbeit.md new file mode 100644 index 0000000..b498d65 --- /dev/null +++ b/assistant_app/knowledge/in-arbeit.md @@ -0,0 +1,76 @@ +--- +titel: Woran Benjamin gerade arbeitet +quelle: Aktuelle Arbeit +--- + +## Videoflix, eine Streaming-Plattform mit Hintergrundverarbeitung + +Videoflix ist eine Videoplattform, an der Benjamin aktuell arbeitet. Das +Backend steht, das eigene Frontend ist noch im Aufbau, und öffentlich +erreichbar ist das Projekt bisher nicht. + +Technisch ist es sein anspruchsvollstes Backend. Nach dem Hochladen eines +Videos läuft die Konvertierung mit FFmpeg zu HLS in drei Auflösungen, 480p, +720p und 1080p, dazu wird ein Vorschaubild herausgeschnitten. Das passiert +nicht während der Anfrage, sondern als Hintergrundjob — ein Video zu +konvertieren dauert Minuten, und solange darf niemand vor einer wartenden Seite +sitzen. + +Die Jobs laufen über zwei Warteschlangen mit unterschiedlicher Priorität: eine +schnelle für E-Mails wie Kontoaktivierung und Passwort-Zurücksetzen, eine +langsame für die Videokonvertierung. Der Grund ist einfach: Eine +Aktivierungsmail, die hinter einer halbstündigen Videokonvertierung in der +Schlange steht, kommt zu spät. Abgearbeitet wird von zwei Arbeitsprozessen in +eigenen Docker-Containern, mit Redis als Unterbau. + +## Warum Videoflix RQ verwendet und nicht Celery + +Benjamin hat in seinen Projekten beide Werkzeuge eingesetzt: Celery bei +Cardelia, RQ bei Videoflix. Die Entscheidung fiel jeweils nach Projektgröße. + +Für Videoflix reicht eine einfache Warteschlange auf Redis-Basis. Celery +entfaltet seine Stärken erst mit einem zusätzlichen Vermittler wie RabbitMQ, +und damit auch dessen Betriebsaufwand. RQ ist leichtgewichtiger, schneller +aufgesetzt und bringt über django-rq eine Oberfläche mit, auf der sich Jobs, +Fehler und vollständige Fehlerausgaben ansehen lassen. + +Bei zwei Warteschlangen und im Kern einem einzigen Job-Typ war das der +passendere Zuschnitt. Die Frage ist für Benjamin nicht, welches Werkzeug +mächtiger ist, sondern welches zur Größe der Aufgabe passt. + +## Warum Videoflix JWT verwendet und nicht Token-Authentifizierung + +Videoflix nutzt Simple-JWT mit Access- und Refresh-Token, beide als +HttpOnly-Cookies statt im LocalStorage abgelegt. + +Der Unterschied ist sicherheitsrelevant: Ein Token im LocalStorage ist für +JavaScript lesbar. Gelingt irgendwo auf der Seite eine Cross-Site-Scripting- +Lücke, ist der Token mit abgeräumt. Ein HttpOnly-Cookie kommt gar nicht erst in +JavaScript-Reichweite. Nebenbei muss das Frontend den Token dann auch nicht +selbst verwalten. + +Dazu kommt die Ablaufsteuerung: Der Access-Token gilt 30 Minuten, der +Refresh-Token 7 Tage, und der Access-Token lässt sich über einen eigenen +Endpunkt sauber erneuern. Die klassische Token-Authentifizierung des Django +REST Frameworks, wie Benjamin sie bei Coderr verwendet, kennt beides nicht: Der +Token ist dort unbefristet gültig und hat keine eingebaute Erneuerung. + +## Der Assistent auf dieser Seite + +Das zweite laufende Vorhaben ist der Assistent, mit dem gerade gesprochen wird. +Er beantwortet Fragen zu Benjamin und seinen Projekten aus einer gepflegten +Wissensbasis, statt sich Antworten auszudenken. Das Verfahren dahinter heißt +Retrieval-Augmented Generation: Zu jeder Frage werden zuerst die passenden +Abschnitte aus der Wissensbasis gesucht, und nur diese Abschnitte bekommt das +Sprachmodell als Grundlage. + +Findet die Suche nichts Passendes, sagt der Assistent das — und das +Sprachmodell wird dann gar nicht erst gefragt. + +Davor sitzt zusätzlich ein Filter, der Versuche erkennt, den Assistenten aus +seiner Rolle zu holen oder ihm fremde Anweisungen unterzuschieben. Solche +Anfragen werden abgewiesen, bevor sie Rechenzeit kosten. + +Benjamin hat den Assistenten gebaut, weil er RAG nicht nur in der Theorie +verstehen wollte, sondern an einem System, das öffentlich läuft und auf das +echte Besucher losgelassen werden. diff --git a/assistant_app/knowledge/infrastruktur.md b/assistant_app/knowledge/infrastruktur.md new file mode 100644 index 0000000..49a8499 --- /dev/null +++ b/assistant_app/knowledge/infrastruktur.md @@ -0,0 +1,80 @@ +--- +titel: Server und Betrieb +quelle: Infrastruktur +--- + +## Benjamin betreibt seine Projekte auf einem eigenen Server + +Benjamins Projekte laufen nicht bei einem Hosting-Baukasten, sondern auf einem +eigenen virtuellen Server unter Ubuntu, den er selbst aufgesetzt hat und selbst +administriert. Das schließt alles ein, was dazugehört: Betriebssystem +einrichten, Dienste installieren und absichern, Zertifikate ausstellen, Updates +einspielen, Fehler im laufenden Betrieb finden. + +Das ist der Unterschied zwischen "ich habe eine Anwendung geschrieben" und "ich +betreibe eine Anwendung". Auf demselben Server laufen mehrere seiner Projekte +nebeneinander, jedes unter einer eigenen Adresse. + +## Wie die Anwendungen ausgeliefert werden + +Vor den Anwendungen steht Nginx als Reverse Proxy. Er nimmt alle Anfragen +entgegen, liefert statische Dateien direkt aus und reicht alles andere an die +Anwendung dahinter weiter. Die Django-Anwendung selbst läuft unter Gunicorn mit +mehreren Arbeitsprozessen, angebunden über einen lokalen Socket statt über +einen offenen Port. + +Die Verschlüsselung läuft über Zertifikate von Let's Encrypt, die sich +automatisch erneuern. HSTS ist aktiv, der Zugriff erfolgt ausschließlich über +HTTPS. + +Als Datenbank kommt PostgreSQL zum Einsatz, erreichbar nur vom Server selbst +und nicht aus dem Netz. + +## Absicherung des Servers + +Die Firewall lässt nur die Ports offen, die tatsächlich gebraucht werden. Ein +Dienst zur Erkennung wiederholter Fehlanmeldungen sperrt auffällige Adressen +automatisch. Zugangsdaten und Schlüssel liegen in einer Konfigurationsdatei mit +eng gesetzten Dateirechten und stehen nicht im Quellcode. + +Öffentliche Formulare sind zusätzlich abgesichert: Eine Begrenzung der Anfragen +pro Absender verhindert massenhaftes Absenden, und ein für Menschen unsichtbares +Feld erkennt automatisierte Einsendungen. + +## Datensicherung + +Die Datenbank wird jede Nacht automatisch gesichert, zusätzlich vor jedem +Ausrollen einer neuen Version. Die Sicherungen werden über einen festen +Zeitraum aufbewahrt und ältere automatisch gelöscht. + +Benjamin prüft die Sicherungen auch auf Wiederherstellbarkeit. Eine Sicherung, +die noch nie zurückgespielt wurde, ist keine Sicherung, sondern eine Annahme. + +## Wie neue Versionen live gehen + +Das Ausrollen passiert nicht von Hand, sondern über eine Pipeline in GitHub +Actions. Bei jeder Änderung laufen zuerst die Prüfungen: Codeformatierung, +statische Analyse, automatische Tests, ein vollständiger Build. Erst wenn alles +davon durchläuft und die Änderung im Hauptzweig landet, wird ausgerollt. + +Ein Pull Request durchläuft dieselben Prüfungen, rollt aber nie aus. Dadurch ist +der Moment, in dem etwas live geht, eine bewusste Entscheidung und kein +Nebeneffekt. + +Nach dem Ausrollen prüft die Pipeline selbst, ob die Seite erreichbar ist und +ob die ausgelieferten Dateien den richtigen Inhaltstyp haben. Ein fehlerhaftes +Ausrollen fällt dadurch sofort auf, statt unbemerkt zu bleiben. + +## Was Benjamin dabei gelernt hat + +Die Fehler, die im Betrieb auftreten, sind andere als die beim Entwickeln. Ein +Beispiel: Nach dem Hochladen von Dateien kamen Unterordner mit zu engen Rechten +auf dem Server an. Der Webserver durfte sie nicht betreten und lieferte +daraufhin für Bilder und Sprachdateien die Startseite aus — mit dem Statuscode +200 und ohne jede Fehlermeldung. Die Seite sah funktionierend aus und war es +nicht. + +Aus solchen Fällen hat er sich angewöhnt, nach jedem Ausrollen nicht nur zu +schauen, ob eine Seite lädt, sondern zu prüfen, ob auch das Richtige +ausgeliefert wird. Genau diese Prüfung läuft heute automatisch in der Pipeline +mit. diff --git a/assistant_app/knowledge/projekt-cardelia.md b/assistant_app/knowledge/projekt-cardelia.md new file mode 100644 index 0000000..e0480f7 --- /dev/null +++ b/assistant_app/knowledge/projekt-cardelia.md @@ -0,0 +1,67 @@ +--- +titel: Cardelia +quelle: Projekt Cardelia +--- + +## Was Cardelia ist + +Cardelia ist ein Kartenkatalog mit Sammlungsverwaltung für Pokémon-Karten. Der +Bestand umfasst rund 77.000 Karten in vier Sprachen, dazu Preise aus mehreren +Quellen. Die Anwendung läuft, ist aber noch nicht öffentlich zugänglich. + +Cardelia ist Benjamins ambitioniertestes Projekt und das einzige, das er ohne +Vorgaben und außerhalb der Developer Akademie baut. Stack, Architektur und +Umfang hat er vollständig selbst entschieden. + +Unter benjaminblarr.de/cardelia ist die Laufzeit-Architektur als Schaubild +einsehbar: welche Bestandteile es gibt, woher die Daten kommen und wohin sie +gehen. + +## Die Architektur von Cardelia + +Cardelia trennt zwei Ebenen, die oft verwechselt werden. + +**Django ist das Backend.** Dort liegen die Domänenlogik, die API und die +Hintergrundjobs — also alles, was Cardelia inhaltlich ausmacht. + +**Supabase ist Infrastruktur, kein Backend.** Es liefert PostgreSQL, +Authentifizierung und Objektspeicher als gemanagten Dienst. Diese Bestandteile +müsste Benjamin sonst selbst betreiben. + +Die beiden konkurrieren also nicht miteinander, sondern liegen auf +verschiedenen Ebenen. Das ist eine Unterscheidung, die Benjamin ausdrücklich +macht: Wer Supabase als Backend bezeichnet, meint meistens den Fall, in dem es +gar kein eigenes Backend gibt und die Oberfläche direkt auf die Datenbank +zugreift. Bei Cardelia ist das nicht so. + +Für die Hintergrundverarbeitung kommen Celery mit einem Worker und Celery Beat +als Zeitplaner zum Einsatz, mit Redis als Vermittler. Zusätzlich läuft eine +tägliche Sicherung. + +## Woher die Daten in Cardelia kommen + +Cardelia zieht seine Daten aus acht externen Quellen: TCGdex, Cardmarket, +PokeTrace, CardTrader, Limitless, PokeWallet, pokemontcg.io und tcggo. + +Einmal täglich läuft ein Lauf, der die Preise aktualisiert und prüft, ob neue +Kartensets erschienen sind. Dieser Lauf ist der Kern des Systems: Ein Katalog +mit 77.000 Karten in vier Sprachen ist keine Datenmenge, die man von Hand +pflegt, und Preise, die eine Woche alt sind, sind für eine Sammlungsverwaltung +wertlos. + +Mehrere Quellen für dasselbe bedeuten dabei nicht mehr Sicherheit, sondern mehr +Arbeit: Die Quellen widersprechen sich, benennen Dinge unterschiedlich und +fallen unterschiedlich oft aus. + +## Warum Cardelia als Projekt zählt + +Bei den Ausbildungsprojekten war der Stack vorgegeben. Cardelia ist die +Ausnahme: Hier hat Benjamin selbst entschieden, was er einsetzt und wie er es +zuschneidet — und muss diese Entscheidungen entsprechend auch selbst +verantworten. + +Es ist außerdem das Projekt, das am längsten läuft und dadurch Fragen aufwirft, +die in einem abgeschlossenen Übungsprojekt nie auftauchen: Was passiert, wenn +eine Datenquelle ihr Format ändert? Wie merkt man überhaupt, dass ein +nächtlicher Lauf nur halb durchgelaufen ist? Was tut man mit Daten, die +widersprüchlich sind? diff --git a/assistant_app/knowledge/projekt-coderr.md b/assistant_app/knowledge/projekt-coderr.md new file mode 100644 index 0000000..5acc367 --- /dev/null +++ b/assistant_app/knowledge/projekt-coderr.md @@ -0,0 +1,72 @@ +--- +titel: Coderr +quelle: Projekt Coderr +--- + +## Was Coderr ist + +Coderr ist eine REST-API, die Benjamin mit dem Django REST Framework gebaut +hat. Sie bildet eine Plattform ab, auf der Dienstleistungen angeboten, bestellt +und bewertet werden: Angebote, Bestellungen und Bewertungen, dazu Registrierung +und Anmeldung mit Token-Authentifizierung. + +Das Frontend stammt von der Developer Akademie und war vorgegeben. Benjamins +Arbeit ist das Backend dahinter, das die vorgegebene Schnittstelle exakt +bedienen muss. + +Coderr läuft unter coderr.benjaminblarr.de auf Benjamins eigenem Server, der +Quelltext liegt öffentlich auf GitHub. + +## Wie Coderr aufgebaut ist + +Coderr ist in sechs Django-Apps aufgeteilt, jede mit einem eigenen Bereich für +die Schnittstelle: Serializer, Views, URLs und Berechtigungen liegen getrennt +voneinander. Der Zuschnitt folgt der Fachlichkeit — Anmeldung, Angebote, +Bestellungen, Bewertungen — statt alles in eine große Anwendung zu legen. + +Die API ist über drf-spectacular dokumentiert und lässt sich als Swagger- +Oberfläche aufrufen. + +Die Standardeinstellung für Berechtigungen ist bewusst geschlossen: Jeder +Endpunkt verlangt zunächst eine Anmeldung, und öffentliche Endpunkte müssen das +ausdrücklich erlauben. Der umgekehrte Weg — alles offen, einzelne Endpunkte +abgesichert — verzeiht keinen Fehler, weil ein vergessener Endpunkt dann offen +steht statt zu. + +## Das Kontaktformular des Portfolios läuft über Coderr + +Das Kontaktformular auf benjaminblarr.de schickt seine Nachrichten an dieselbe +Django-Instanz. An diesem kleinen Endpunkt hängen mehrere Entscheidungen, die +Benjamin gern erklärt, weil sie zeigen, woran man bei einem öffentlichen +Formular denken muss. + +Ein für Menschen unsichtbares Feld erkennt automatisierte Einsendungen. Wird es +ausgefüllt, antwortet der Server trotzdem mit einer Erfolgsmeldung und verwirft +die Nachricht still. Eine ehrliche Fehlermeldung würde dem Absender verraten, +dass die Falle erkannt wurde, und ihm beim nächsten Versuch helfen. + +Die Begrenzung der Anfragen pro Absender richtet sich nach der IP-Adresse, die +der Webserver einträgt, und nicht nach der, die der Absender selbst behaupten +kann. Der Unterschied entscheidet darüber, ob die Begrenzung überhaupt wirkt. + +Die Nachricht wird zuerst gespeichert und erst danach als E-Mail verschickt. Ist +der Mailversand gestört, ist die Nachricht trotzdem da. Als Absender steht dabei +Benjamins eigene Adresse, die Adresse des Besuchers steht in der +Antwort-an-Angabe — eine fremde Adresse als Absender zu setzen, lässt Mails in +Spamfiltern hängen. + +## Warum der Zwischenspeicher in der Datenbank liegt + +Eine Besonderheit an Coderr: Der Zwischenspeicher liegt nicht im +Arbeitsspeicher, sondern in der Datenbank. Das ist langsamer und trotzdem die +richtige Wahl. + +Der Grund liegt in der Zählung der Anfragen pro Absender. Die Anwendung läuft +mit mehreren Arbeitsprozessen nebeneinander. Läge der Zähler im Arbeitsspeicher, +hätte jeder Prozess seinen eigenen — bei drei Prozessen dürfte derselbe Absender +das Dreifache des erlaubten Limits verschicken, weil keiner von den anderen +weiß. Erst ein gemeinsamer Speicher macht die Begrenzung zu einer echten +Begrenzung. + +Das ist ein Beispiel für einen Fehler, den man im Betrieb nicht bemerkt: Es +funktioniert scheinbar, es zählt nur falsch. diff --git a/assistant_app/knowledge/projekt-el-pollo-loco.md b/assistant_app/knowledge/projekt-el-pollo-loco.md new file mode 100644 index 0000000..8cb5990 --- /dev/null +++ b/assistant_app/knowledge/projekt-el-pollo-loco.md @@ -0,0 +1,46 @@ +--- +titel: El Pollo Loco +quelle: Projekt El Pollo Loco +--- + +## Was El Pollo Loco ist + +El Pollo Loco ist ein Jump-and-Run-Spiel, das Benjamin in reinem JavaScript +geschrieben hat. Ohne Framework, ohne Spiel-Engine, ohne Build-Schritt. Die +Spielfigur Pepe sammelt Münzen und Flaschen mit Tabasco-Salsa und setzt sie im +Kampf gegen eine Boss-Henne ein. + +Das Spiel ist unter benjaminblarr.de/el-pollo-loco spielbar, der Quelltext liegt +öffentlich auf GitHub. + +## Die Architektur hinter El Pollo Loco + +Interessant an dem Projekt ist weniger das Spiel selbst als der Aufbau +dahinter. Es besteht aus 24 Klassen, von denen 17 eine gemeinsame Basisklasse +erweitern. Alles, was sich bewegt — die Spielfigur, die Gegner, die Flaschen, +die Wolken — erbt von dieser einen Klasse, die weiß, wo sie sich befindet, wie +groß sie ist und wie sie sich zeichnet. + +Darüber läuft eine einzige Schleife, die das Bild viele Male pro Sekunde leert +und alles neu zeichnet. In jedem Durchgang werden Schwerkraft, +Animationszustände und Kollisionsprüfungen angewandt. + +Benjamin nennt das als Beispiel dafür, wie er objektorientiertes Arbeiten +gelernt hat: nicht als Theorie über Vererbung, sondern an einer Stelle, an der +Vererbung tatsächlich Arbeit spart. Eine neue Gegnerart hinzuzufügen heißt in +diesem Aufbau, eine Klasse zu erweitern, statt Zeichen- und Kollisionslogik ein +weiteres Mal zu schreiben. + +Der Boss-Kampf hat eine eigene Zustandsverwaltung mit den Phasen Alarm, +Angriff, Verletzung und Tod. + +## Warum die Geräusche in El Pollo Loco selbst erzeugt sind + +Grafiken und Spielfiguren kamen als Vorlage mit dem Projekt. Der Ton nicht: Die +mitgelieferten Geräusche fand Benjamin schwach. Er hat deshalb mit ElevenLabs +einen eigenen Satz erzeugt und davon nur behalten, was tatsächlich +funktionierte. + +Das ist eine kleine Sache, sagt aber etwas über die Arbeitsweise: Was als +Vorlage kommt, wird nicht automatisch übernommen, wenn es das Ergebnis +verschlechtert. diff --git a/assistant_app/knowledge/projekt-join.md b/assistant_app/knowledge/projekt-join.md new file mode 100644 index 0000000..7071b51 --- /dev/null +++ b/assistant_app/knowledge/projekt-join.md @@ -0,0 +1,53 @@ +--- +titel: Join +quelle: Projekt Join +--- + +## Was Join ist + +Join ist ein Task-Manager nach dem Vorbild eines Kanban-Boards. Aufgaben lassen +sich Nutzern und Kategorien zuordnen und per Drag-and-Drop zwischen den Spalten +verschieben. Gebaut ist es mit Angular und TypeScript, als Datenschicht dient +Supabase. + +Join ist unter benjaminblarr.de/join erreichbar, der Quelltext liegt öffentlich +auf GitHub. + +## Join war Teamarbeit zu viert + +Join hat Benjamin nicht allein gebaut, sondern in einem Team aus vier Personen. +Das ist für die Einordnung des Projekts wichtiger, als es zunächst klingt: Die +schwierigste Aufgabe war nicht der Code, sondern die Koordination. + +Vier Leute, die gleichzeitig an derselben Anwendung arbeiten, kommen sich +zwangsläufig in die Quere, wenn nicht vorher geklärt ist, wer woran sitzt. +Benjamin und sein Team haben das über Trello gelöst und dabei ein Verfahren +angewandt, das er bis heute benutzt: erst sammeln, welche großen Aufgaben es +überhaupt gibt, diese dann in Teilaufgaben zerlegen und diese wiederum, bis am +Ende einzelne To-dos übrig bleiben, die klein genug sind, dass eine Person sie +abschließen kann. Jeder nimmt sich eines und arbeitet es ab. + +Der Effekt: Niemand arbeitet doppelt, niemand blockiert einen anderen, und der +Stand ist für alle jederzeit sichtbar. + +## Die schwierigste technische Stelle in Join + +Technisch war Drag-and-Drop der aufwendigste Teil. Eine Aufgabe von einer Spalte +in die andere zu ziehen sieht für den Anwender nach einer einzigen Bewegung aus. +Dahinter stehen mehrere Dinge gleichzeitig: erkennen, was gerade gezogen wird, +erkennen, wo es fallen gelassen werden soll, die Anzeige währenddessen +nachführen und am Ende den neuen Zustand speichern, ohne dass die Oberfläche +flackert oder eine Aufgabe kurzzeitig an zwei Stellen liegt. + +## Warum bei Join Supabase eingesetzt wurde + +Supabase war bei Join vorgegeben, wie der übrige Stack auch. Join ist ein +Ausbildungsprojekt der Developer Akademie, und die Technologiewahl gehörte zur +Aufgabenstellung. + +Benjamins eigene Einschätzung nach der Arbeit damit: Supabase ist ein sehr gutes +Werkzeug, wenn man kein eigenes Backend bauen will. Man bekommt Datenbank, +Authentifizierung und Ablage als fertigen Dienst und kann sich auf die Anwendung +konzentrieren. Wo es hingegen um eigene Domänenlogik geht, braucht es etwas +anderes — in seinen späteren Projekten übernimmt diese Rolle Django, während +Supabase dort als Infrastruktur darunter liegt. diff --git a/assistant_app/knowledge/projekt-pokedex.md b/assistant_app/knowledge/projekt-pokedex.md new file mode 100644 index 0000000..b2bfde8 --- /dev/null +++ b/assistant_app/knowledge/projekt-pokedex.md @@ -0,0 +1,37 @@ +--- +titel: Pokédex +quelle: Projekt Pokédex +--- + +## Was der Pokédex ist + +Der Pokédex ist ein interaktives Pokémon-Verzeichnis, das Benjamin in reinem +JavaScript gebaut hat. Die Daten kommen live von der PokéAPI. Die Anwendung +zeigt die Pokémon als Kartenraster, eine Suche nach Namen filtert sie, und ein +Klick öffnet eine Detailansicht mit Grundwerten, Fähigkeiten, der +Shiny-Variante und der Entwicklungsreihe. + +Der Pokédex ist unter benjaminblarr.de/pokedex erreichbar. + +## Wo die eigentliche Schwierigkeit im Pokédex lag + +Fast nichts kommt bei diesem Projekt fertig an. Eine einzige Detailansicht wird +aus mehreren Endpunkten zusammengesetzt, die Antworten sind tief verschachtelt, +und die Entwicklungsreihe lässt sich erst über mehrere aufeinander aufbauende +Abrufe auflösen. + +Gleichzeitig müssen Liste, Suche und Detailansicht bedienbar bleiben, während +im Hintergrund noch Anfragen laufen. Der größte Teil der Arbeit steckte genau +darin — nicht in einer einzelnen Funktion, sondern darin, dass sich das Ganze +flüssig anfühlt, obwohl ständig auf Daten gewartet wird. + +Die Pokémon werden nicht alle auf einmal geladen, sondern nachgeladen, wenn sie +gebraucht werden. + +## Was Benjamin am Pokédex gelernt hat + +Der Pokédex ist das Projekt, an dem Benjamin den Umgang mit einer fremden API +gelernt hat, die ihm ihre Struktur vorgibt. Man bekommt die Daten so, wie die +Schnittstelle sie liefert, nicht so, wie man sie in der Oberfläche braucht. Die +Arbeit besteht darin, dazwischen zu übersetzen und dabei die Zahl der Anfragen +im Blick zu behalten. diff --git a/assistant_app/knowledge/ueber-benjamin.md b/assistant_app/knowledge/ueber-benjamin.md new file mode 100644 index 0000000..95bf34e --- /dev/null +++ b/assistant_app/knowledge/ueber-benjamin.md @@ -0,0 +1,54 @@ +--- +titel: Über Benjamin +quelle: Über mich +--- + +## Wer Benjamin Blarr ist und wie er zur Softwareentwicklung kam + +Benjamin Blarr ist Fullstack-Entwickler und Quereinsteiger. Er hat bei der +Developer Akademie ein Jahr in Vollzeit Frontend- und Backend-Entwicklung +gelernt. Heute baut er Webanwendungen von der Oberfläche bis zur API und +betreibt sie auf einem eigenen Server, den er selbst aufgesetzt hat und +administriert. + +Seine Stärke liegt darin, Vorlagen exakt und detailliert umzusetzen. Die +responsiven Layouts seiner Projekte sind dafür das sichtbarste Beispiel: sie +sind nicht ungefähr nachgebaut, sondern bis in die Abstände hinein. + +Dass er von der Oberfläche bis zum Server durchgeht, ist keine Aufzählung von +Schlagworten, sondern nachprüfbar: dieselbe Anwendung, die er in Angular +geschrieben hat, läuft hinter einem Webserver, den er konfiguriert hat, auf +einem System, das er selbst abgesichert hat. + +## Wo Benjamin lebt und wie er arbeiten möchte + +Benjamin lebt in Schöningen in der Region Braunschweig, Wolfsburg und +Magdeburg. Für Remote-Arbeit ist er sehr offen, und Pendeln ist für ihn kein +Problem. Umziehen möchte er im Moment nicht. + +## Wie Benjamin an Probleme herangeht + +Benjamin löst Probleme strukturiert und in dieser Reihenfolge: zuerst das +Problem verstehen, dann Lösungswege erarbeiten, dann sauber umsetzen. Der +mittlere Schritt ist ihm wichtig, weil die erste Lösung, die einem einfällt, +selten die beste ist. + +Wichtig sind ihm Lesbarkeit, Performance und die Bedienbarkeit für den +Anwender. Genauso wichtig ist ihm die Zusammenarbeit im Team: voneinander zu +lernen und gemeinsam besser zu werden. + +Qualität geht bei ihm vor Schnelligkeit. Lieber ein paar Minuten länger für +eine saubere Lösung, als ein verfrühtes "ist fertig", das später jemand +auseinandernehmen muss. Bei Fehlern sucht er die Ursache, statt das Symptom zu +überdecken. + +## Wie Benjamin mit KI arbeitet + +Die Arbeit mit KI macht Benjamin inzwischen am meisten Spaß. Zwei Gründe nennt +er dafür: Er kommt schneller voran, und sie nimmt ihm wiederkehrende Abläufe +ab, die er sonst jeden Tag von Hand machen müsste. + +Dabei hat er eine feste Regel: Was dabei herauskommt, prüft er nach, und er +übernimmt keinen Code, den er nicht versteht. KI ist für ihn ein Werkzeug, das +Arbeit beschleunigt, und keine Instanz, der man das Ergebnis abnimmt, ohne es +gelesen zu haben.