Changelog
Every shipped change, newest first. Sourced from CHANGELOG.md in the repo.
- 2026-06-18
Fix
- ·Preset-Laden überträgt jetzt den Effekt-Typ ans Gerät (#80). Beim Laden einer
.prst-Datei – und beim Speichern in einen Slot – sendete der Editor nur Toggle, Parameter und Author per USB-MIDI, aber nie den Effekt-Typ selbst (SysExsub=0x14). Das Gerät behielt dadurch seinen zuvor geladenen Algorithmus pro Block, sodass Parameter und An/Aus-Zustand auf dem falschen Effekt landeten (die App zeigte z. B. „UK 800", während das Gerät noch „Tweedy" hatte und keine Werte übernahm). Beide Sync-Pfade senden jetzt pro Block in der Reihenfolge Effektwechsel → Parameter → Toggle, mit kurzer Settling-Pause, damit das Gerät den Algorithmus umschalten kann, bevor die Parameter ankommen.
- ·Preset-Laden überträgt jetzt den Effekt-Typ ans Gerät (#80). Beim Laden einer
- 2026-05-19
Security
- ·Admin-Flag wird auf allen öffentlichen Read-Paths enforced. Gallery,
/api/share/[token],/share/[token]/download,/share/[token]/jsonund Sitemap filtern jetzt zusätzlich aufflagged: false. Bis hierher konnte ein admin-geflaggtes Preset weiter ausgeliefert und von Googlebot gecrawlt werden — Moderation entzieht Inhalte jetzt tatsächlich. - ·
fast-xml-builderHIGH-Advisory geschlossen — (GHSA-5wm8-gmm8-39j9, CVSS 6.1) durchnpm update @aws-sdk/client-s3. Erreichte prod via@aws-sdk/xml-builder. - ·Admin-PATCH-User akzeptiert keine Email-Änderung mehr. Bisher konnte ein kompromittierter Admin-Account Victim-Emails überschreiben und sofort einen Password-Reset triggern → Account-Takeover. Email-Änderungen brauchen jetzt einen Out-of-Band-Weg.
- ·Avatar-Upload gehärtet: Magic-Byte-Probe (JPEG/PNG/WebP Signaturen),
limitInputPixels: 25 Mund try/catch umsharp()— eine PNG-Bombe oder umbenannte Binärdatei erzeugt jetzt 400 statt 500 mit CPU-/RAM-Spike. - ·Avatar-Cache
immutableentfernt — (Cache-Control: public, max-age=3600). Eine Admin-User-Löschung wirkt jetzt innerhalb einer Stunde an jedem Cache-Layer.
Fix
- ·Middleware-Auth-Guard erkennt
pt-BR. Die Regex(de|en|es|fr|it|pt)war beim Locale-Add nicht mitgezogen worden, sodass/pt-BR/profile&/pt-BR/adminden Cookie-Presence-Check der Middleware übersprangen. Page-Level-validateSessionhat es abgefangen — kein Datenleck —, aber Defense-in-Depth weg. Regex wird jetzt ausLOCALESgeneriert; Test stellt sicher, dass jeder Eintrag der LOCALES-Tuple gematcht wird. - ·
/api/admin/commentsnutztwithAdminAuth-Wrapper — statt manuellemtry/catch(requireAdmin)— konsistent zu allen anderen/api/admin/*Routen.
- ·Admin-Flag wird auf allen öffentlichen Read-Paths enforced. Gallery,
- 2026-05-19
Features
- ·30 s Audio-Schnipsel pro Preset. Owner können beim Save-to-Gallery oder nachträglich auf
/share/[token]ein MP3- oder M4A/AAC-File (max 30 s, max 2 MB) anhängen. Player erscheint auf der Share-Page (voll), im Homepage-Featured-Block und auf jeder Gallery-Card (Icon). Nur ein Player spielt gleichzeitig — Klick auf einen Card-Play pausiert alle anderen. - ·Admin-Audit für fremdes Audio. Wenn ein Admin Audio eines fremden Presets ersetzt oder löscht, wird die Aktion mit Reason (bei Delete) im AdminAction-Log auditiert.
Storage / Validation
- ·Neuer Garage S3-Bucket
gp200editor-audio. Server prüft Mime + Magic Bytes + Größe (≤ 2 MB) + Dauer (≤ 30.5 s viamusic-metadata) vor jedem S3 PUT.
Schema
- ·Drei neue nullable Felder auf
Preset:audioKey,audioMimeType,audioDurationMs.
- ·30 s Audio-Schnipsel pro Preset. Owner können beim Save-to-Gallery oder nachträglich auf
- 2026-05-19
Features
- ·Brasilianisches Portugiesisch (pt-BR) als 7. Locale. Vorher war
pt.jsonfaktisch brasilianisch übersetzt (Salvar/Senha/usuário/arquivo); der Inhalt wandert nachpt-BR.jsonund steht jetzt brasilianischen Nutzern als eigenes Locale mit 🇧🇷-Flag im Switcher zur Verfügung.pt.jsonwurde mit ~175 gezielten Substitutionen auf echtes europäisches Portugiesisch konvertiert (Guardar/Palavra-passe/utilizador/ficheiro/Iniciar sessão/A guardar/A carregar/Ligar/Registo/Rastreio).
i18n-Polish (Sprach-Review aller 7 Locales)
- ·DE/IT: 4 Admin-Buttons (
Unpublish/Republish/Flag/Unflag) waren noch englisch — jetzt übersetzt. - ·DE:
home.featured.titlehatte den „Featured ·"-Präfix verloren — wieder dran. - ·IT:
home.featured.titlehatte „Top Rated" englisch — jetzt „Più votati". - ·FR: tu/vous-Inkonsistenz behoben — drei FAQ-Antworten + zwei Tooltips + die Verify-Confirm-Seite waren in
vous, während die App sonsttunutzt. E-Mail-Templates bleiben bewusst invous(formaler Kontext). - ·PT-BR: Ein EU-PT-Slip in
gallery.rate.ownPresetTooltipkorrigiert.
Fix
- ·Übersetzungs-Skript-Bug korrigiert. Beim BR→EU-Sweep der
legal.privacyOverviewTextwurde „salvo quando exigido por lei" (im Sinne von „außer wenn") fälschlich zu „guardado quando exigido por lei" umgeschrieben. Zurückgedreht.
- ·Brasilianisches Portugiesisch (pt-BR) als 7. Locale. Vorher war
- 2026-05-19
Security
- ·Comments leak after un-publish — fixed.
GET /api/presets/[id]/commentsnow refuses to return the thread when the preset has been made non-public or flagged. POST top-level + Reply gained the same gate (Reply previously checked neither). Anyone who had the preset id from a previous public link can no longer continue reading a thread the author tried to retract. - ·Featured-Preset Sybil-Dampening verstärkt. Bayes-Konstante
mvon 5 auf 10 — eine einzelne 5★-Bewertung von einem Accomplice-Account scoret jetzt nur noch ~4.09 (statt 4.17) und schiebt sich nicht mehr vor etablierte Presets mit echtem Rating-Verlauf.
Bugfixes
- ·Inline-Rating Optimistic-UI ohne Rollback — bei fehlgeschlagenem POST blieb die UI bei der Phantom-Bewertung. Snapshot+Restore +
errorTooltip-Toast. - ·Comment-Textarea verlor Inhalt bei 429/Auth-Fail —
CommentFormclear jetzt nur bei Success; bei Fehler steht der Text zum Retry da. - ·CommentSection swallowed 401/5xx silently — separate Toasts für Rate-Limit, Session-Expired und generischen Fehler.
- ·Gallery-Rating Page 2+ zeigte falschen Count — bereits-bewertete Presets jenseits der ersten SSR-Page bekamen
existingRating=0, was bei Re-Rating zu Phantom-Counts führte. Session-Lookup zog ans/api/gallery-Endpoint, jede Card trägt jetzt korrekte Rating-Context. - ·AdminCommentsTab hatte keine Pagination-UI — alle Comments jenseits der ersten 50 waren unerreichbar. Load-More-Button + In-Flight-Guard.
UI / i18n
- ·Confirm-Dialog vor User-Soft-Delete. Klick auf „Delete" beim eigenen Kommentar öffnet jetzt einen Bestätigungsdialog (Soft-Delete ist nicht reversibel —
bodywird genullt). Admin-Hard-Delete behält seinen separaten Reason-Dialog. - ·Drei hardcoded englische Strings korrigiert — (
CommentsHeader,Email verification required, Admin-Cancel-Button) — jetzt in allen 6 Locales übersetzt. - ·Toter i18n-Key entfernt — (
comments.adminDeleteReasonLabel— Admin-Tab nutztadmin.comments.hardDeleteReasonLabel).
Schema / Performance
- ·Index
Comment(createdAt DESC)— die Admin-Moderation-Liste sortiert ohnepresetId-Filter; der bisherige Compound-Index half nicht. Cheap forward-looking change. - ·Shared
commentSerializer— Avatar-Mapping (avatarKey → /api/avatar/<key>) lebt jetzt insrc/lib/commentSerializer.ts; PATCH gab bisher den Raw-avatarKeyzurück, alle anderen Routes serialisierten zuavatarUrl. Inkonsistenz behoben.
- ·Comments leak after un-publish — fixed.
- 2026-05-18
Features
- ·Inline-Rating in der Gallery — Bewertungen können direkt auf der Gallery-Liste abgegeben werden. Anonyme Klicks zeigen einen Tooltip mit Login-Link; eigene Presets sind erwartungsgemäß nicht bewertbar.
- ·Kommentare auf Share-Pages — Plaintext-Kommentare mit 1-Level-Threading (Top-Level + Reply), max 1000 Zeichen, URLs werden automatisch verlinkt (
rel=nofollow). Verifizierte User können kommentieren, jederzeit editieren und soft-löschen. Soft-Delete zeigt einen Platzhalter, Replies bleiben sichtbar. - ·Admin-Moderation für Kommentare — Neuer Tab im Admin-Dashboard: Liste der letzten 50 Kommentare. Hard-Delete erfordert einen Grund (5–200 Zeichen) und wird im AdminAction-Log auditiert; kaskadiert auf Replies.
- ·Featured Preset auf der Startseite — Bayes-Average (m=5, C=globaler Durchschnitt) über alle Presets mit Ratings der letzten 30 Tage. Hero-Block mit Signal-Chain-Grafik (Amp/Cab-Realnamen), Sternebewertung, Beschreibung und den 3 neuesten Kommentaren. Fallback auf All-Time-Best wenn das 30-Tage-Fenster leer ist.
- ·FX-Loop SEND/RETURN editor — neuer Insertion-Point-Editor analog zum offiziellen Valeton GP-200 Editor. Pfeile (
↗SEND,↘RETURN) lassen sich per Drag & Drop oder Tastatur (←/→) zwischen den 11 Effekt-Slots (PRE…VOL) verschieben. Bypass-Anzeige wenn SEND === RETURN. ARIA-konform (role="slider", vollständige Screenreader-Labels in allen 6 Sprachen). - ·Live MIDI für FX-Loop — SEND/RETURN-Bewegungen werden bei verbundenem Gerät sofort als SysEx
sub=0x20ans Pedal geschickt. Push-Constraint (SEND ≤ RETURN) feuert bei Bedarf zwei Messages, um beide Pfeile synchron zu halten. - ·
.prstCodec für FX-Loop — SEND/RETURN werden an Bytes0x92/0x93(innerhalb des Routing-Section-Headers) gelesen und geschrieben. Round-Trip-stabil, inkl.rawSource-basierter Presets.
Schema
- ·Neue Tabelle
Comment— mit Self-FK für 1-Level-Threading (parentIdnullable), Soft-Delete-Marker (deletedAt/deletedBy), Cascade-Delete bei Preset/User/Parent-Removal.
Protocol
- ·
sub=0x20Reorder vs. FX-Loop Move differenziert —decoded[14]/[15]halten SEND/RETURN (vorher fälschlich als Konstanten markiert);decoded[27]ist ein Diskriminator:0x08= SEND verschoben,0xBA= RETURN verschoben,0x44= reine Routing-Umordnung. Reverse-engineered aus zwei USB-MIDI-Captures (2026-05-18), byte-für-byte verifiziert.
- 2026-04-11
Features
- ·PRST Library + JSON API — 145 curated Valeton GP-200 presets ingested from guitarpatches.com, each served with real-world amp/cab names (e.g. "Marshall® JCM800", "Fender® '65 Twin Reverb"). New
/api/share/[token]/jsonendpoint serves a round-trip JSON document with signal chain, highlights, and raw preset data. - ·SEO-crawlable signal chain on share pages — every share page now renders the full effect chain as semantic HTML with both Valeton fake names and real-world brand names. Google rich results supported via schema.org/Product markup per preset.
- ·Amp category landing pages — 64 new pages at
/[locale]/amp/[slug](e.g./en/amp/marshall-jcm800,/en/amp/mesa-boogie-dual-rectifier-modern-mode), each listing all presets using that amp. Pre-rendered for both locales. - ·hreflang + canonical + JSON-LD — every share page gets
<link rel="alternate" hreflang>for de/en/x-default,<link rel="canonical">, schema.org/Product JSON-LD with auto-extracted brand, Open Graph + Twitter Card metadata. - ·Dynamic Open Graph images — 1200×630 PNG per share page generated on demand via Next.js 15
ImageResponse, showing preset name + amp + cab real names with Preset Forge branding. - ·Ingest pipeline — new
scripts/ingest-presets.tsCLI with four source adapters: guitarpatches.com (polite 10s crawl delay), GitHub Code Search, Valeton factory folder, and a manual curated-URL list. Automatic validation (TSRP magic + checksum), dedup by source URL + sha256 content hash, auto-generated descriptions + tags. - ·Sitemap coverage — 586 URLs including 128 amp category pages, 450 preset URLs (de/en/json), and 8 static pages. Force-dynamic so newly-ingested presets become indexable without redeploying.
Bugfixes
- ·Decoder NaN handling — real .prst files from guitarpatches.com carry NaN bytes in unused effect params; the decoder now substitutes 0 so validation doesn't drop ~10% of the library.
- ·Factory-size checksum — 1176-byte factory presets no longer trip the out-of-bounds read at offset 0x4C6.
- ·Description generator —
generateDescriptionno longer produces "cabinet cabinet" when the real name already contains the module label. - ·metadataBase — Open Graph image URLs now resolve to
https://preset-forge.com/...instead ofhttp://localhost:3000/....
Local CI
- ·GitHub Actions removed — replaced with
scripts/local-ci.shrunning lint + typecheck + vitest + next build locally. Newnpm run cientry point.
Performance + Security (pre-library)
- ·Paginated
GET /api/presetsand/presetsSSR page (default 100, max 500) — previously unbounded. - ·Capped
sitemap.xmlquery at 10 000 rows withorderBy: updatedAt desc. - ·Memoized
getEffectParamslookup inEffectParams. - ·Middleware regex compilation moved to module scope (single pattern instead of three per request).
- ·
next-intlupgraded to 4.9.1 (GHSA-8f24-v5vv-gm5j open redirect). - ·
DELETE /api/admin/users/[id]refuses to delete admins — forces an auditable PATCH demotion first. - ·Per-IP rate limit on
/api/auth/forgot-passwordalongside the existing per-email limit, closing the account enumeration side-channel.
- ·PRST Library + JSON API — 145 curated Valeton GP-200 presets ingested from guitarpatches.com, each served with real-world amp/cab names (e.g. "Marshall® JCM800", "Fender® '65 Twin Reverb"). New
- 2026-03-24
Features
- ·Live param updates from hardware — When the user turns knobs on the GP-200 (Volume, Gain, Presence, Bass, Middle, Treble), sliders update in real-time in the webapp. New sub=0x10 D→H knob notification parsing with discriminator (bytes[29:37]=all zeros = knob, otherwise = toggle).
- ·AMP Head Panel — New
AmpHeadPanelcomponent showing the AMP block's main knobs (Gain/Presence/Volume + Bass/Middle/Treble) prominently at the top of the editor. Auto-detects AMP model from preset. - ·Collapsible head sections — AMP Head, Preset Info + Patch Settings, and Controller sections can be independently toggled via a button bar at the top of the editor.
- ·Auto-load preset names — After device connect, all 256 preset names load automatically in the background. Previously required opening the slot browser first.
Bugfixes
- ·Correct initial slot detection — State dump decoded[8:10] LE16 contains the active slot. Previously always returned slot 0. Verified via captures 084047 (slot 13/04-B) and 084156 (slot 0/01-A).
- ·Bank switching on device slot change — When device changes to a slot in a different bank, editor now pulls the entire new bank and switches tab. Previously loaded wrong preset into wrong tab.
- ·MIDI operation serialization — Background
loadPresetNamesno longer conflicts withpullPreset/pushPreset. AddedpauseNameLoading()that aborts name loader before any pull/push/write operation. - ·Nibble-encode slot for slots > 127 — SysEx data bytes must be 0-127. Slot 252 (64-A) was sent as raw 0xFC (invalid). Now nibble-encoded at [25:26] in
buildPresetChangeand decoded inonMidiMessage. - ·Status bar shows editor preset name —
currentPresetNamefrom editor takes priority over stale cachedpresetNames. - ·ControllerPanel visible when disconnected — Shows at 50% opacity instead of hidden.
- ·Cache-Control no-store in dev mode — Prevents browser from serving stale JS after code changes.
Protocol
- ·State dump header decoded — decoded[0:10]: constants + active slot at [8:10] LE16. Verified via captures 084047 (slot 13/04-B) and 084156 (slot 0/01-A).
- ·D→H Knob notification (sub=0x10) byte[22]=block, byte[24]=param, [29:37]=zeros discriminator, [37:45]=nibble float32 value. AMP block=3: param 0=Gain, 1=Presence, 2=Volume, 3=Bass, 4=Middle, 5=Treble.
- 2026-03-23
Features
- ·EXP controller assignments — Hardware-verified EXP1/EXP2 parameter selection + min/max via SysEx (sub=0x14 + sub=0x18).
- ·NAM upload analysis — Captured IR upload protocol (sub=0x1C, multi-chunk).
- ·Patch Settings — VOL/PAN/Tempo live editing via sub=0x10.
Protocol
- ·Save-to-Slot sub-slot index — decoded[4] = A(0)/B(1)/C(2)/D(3). Without this, save always wrote to slot A.
- ·Effekt-Change-Response (sub=0x0C) Block index, effect ID decoded from D→H notification.
- ·EXP/Controller Assignment — Navigation (sub=0x18) + Min/Max write (sub=0x14), hardware-verified.