← All selected work← Alle Projekte

04 · Product App · 2026

Author's Companion

Ein plattformübergreifender Schreibbegleiter, der Projektkontext im Gespräch behält.

// in brief// kurz gesagt

Flutter- und Supabase-Rebuild des Schreibbegleiters: plattformübergreifender Workspace, account-bewusster Sync, retrieval-getriebener Kontext, Spracheingabe und eine gemeinsame Produktschale für Desktop, Mobile und Web.

RoleRolle
Product Design + Cross-platform DevProduktdesign + Cross-platform Dev
Built withEntwickelt mit
Flutter · Dart · Supabase
FormatFormat
Product App

// the decisions behind the screen// die entscheidungen hinter dem screen

01

Keep story context in the eyelineStory-Kontext im Blick behalten

The active chapter, conversation, project context, and memory are visible in one working view. That reduces context reconstruction between a question and the next sentence.Aktives Kapitel, Konversation, Projektkontext und Memory sind in einer Arbeitsansicht sichtbar. Das reduziert den Wiederaufbau von Kontext zwischen einer Frage und dem nächsten Satz.

02

Progressive disclosureSchrittweise Offenlegung

Voice, drafting, critique, prompt templates, project notes, and system context are separate modes rather than one overloaded composer. The writer can expand the toolset only when the task calls for it.Voice, Drafting, Critique, Prompt-Templates, Projektnotizen und Systemkontext sind getrennte Modi statt eines überladenen Composers. Der Werkzeugkasten erweitert sich erst, wenn die Aufgabe es verlangt.

// a technical decision// eine technische entscheidung

Context before generation, across every platformKontext vor der Generierung, auf jeder Plattform

Before a response is requested, the companion brings together recent turns, the active chapter, and only the memories relevant to the current writing task.Bevor eine Antwort angefragt wird, führt der Companion die letzten Turns, das aktive Kapitel und nur die für die aktuelle Schreibaufgabe relevanten Memories zusammen.

final priorTurns = await _conversationRepository.fetchRecentTurns(
  projectId: project.id,
  chapterId: chapter?.id,
  limit: 8,
);

final retrievedMemories = await _memoryNotesRepository
    .retrieveRelevantMemories(
  projectId: project.id,
  chapterId: chapter?.id,
  query: retrievalQuery,
  configuration: settings.retrievalConfig,
);

final systemPrompt = ConversationPromptBuilder.systemPrompt(
  project: project,
  chapter: chapter,
  retrievedMemories: retrievedMemories,
  settings: settings,
);

// outcome// ergebnis

Eine funktionierende plattformübergreifende Basis mit Authentifizierung, Workspace-Navigation, Conversation-Orchestrierung, Mobile-Smoke-Tests, Supabase-Migrationen, account-bewusster Ownership und einem klaren Release-Pfad für iOS, Android, Desktop und Web.

// selected screens// ausgewählte ansichten

