一键导入
extend-core
Extending or modifying @rangka/core internals (registries, handlers, boot, context). Use when contributing to the framework itself.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Extending or modifying @rangka/core internals (registries, handlers, boot, context). Use when contributing to the framework itself.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | extend-core |
| description | Extending or modifying @rangka/core internals (registries, handlers, boot, context). Use when contributing to the framework itself. |
You are modifying framework internals. App developers depend on the public API staying stable. Every change must preserve existing behavior unless intentionally breaking (with migration path).
Identify what you are changing:
src/boot/index.ts)src/api/route-generator.ts)src/hooks/executor.ts, src/hooks/middleware.ts)@rangka/shared types/context.ts + src/hooks/context.ts)src/model-api/)Read the public API surface that consumers use:
FrameworkContext in @rangka/shared/src/types/context.ts — hooks, services, and jobs receive thisModelAccessInterface / ModelQueryInterface in the same file — the query API app devs calldefineHooks, defineService, defineJob in @rangka/shared/src/define.ts — app definition APIBootPayload in @rangka/shared/src/types/boot.ts — what the client receives at startupSearch for all consumers before modifying:
grep -r "ctx.models" packages/core/src/
grep -r "FrameworkContext" packages/
grep -r "SchemaRegistry" packages/core/src/
Registries are singleton objects created during boot. They hold runtime state.
Pattern for adding a method:
src/schema/registry.ts)@rangka/sharedPattern for adding a new registry:
src/notifications/registry.ts)src/boot/index.ts during the boot sequenceFrameworkContext if app devs need access@rangka/shared types if the interface is publicThis is the most sensitive change. Every hook, service, and job receives this object.
Adding a new field:
FrameworkContext in @rangka/shared/src/types/context.tssrc/hooks/context.ts (createHookContext) AND src/context.ts (createFrameworkContext)pnpm --filter @rangka/shared build && pnpm --filter @rangka/core buildpnpm buildModifying an existing field's type:
The hook pipeline is in src/hooks/executor.ts and src/hooks/middleware.ts.
executor.ts — runs hook chains (validate → before → after) in sequencemiddleware.ts — Fastify request handlers that orchestrate the full CRUD + hooks flowRules:
HookLifecycle type in src/hooks/types.ts AND the executorwithHooksCreate, withHooksUpdate, withHooksDelete) are the authoritative CRUD handlers. Never create a parallel CRUD path.src/api/route-generator.ts auto-generates REST routes for all models.
withHooksCreate/Update/Delete from src/hooks/middleware.ts for mutationslistHandler/getHandler from src/api/handlers.ts for readsTo add a new capability to all model routes (e.g., new query parameter, new response field):
src/api/handlers.tssrc/api/openapi-schema.ts)To add a non-model route (e.g., /api/meta/...):
generateRoutes() alongside the existing meta/session routesThe model access layer (src/model-api/) is the query engine.
query-builder.ts — ModelQueryBuilder (fluent API for filtering/sorting/pagination)filter-translator.ts — converts API filter syntax to Kysely where clausesfilter-applier.ts — applies filter conditions to a queryscope-enforcer.ts — enforces tenant/scope/field-level permissionsinclude-resolver.ts — resolves relationship includesfield-access.ts — strips hidden fields, enforces readOnlyRules:
filter-translator.tsModelQueryBuilder.unscoped() explicitlyModelAccessInterface in @rangka/shared is the public contract. Adding a method there is fine (additive). Changing signatures is breaking.| Anti-pattern | Correct approach |
|---|---|
| New CRUD handler that skips hooks | Use withHooksCreate/Update/Delete |
| Custom filter logic in a route handler | Add to filter-translator.ts |
| Direct Kysely queries for model CRUD in handlers | Use model-api through the existing handler pattern |
| New singleton that duplicates a registry's purpose | Extend the existing registry |
Modifying FrameworkContext in core without updating shared types | Always update @rangka/shared first |
Adding a field to BootPayload without updating client consumer | Check packages/client/src/boot/ |
@rangka/shared updated if neededcreateHookContext() and createFrameworkContext() both updated if FrameworkContext changedpnpm testpnpm test:integrationpnpm build