Mobile Lern- und Übungsapp für Programmiergrundlagen an der DHBW Lörrach.
Code Companion unterstützt Studierende beim selbstgesteuerten Lernen:
- Themenbasiertes Lernen mit Curricula für JavaScript, Python und Java
- KI-gestützte Quiz-Generierung pro Thema oder als Mixed Quiz
- KI-Erklärungen zu Themen als Markdown-Modal
- Fortschritt, Skill-Level und Lernstreaks pro Programmiersprache
- App-Lokalisierung (Deutsch/Englisch) und Theme-Modi (System/Hell/Dunkel)
- Produktfokus ausschließlich auf Android und iOS; keine geplante Webapp
Die App wurde am Studienzentrum IT-Management & Informatik (SZI) der DHBW Lörrach unter Leitung von Prof. Dr. Erik Behrends entwickelt.
- SZI: https://www.dhbw-loerrach.de/szi
- Quellcode: https://github.com/DHBWLoerrach/CodeCompanion
- Feedback: apps@dhbw-loerrach.de
- Es werden keine benutzerbezogenen Daten auf Servern gespeichert.
- Lernfortschritt, Profil und Einstellungen liegen ausschließlich lokal auf dem Gerät (AsyncStorage).
- Expo SDK 55 + React Native 0.83 + React 19.2
- Expo Router 6 (file-based routing)
- React Query
- Expo API Routes (
app/api/*) überweb.output="server"für serverseitige Endpunkte - OpenAI Responses API (Server-seitig in
server/quiz.ts) - AsyncStorage (lokale Persistenz)
app/ Expo Router Routen + API Routes
(tabs)/ Learn, Practice, Progress
api/ quiz + topic explain endpoints
_layout.tsx globale Provider + Stack-Layout
client/
components/ UI-Bausteine
screens/ Screen-Implementierungen
hooks/ Hooks (z. B. useTranslation)
contexts/ Theme/Language/ProgrammingLanguage Contexts
lib/ storage, i18n, topics-Adapter, query-client
constants/ Design-Tokens
server/
quiz.ts Prompting + OpenAI-Integration
topic-prompts.ts Topic-ID -> Prompt-Mapping je Sprache
validation.ts Request-Validierung für API Routes
logging.ts API-Error-Logging
shared/
curriculum/ JSON-Curricula + Loader/Validierung
programming-language.ts unterstützte Programmiersprachen
skill-level.ts Shared Types (Skill/Difficulty)
__tests__/
unit/ Unit Tests
integration/ Integrationstests
e2e/
maestro/ E2E Tests (Maestro)
- Node.js 20+
- npm 10+
- Expo Go App (optional, für schnelles Testen)
npm ciFür das initiale Setup immer npm ci verwenden, nicht npm install.
So werden exakt die Versionen aus package-lock.json installiert und unnötige Lockfile-Änderungen zwischen Betriebssystemen reduziert.
npm ci ist für ein reproduzierbares Setup gedacht.
Wenn Abhängigkeiten geändert werden sollen, erfolgt das bewusst mit npm install oder npm uninstall:
- Hinzufügen:
npm install <paket>(bzw.npm install -D <paket>für Dev-Dependencies) - Aktualisieren:
npm install <paket>@<version>odernpm update <paket> - Entfernen:
npm uninstall <paket>
Dabei werden package.json und package-lock.json aktualisiert.
Beide Dateien müssen gemeinsam committed werden.
OPENAI_API_KEY- API-Key für
POST /v1/responses. - Nur server-seitig verwenden.
- In Produktion aus der EAS-Environment
production.
- API-Key für
OPENAI_MODEL- Modellname, Standard:
gpt-5.4-nano.
- Modellname, Standard:
EXPO_PUBLIC_API_URL- Basis-URL für API-Calls im Client (für Deployments erforderlich).
API_QUOTA_ENABLED- Aktiviert serverseitiges Rate Limiting für
POST /api/quiz/generateundPOST /api/quiz/generate-mixed. - Lokaler Standard:
false.
- Aktiviert serverseitiges Rate Limiting für
SUPABASE_URL- Nur erforderlich, wenn
API_QUOTA_ENABLED=true. - URL der dedizierten Supabase-Instanz für Quota-Daten.
- Nur erforderlich, wenn
SUPABASE_SECRET_KEY- Nur server-seitig verwenden.
- Nur erforderlich, wenn
API_QUOTA_ENABLED=true. - Verwendet den serverseitigen Zugriff auf
public.api_usage.
- Niemals
EXPO_PUBLIC_OPENAI_API_KEYverwenden. - Niemals
EXPO_PUBLIC_SUPABASE_SECRET_KEYoder andere Secrets mitEXPO_PUBLIC_versehen. - OpenAI-Key als
Restrictedanlegen und nurResponses: Writeerlauben. .envund.env*.localsind per.gitignorevom Commit ausgeschlossen.
- Standardmodus:
API_QUOTA_ENABLED=false- Keine lokale Supabase-Abhängigkeit
- Integrationsmodus:
API_QUOTA_ENABLED=trueSUPABASE_URLundSUPABASE_SECRET_KEYmüssen gesetzt sein- Nur gegen eine dedizierte Dev-/Test-Supabase-Instanz testen, nie gegen Produktion
Supabase wird in diesem Projekt aktuell nur für das serverseitige Quota-Feature benötigt.
Für den normalen lokalen Entwicklungsalltag bleibt API_QUOTA_ENABLED=false.
Wichtiger Stand heute:
- Es gibt aktuell kein
supabase/-Verzeichnis mit committed Migrationen. - Das benötigte Schema wird derzeit manuell im Supabase SQL Editor angelegt.
Ein dediziertes Supabase-Projekt für Entwicklung oder Integrationstests anlegen. Nie gegen das Produktionsprojekt entwickeln oder testen.
Im Supabase SQL Editor folgendes ausführen:
create table public.api_usage (
id bigint generated always as identity primary key,
device_id_hash text not null,
endpoint text not null check (endpoint in ('quiz/generate', 'quiz/generate-mixed')),
usage_date date not null default ((now() at time zone 'utc')::date),
created_at timestamptz not null default now()
);
create index idx_api_usage_device_day
on public.api_usage (device_id_hash, usage_date);
create index idx_api_usage_device_day_endpoint
on public.api_usage (device_id_hash, usage_date, endpoint);
create index idx_api_usage_global_day
on public.api_usage (usage_date);
alter table public.api_usage enable row level security;Danach prüfen:
public.api_usageexistiert- RLS ist aktiv
Aus dem Supabase-Projekt werden für dieses Repo benötigt:
SUPABASE_URLSUPABASE_SECRET_KEY
SUPABASE_SECRET_KEY ist rein serverseitig und darf niemals über EXPO_PUBLIC_* exponiert werden.
OPENAI_API_KEY=...
OPENAI_MODEL=gpt-5.4-nano
EXPO_PUBLIC_API_URL=
API_QUOTA_ENABLED=true
SUPABASE_URL=...
SUPABASE_SECRET_KEY=sb_secret_...Wenn Supabase lokal nicht benötigt wird, reicht weiterhin:
OPENAI_API_KEY=...
API_QUOTA_ENABLED=falsenpm run startDie Supabase-Anbindung ist nur relevant für:
POST /api/quiz/generatePOST /api/quiz/generate-mixed
Für Deployments müssen dieselben Variablen zusätzlich in der EAS-Environment gesetzt werden.
Mehr Kontext zur Architektur und zum Rollout steht in docs/specs/rate-limits/rate-limiting-plan-v4.md.
npm run startDanach in Expo:
- iOS Simulator (
i) - Android Emulator (
a)
Hinweis:
web.output="server"wird in diesem Projekt nur genutzt, um Expo API Routes auf EAS Hosting bereitzustellen.- Eine produktive Webapp ist aktuell nicht geplant.
wist daher kein regulärer Produktpfad, höchstens ein lokaler Debug-/Testpfad für API-Route-nahe Entwicklung.
npm run start- Expo Dev Server startennpm run ios- iOS Build startennpm run android- Android Build startennpm run lint- ESLintnpm run lint:fix- ESLint mit Auto-Fixesnpm run check:types- TypeScript Check (tsc --noEmit)npm run check:format- Prettier Checknpm run format- Prettier Writenpm test- Alle Tests ausführennpm run test:unit- Unit Testsnpm run test:integration- Integrationstestsnpm run test:watch- Tests im Watch-Modusnpm run test:coverage- Tests mit Coverage-Reportnpm run test:e2e- E2E Smoke Tests (Maestro)npm run test:e2e:ai- E2E AI-Tests (Maestro)
Erzeugt ein Quiz für ein einzelnes Topic.
Wenn API_QUOTA_ENABLED=true, muss der Client zusätzlich den Header X-Device-Id mit einer persistierten UUID v4 mitsenden.
Request-Body:
topicId(string, required)count(number, optional, 1-20, default 5)language(en|de, optional, defaulten)skillLevel(number, optional, default 1)programmingLanguage(javascript|python|java, optional, defaultjavascript)
Erzeugt ein gemischtes Quiz über mehrere Topics.
Wenn API_QUOTA_ENABLED=true, muss der Client zusätzlich den Header X-Device-Id mit einer persistierten UUID v4 mitsenden.
Request-Body:
count(number, optional, 1-20, default 10)language(en|de, optional, defaulten)skillLevel(number, optional, default 1)programmingLanguage(javascript|python|java, optional, defaultjavascript)topicIds(string[], optional, max 20; wenn leer, zufällige Topics)
- Source of truth für Lerninhalte:
shared/curriculum/<language>.json - Loader/Validierung:
shared/curriculum/index.ts - UI-Adapter:
client/lib/topics.ts - Statische Erklärungen:
shared/explanations/*.json - Prompt-Mapping:
shared/topic-prompts/*.json
Beim Start wird die Konsistenz zwischen Topic-IDs und Prompt-Mapping geprüft.
EAS Hosting wird in diesem Projekt für die serverseitigen Expo API Routes genutzt, nicht für eine eigenständige Webapp.
- Deployments sind ausschließlich über GitHub Actions erlaubt.
- Lokales
eas deployist nicht erlaubt. - Produktion läuft über
.github/workflows/deploy.yml(manueller Triggerworkflow_dispatch).
Voraussetzungen:
- GitHub Secret
EXPO_TOKENist gesetzt. - In EAS-Environment
productionist mindestensOPENAI_API_KEYgesetzt. - Für aktives Quota-Feature zusätzlich
API_QUOTA_ENABLED=true,SUPABASE_URLundSUPABASE_SECRET_KEYsetzen.
Workflow-Schritte (vereinfacht):
npm cieas env:exec production 'npx expo export --platform web --no-ssg' --non-interactiveeas deploy --environment production --prod --non-interactive
- Variablen sind pro Deployment gebunden (immutable Deployments).
- Änderungen an Variablen wirken erst nach neuem Export + Deploy.
- EAS Hosting unterstützt für diese Server-Variablen
plaintextundsensitive, aber keinesecret-Sichtbarkeit.
- Topic in
shared/curriculum/<language>.jsonergänzen. - Prompt in
shared/topic-prompts/<language>.jsonergänzen. - Auf gültige
prerequisitesund eindeutige IDs achten.
- ID in
shared/programming-language.tsergänzen. - Neues Curriculum in
shared/curriculum/anlegen. - Prompt-Mapping in
shared/topic-prompts/ergänzen.
- App-Texte in
client/lib/i18n.tspflegen. - Themen-/Kategorie-Texte bevorzugt im Curriculum (
shared/curriculum/*.json) pflegen.
- Farben/Tokens in
client/constants/theme.ts - Header/Stack-Defaults in
client/hooks/useScreenOptions.ts
- Storage, Settings, Progress in
client/lib/storage.ts
Vor PR/Commit mindestens ausführen:
npm run check:types
npm run lint
npm run check:format
npm testFormatierung automatisch anwenden:
npm run formatMIT, siehe LICENSE.