create-cmpnnt
Skill zum Erstellen einer neuen Komponente (cmpnnt) — eines Kommandos, einer Prozedur, eines Subbefehls,
einer Yew-Komponente oder einer ganzen Crate — im literarischen org-babel-Stil,
wie in ~/.claude/CLAUDE.md dokumentiert. Als Grundlage dienen die realen Dateien
code/ads-back (crates/api/create-card.org, crates/api/retrve-card.org,
crates/cli/main.org, crates/svc/main.org, die Wurzel-config.org, env.org).
Schritt 0 — Bestimmen der Variante
Ohne explizite Argumente bestimme die Variante aus der Benutzeranfrage; bei Mehrdeutigkeit
stelle eine klärende Frage über AskUserQuestion, statt stillschweigend zu raten:
- A. Prozedur/Kommando in einer bestehenden Crate — der typische Fall (z. B. ein neuer
rocket-Handler incrates/api, eine neue Bibliotheksfunktion incrates/db). Eine neue Org-Datei, keine Änderungen an derconfig.org. - B. Subbefehl eines bestehenden
CLI— eine neue Datei<subbefehl>.org(Mod) + Eintragung in die bestehendemain.orgdieser Crate (mod,Command:Елементи,Варіанти). - C.
Yew-Komponente (ads-front) — Struktur ähnlich wiecrates/app/marker.org: Abschnitt "Eigenschaften" mit den Komponenteneigenschaften,Html-Blöcke. Das gleiche Gerüst (Deklarationen vor Definition, eine Überschrift pro Konzept), andere Blockterminologie. - D. Neue Crate („föderiertes
cargo") — wenn die Komponente logisch in keine vorhandene Crate passt. Dann werden zusätzlich zur Komponente selbst eineconfig.org,env.org,main.orgder neuen Crate und die Registrierung in der Wurzel-config.orgbenötigt (siehe Schritt 4).
Weise Variante D nicht „vorsorglich" zu — nur wenn der Benutzer explizit eine neue Crate verlangt oder wenn keine vorhandene Crate logisch passt (und dies vom Benutzer bestätigt wurde).
Schritt 1 — Sprache der Org-Datei
Die Sprache ist kontextabhängig, nicht fest vorgegeben. Vor dem Erstellen der Datei sieh
dir die Sprache der benachbarten Org-Dateien im Zielverzeichnis an
(code/ads-back/env.org — Englisch, die meisten crates/api/*.org — Ukrainisch):
wenn das Verzeichnis eine klare Mehrheit hat, schreibe in derselben Sprache; wenn es ein
neues Verzeichnis ist oder die Sprache der Nachbarn mehrdeutig, frage den Benutzer mit
einer Frage, statt zu raten.
Schritt 2 — Gemeinsames Gerüst (alle Varianten)
Unabhängig von der Variante hat jede neue Org-Datei mit eigenem :tangle-Ziel:
-
#+title: ...— Name der Komponente (in der Sprache aus Schritt 1). -
Bei Bedarf — ein Absatz mit einem Link zur Spezifikation (
[[https://...][Spezifikation]]), wie increate-card.org. -
Die erste Überschrift (
* Modul/* Datei/* Crate— Name nach dem Vorbild der benachbarten Dateien im selben Verzeichnis, dies ist nicht streng festgelegt) mit einem Skelettblock:#+begin_src rust :noweb yes :mkdirp yes :tangle src/DATEINAME.rs <<Deklarationen>> <<Definitionen>> #+end_src -
Unmittelbar nach dem Skelett — ein Abschnitt
* Ausführer(für Prozedur/Kommando) mit zwei Blöcken::noweb-ref Deklarationen(Imports, einschließlich der TypenRequest/Responseausads_api) und:noweb-ref Definitionen(die Funktionpub fn run(...), deren Rumpf hauptsächlich<<Aktionen>>innerhalb vondb::cnnctn().transaction(...)ist, falls eine Transaktion benötigt wird). -
Jedes folgende logische Detail (Prüfung, Feldabruf, Tabelleneinfügung usw.) — eine separate Überschrift
*/**mit eigenen:noweb-ref Deklarationen(falls neueusebenötigt) und:noweb-ref Aktionen— in dieser Reihenfolge (Deklaration vor Verwendung, wie überall). Sammle nicht die gesamte Logik in einem Block – jeder sinnvolle Schritt sollte seine eigene Überschrift haben, wie increate-card.org(dort 15+ separate Überschriften für eine Prozedur). -
Wenn ein Schritt eine Hilfsfunktion hervorbringt (z. B.
upsert_phoneincreate-card.org) — ein eigener:noweb-ref Definitionenfür die Funktionssignatur, der Rumpf über einen eigenen benanntennoweb-ref(upsert-phone:Aktionen), und Unterüberschriften**/***für jede Aktion darin.
Variante B (CLI-Subbefehl) unterscheidet sich dadurch, dass es keinen neuen
Skelettblock gibt – stattdessen füge in die bestehende main.org drei Noweb-Blöcke ohne
neue Skelettüberschrift ein: :noweb-ref Deklarationen (mod neuer_subbefehl;),
:noweb-sep ",\n" :noweb-ref Command:Елементи (Variante des enum Command mit
Argumentfeldern) und :noweb yes :noweb-sep ",\n" :noweb-ref Варіанти
(Command::Variante { ... } => crate::modul::run(...)) – jeder in einer eigenen
*-Überschrift, benannt nach der Aktion (z. B. * Organisation erstellen), und die
Implementierung selbst in einer separaten neuen Org-Datei des Subbefehls nach dem
gemeinsamen Gerüst (Schritt 2, Variante A).
Variante C (Yew-Komponente) unterscheidet sich durch die Abschnittsnamen: statt
„Ausführer" gibt es den Abschnitt „Eigenschaften" (struct ...Props, eine Eigenschaft =
ein **-Unterabschnitt, :noweb-sep ",\n" :noweb-ref NameProps:Властивості) und den
Abschnitt „Komponente" (#[function_component(...)], Rumpf — <<Name:Status>>,
<<Name:Effekte>>, <<Name:Handler>>, html! { <<Name:Html>> }). Sieh dir
code/ads-front/crates/app/marker.org als lebendiges Beispiel dieser Variante an.
Schritt 3 — Typische main-Funktion (Variante D, zunächst)
Die erste Version der main.org einer neuen Crate sollte so dumm wie möglich sein –
ohne Fehlerbehandlung, ohne Result, ohne async, ohne Logger-/Env-Initialisierung,
sofern kein konkreter Bedarf besteht:
#+title: CRATENAME
* Datei
#+begin_src rust :noweb yes :mkdirp yes :tangle src/main.rs
<<Deklarationen>>
<<Definitionen>>
fn main() {
<<Aktionen>>
}
#+end_src
<<Aktionen>> kann anfangs völlig leer sein (neue Crate tut noch nichts) – das ist ein
normaler erster Schritt; nachfolgende Überschriften füllen es nach und nach, wie in
crates/cli/main.org/crates/svc/main.org. Fehlerbehandlung (Result, ?), async,
Initialisierung von dotenv/env_logger usw. füge in separaten Überschriften später
hinzu, wenn ein konkreter Schritt es tatsächlich erfordert – nicht vorab.
Schritt 4 — Neue Crate: config.org und Registrierung in der föderierten config.org
-
crates/NAME/config.org— Datei der Crate (siehecrates/cli/config.orgals Beispiel):#+title: =Cargo=-Datei * Datei #+begin_src toml :noweb yes :tangle Cargo.toml [package] name = "NAME" version = "0.1.0" edition = "2021" [dependencies] <<Abhängigkeiten>> #+end_srcJede Abhängigkeit — eine separate
* =cratename=-Überschrift mit:noweb-ref Abhängigkeiten(name = { workspace = true }), geordnet nach der Regel ausCLAUDE.md(externe →forge→ Projekt-Crates, sonst alphabetisch). Blöcke* Rust-Version/* Lokale Konfiguration(rust-toolchain.toml/.cargo/config.toml) kopiere aus der benachbartenconfig.orgnur, wenn es in diesem Verzeichnis so üblich ist – füge sie nicht „vorsorglich" hinzu, wenn keine benachbarte Crate dies tut. Wenn du kopierst, wird die Datei zu einem Multi-Target (mehrere verschiedene:tangle), daher wechseln alle Noweb-Blöcke (einschließlichAbhängigkeiten) zu präfixierten Namen (Cargo:Abhängigkeiten,config:Definitionenusw., siehe CLAUDE.md) – wie in der Wurzel-config.orgunten. -
Füge in der WURZEL-
config.org(Workspace) eine neue* =NAME=-Überschrift mit zwei Blöcken ein – nach dem Vorbild der Abschnitte* =db=/* =api=in der Wurzel:#+begin_src toml :noweb-sep ",\n" :noweb-ref Cargo:Crates "crates/NAME" #+end_src #+begin_src toml :noweb-ref Cargo:Abhängigkeiten NAME = { path = "crates/NAME" } #+end_src -
env.org– Wenn die neue Crate keine eigenen Umgebungsvariablen einführt, ändere nichts. Wenn sie welche einführt und es bereits eine gemeinsame Wurzel-env.orgim Projekt gibt, füge dort einen neuen*-Abschnitt mit eigenem:noweb-refhinzu (wie* Datenbankzugriff/* =JWT=-Parameter), anstatt eine separate Datei zu erstellen. Erstelle eine SEPARATEenv.orgfür die neue Crate nur dann, wenn sie eine eigenständige Bereitstellung ist (eigene.env, nicht derselbe Prozess) und es keine gemeinsameenv.orggibt. In jedem Fall kann die ersteenv.orgganz ohne konkrete Variablen bleiben („kann ganz ohne Werte sein, nur die Hauptdatei") – einfach ein Skelett:#+title: =dotenv=-Datei * Konfigurationsdatei #+begin_src conf :noweb yes :tangle .env.example <<Definitionen>> #+end_srcund fülle später konkrete
* =X=-Parameter-Abschnitte, wenn echte Variablen auftauchen.
Schritt 5 — Überprüfung nach jeder Änderung
Nach jeder wesentlichen Bearbeitung einer Org-Quelle:
- Echter
tangleüberemacsclient --eval(schreibe niemals den Inhalt von.rs/.toml/.env.examplevon Hand – siehe die entsprechende globale Regel). cargo check -p CRATE(füge--target wasm32-unknown-unknownfürads-fronthinzu) – null Warnungen und Fehler.- Führe den Skill
org-lintauf der geänderten Datei aus und korrigiere „SICHERE" Funde sofort, „prüfungsbedürftig" – überprüfe. - Für gerade geschriebene/geänderte Prosa –
(font-lock-ensure)+org-fill-paragraphüber denselbenemacsclient, nicht von Hand.
Zeige die Komponente dem Benutzer erst als fertig an, wenn diese vier Punkte für jede neue oder geänderte Org-Datei bestanden sind.