create-cmpnnt
Habilidad para crear un nuevo componente (cmpnnt) — comando, procedimiento, subcomando, Yew-componente
o crate completo — en el estilo literario org-babel, documentado en ~/.claude/CLAUDE.md. Se
basa en los archivos reales de code/ads-back (crates/api/create-card.org, crates/api/retrve-card.org,
crates/cli/main.org, crates/svc/main.org, el config.org raíz, env.org).
Paso 0 — determinar la variante
Por defecto (sin argumentos explícitos), determina la variante a partir de la propia solicitud del usuario; si es ambiguo,
pregunta mediante AskUserQuestion, no adivines en silencio:
- A. Procedimiento/comando en crate existente — caso típico (ej. nuevo manejador
rocketencrates/api, nueva función de biblioteca encrates/db). Un nuevo archivo org, sin cambios enconfig.org. - B. Subcomando de
CLIexistente — nuevo archivo<subcomando>.org(mod) + inserción en elmain.orgexistente de ese crate (mod,Command:Elementos,Variantes). - C. Componente
Yew(ads-front) — estructura similar acrates/app/marker.org: sección "Propiedades" con las propiedades del componente, bloquesHtml. Mismo esqueleto (Declaraciones antes de Definiciones, un encabezado por concepto), diferente terminología de bloques. - D. Nuevo crate ("
cargofederativo") — cuando el componente lógicamente no cabe en ningún crate existente. Entonces, además del propio componente, se necesitanconfig.org,env.org,main.orgdel nuevo crate y el registro en elconfig.orgraíz (ver Paso 4).
No asignes la variante D "por si acaso" — solo cuando el usuario pida explícitamente un nuevo crate, o cuando ningún crate existente sea lógicamente adecuado (y esto sea confirmado por el usuario).
Paso 1 — idioma del archivo org
El idioma depende de la situación, no está fijado de antemano. Antes de crear el archivo, revisa el idioma de los
archivos org vecinos en el directorio destino (code/ads-back/env.org — en inglés, la mayoría de crates/api/*.org —
en ucraniano): si el directorio tiene una mayoría clara, escribe en ese mismo idioma; si es un directorio nuevo o el idioma
de los vecinos es ambiguo, pregunta al usuario con una sola pregunta, no adivines.
Paso 2 — esqueleto común (todas las variantes)
Independientemente de la variante, cada nuevo archivo org con su propio destino :tangle:
-
#+title: ...— nombre del componente (en el idioma del paso 1). -
Si es necesario, un párrafo con enlace a la especificación (
[[https://...][especificación]]), como encreate-card.org. -
Primer encabezado (
* Módulo/* Archivo/* Crate— nombre según el ejemplo de los archivos vecinos del mismo directorio, no está estrictamente fijo) con un bloque esqueleto:#+begin_src rust :noweb yes :mkdirp yes :tangle src/NOMBRE_ARCHIVO.rs <<Declaraciones>> <<Definiciones>> #+end_src -
Inmediatamente después del esqueleto — sección
* Ejecutor(para procedimiento/comando) con dos bloques::noweb-ref Declaraciones(imports, incluyendo los tiposRequest/Responsedeads_api) y:noweb-ref Definiciones(la funciónpub fn run(...), cuyo cuerpo es principalmente<<Acciones>>dentro dedb::cnnctn().transaction(...), si se necesita una transacción). -
Cada detalle lógico siguiente (verificación, obtención de campo, inserción en tabla, etc.) — encabezado
*/**separado con sus propios:noweb-ref Declaraciones(si se necesitan nuevosuse) y:noweb-ref Acciones— en ese orden (declaración antes del uso, como en todas partes). No juntes toda la lógica en un solo bloque — cada paso significativo debe tener su propio encabezado, como encreate-card.org(allí hay 15+ encabezados separados para un solo procedimiento). -
Si un paso genera una función auxiliar (ej.
upsert_phoneencreate-card.org) — un:noweb-ref Definicionespropio para la firma de la función, y el cuerpo a través de su propionoweb-refnombrado (upsert-phone:Acciones), y subencabezados**/***para cada acción dentro de ella.
La variante B (subcomando CLI) difiere en que no habrá un nuevo bloque esqueleto — en su lugar,
añade en el main.org existente tres bloques noweb sin un nuevo encabezado-esqueleto:
:noweb-ref Declaraciones (mod nuevo_subcomando;), :noweb-sep ",\n" :noweb-ref Command:Elementos
(variante del enum Command con campos de argumentos), y
:noweb yes :noweb-sep ",\n" :noweb-ref Variantes (Command::Variante { ... } => crate::módulo::run(...)) —
cada uno en su propio encabezado *, nombrado con la acción (ej. * Creación de organización), y la implementación
en sí en un nuevo archivo org del subcomando según el esqueleto común (paso 2, variante A).
La variante C (componente Yew) difiere en los nombres de las secciones: en lugar de "Ejecutor" — sección
"Propiedades" (struct ...Props, una propiedad = un subapartado **, :noweb-sep ",\n" :noweb-ref NombreProps:Propiedades), y sección "Componente" (#[function_component(...)], cuerpo —
<<Nombre:Estado>>, <<Nombre:Efectos>>, <<Nombre:Manejadores>>, html! { <<Nombre:Html>> }). Mira
code/ads-front/crates/app/marker.org como ejemplo vivo de esta variante.
Paso 3 — función main típica (variante D, inicialmente)
La primera versión de main.org de un nuevo crate debe ser lo más simple posible — sin manejo de errores, sin Result, sin
async, sin inicialización de logger/env, a menos que haya una necesidad concreta:
#+title: NOMBRE DEL CRATE
* Archivo
#+begin_src rust :noweb yes :mkdirp yes :tangle src/main.rs
<<Declaraciones>>
<<Definiciones>>
fn main() {
<<Acciones>>
}
#+end_src
<<Acciones>> al principio puede estar completamente vacío (el nuevo crate aún no hace nada) — este es un primer
paso normal; los siguientes encabezados lo llenan gradualmente, como en crates/cli/main.org/crates/svc/main.org.
El manejo de errores (Result, ?), async, inicialización de dotenv/env_logger, etc., se añaden en encabezados
separados más tarde, cuando un paso concreto realmente lo requiera — no por adelantado.
Paso 4 — nuevo crate: config.org y registro en el config.org federativo
-
crates/NOMBRE/config.org— archivo del crate (vercrates/cli/config.orgcomo ejemplo):#+title: =Cargo=-archivo * Archivo #+begin_src toml :noweb yes :tangle Cargo.toml [package] name = "NOMBRE" version = "0.1.0" edition = "2021" [dependencies] <<Dependencias>> #+end_srcCada dependencia — un encabezado
* =nombre_crate=separado con:noweb-ref Dependencias(nombre = { workspace = true }), ordenado según la regla deCLAUDE.md(terceros →forge→ crates del proyecto, de lo contrario alfabético). Los bloques* Versión =Rust=/* Configuración local(rust-toolchain.toml/.cargo/config.toml) se copian delconfig.orgvecino solo si es una práctica común en ese directorio — no los añadas "por si acaso" si ningún crate vecino lo hace. Si copias, el archivo se vuelve multi-destino (varios:tanglediferentes), por lo que todos los bloques noweb (incluyendoDependencias) pasan a usar nombres con prefijo (Cargo:Dependencias,config:Definiciones, etc., ver CLAUDE.md) — como en elconfig.orgraíz más abajo. -
En el
config.orgRAÍZ (workspace), añade un nuevo encabezado* =NOMBRE=con dos bloques — siguiendo el ejemplo de las secciones* =db=/* =api=en la raíz:#+begin_src toml :noweb-sep ",\n" :noweb-ref Cargo:Crates "crates/NOMBRE" #+end_src #+begin_src toml :noweb-ref Cargo:Dependencias NOMBRE = { path = "crates/NOMBRE" } #+end_src -
env.org— si el nuevo crate no introduce variables de entorno propias, no toques nada. Si introduce, y en el proyecto ya existe unenv.orgraíz compartido, añade allí una nueva sección*con su propio:noweb-ref(como* Database access/* =JWT= parameters), y no crees un archivo separado. Crea unenv.orgSEPARADO para el nuevo crate solo cuando este sea un despliegue independiente (su propio.env, no el mismo proceso) y no haya unenv.orgcompartido. En cualquier caso, el primerenv.orgpuede dejarse completamente sin variables concretas ("puede estar sin valores, solo el archivo principal") — simplemente un esqueleto:#+title: =dotenv= file * Configuration file #+begin_src conf :noweb yes :tangle .env.example <<Definiciones>> #+end_srcy llenarlo con secciones
* =X= parametersmás tarde, cuando aparezcan variables reales.
Paso 5 — verificación después de cada cambio
Después de cada edición sustancial del código fuente org:
tanglereal medianteemacsclient --eval(nunca escribas el contenido de.rs/.toml/.env.examplemanualmente — ver la regla global correspondiente).cargo check -p CRATE(añade--target wasm32-unknown-unknownparaads-front) — cero advertencias y errores.- Ejecuta la habilidad
org-linten el archivo modificado y corrige los hallazgos "CIERTOS" de inmediato; "requiere revisión" — revísalos. - Para la prosa recién escrita/modificada —
(font-lock-ensure)+org-fill-paragrapha través del mismoemacsclient, no manualmente.
No muestres el componente al usuario como terminado hasta que estos cuatro puntos se hayan completado para cada archivo org nuevo o modificado.