18 Ansichten
One product, two platform eras: four platforms, one Flutter codebase, a solo rebuild of design, code, and infra.Ein Produkt, zwei Plattform-Ären: vier Plattformen, ein Flutter-Codebase, ein Solo-Rebuild von Design, Code und Infrastruktur.
Turn the product contract of the native prototype into a reliable cross-platform companion — without flattening it into a generic chat app.Den Produktkern des nativen Prototyps in einen zuverlässigen plattformübergreifenden Companion übertragen — ohne ihn zu einem generischen Chat zu glätten.
What this project actually tests: cross-platform architecture judgment, backend migration under real constraints, production hardening discipline, and solo end-to-end execution.Was dieses Projekt wirklich prüft: Cross-Platform-Architekturentscheidungen, Backend-Migration unter echten Constraints, Production-Hardening und Solo-Umsetzung von Anfang bis Ende.
Conversation, with memory — every turn is tagged by mode, so the thread stays legible as the work shifts from idea to sentence to revision.Konversation mit Gedächtnis — jeder Turn ist nach Modus getaggt, damit der Thread lesbar bleibt, während die Arbeit von Idee zu Satz zu Revision wandert.
Voice is a mode, not a mic icon — a dedicated focus surface for talking through a scene, on desktop and mobile alike.Voice ist ein Modus, kein Mikrofon-Icon — eine eigene Fokusfläche, um eine Szene laut durchzugehen, auf Desktop und Mobile gleichermaßen.
A manuscript surface, not a chat log — draft, word count, and project context sit together, separate from the conversation that shaped them.Eine Manuskript-Oberfläche statt eines Chat-Logs — Entwurf, Wortzahl und Projektkontext stehen zusammen, getrennt von der Konversation, die sie geformt hat.
Context lives with the work — chapter outline and revision notes on one side, typed and tagged memory notes on the other.Kontext lebt bei der Arbeit — Kapitel-Outline und Revisionsnotizen auf der einen Seite, typisierte und getaggte Memory-Notizen auf der anderen.
The user picks the model, not us — provider and model are user-chosen, routed through the same gateway whether local or cloud.Der Nutzer wählt das Modell, nicht wir — Provider und Modell sind nutzerwählbar, geroutet über dasselbe Gateway, ob lokal oder Cloud.
Three layers, secrets never touch the client — Flutter clients, an authenticated Supabase Edge API, and an internal inference service routing LLM, TTS, and STT.Drei Schichten, Secrets erreichen nie den Client — Flutter-Clients, eine authentifizierte Supabase-Edge-API und ein interner Inference-Service für LLM-, TTS- und STT-Routing.
One state machine, every surface obeys it — the same request state drives the desktop panel, the voice-focus panel, and the mobile talk-first shell.Eine State-Machine, jede Oberfläche folgt ihr — derselbe Request-Status steuert das Desktop-Panel, das Voice-Fokus-Panel und die mobile Talk-First-Shell.
Eight tools, one gateway — from Flutter and Riverpod down to self-hosted Kokoro for voice and Whisper for transcription.Acht Tools, ein Gateway — von Flutter und Riverpod bis zum selbst gehosteten Kokoro für Voice und Whisper für Transkription.
Context before generation — recent turns, the active chapter, and only the relevant memories are assembled before any reply is requested.Kontext vor der Generierung — letzte Turns, aktives Kapitel und nur relevante Memories werden zusammengeführt, bevor eine Antwort angefragt wird.
The system this replaced — reading the original Swift prototype closely enough to carry its judgment, not just its UI, into the new architecture.Das System, das ersetzt wurde — den ursprünglichen Swift-Prototyp so genau lesen, dass seine Logik, nicht nur seine UI, in die neue Architektur übertragen werden konnte.
Two rules that shaped the shell: keep story context in the eyeline, and let the toolset expand only when the task calls for it.Zwei Regeln, die die Shell geprägt haben: Story-Kontext im Blick behalten, und der Werkzeugkasten erweitert sich erst, wenn die Aufgabe es verlangt.
A working cross-platform shell, not a proof of concept — auth, conversation orchestration, mobile smoke tests, Supabase migrations, and a scripted release path.Eine funktionierende plattformübergreifende Shell, kein Proof of Concept — Auth, Conversation-Orchestrierung, Mobile-Smoke-Tests, Supabase-Migrationen und ein skriptierter Release-Pfad.
Did you know? One script runs static analysis, the full test suite, an edge-function type-check, and four platform builds before anything ships.Schon gewusst? Ein Skript führt statische Analyse, die komplette Testsuite, einen Typ-Check der Edge-Functions und vier Plattform-Builds aus, bevor etwas live geht.
Not a demo, a working system — role, technical range, process, and evidence, laid out for anyone deciding whether to hire.Keine Demo, ein funktionierendes System — Rolle, technischer Umfang, Prozess und Belege, aufbereitet für die Einstellungsentscheidung.
The closing slide of the case-study deck — contact details and a direct line: open to cross-platform / full-stack engineering roles.Die Abschlussfolie des Case-Study-Decks — Kontaktdaten und eine klare Ansage: offen für Cross-Platform-/Full-Stack-Engineering-Rollen.