SE
service-development
Build or update services in `app/features/services` using the `_template/service` conventions (container/store/structure/lib/constants) so code stays consistent with project rules.
Install
mkdir -p .claude/skills/service-development && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16318" && unzip -o skill.zip -d .claude/skills/service-development && rm skill.zipInstalls to .claude/skills/service-development
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Build or update services in `app/features/services` using the `_template/service` conventions (container/store/structure/lib/constants) so code stays consistent with project rules.180 charsno explicit “when” trigger
About this skill
Service Development
When to use
- Creating a new service (copy
_template/serviceintoapp/features/services/<serviceName>and rename Sample placeholders). - Updating container/store/structure/lib/constants for an existing service while keeping template rules intact.
- Removing an existing service and its wiring from store/actions via CLI.
Quick start
- Scaffold via CLI:
ill addService auth- or
ill addService --name auth - Add
--no-storeif the service does not need a Redux slice/store wiring.
- Keep export surface the same (
index.tsxre-exports store/constants/lib and exposes{ service: useContainer }from a lowercase export). - Replace placeholder DTO/UI types, schemas, and data models; move every magic number/string into
constants/and re-export viaconstants/index.ts. - If the service is global (app-wide side effects), register it in the root ServiceInjector services list.
- Remove via CLI when needed:
ill removeService auth- or
ill removeService --name auth
File roles and guardrails
-
container (
container/index.ts)- Hook signature stays
useContainer: SC; no props passed. - Comment every logical block with
// Описание: Начало/Конец; do not comment the return; update comments instead of deleting. - Naming: camelCase vars/functions, PascalCase components/types, booleans with is/has/should/can; handlers named
on***Handler; use meaningful names. - No
useCallback/useMemo(React compiler handles it). - Constants in SCREAMING_SNAKE_CASE under
constants/with barrel re-export; no inline magic literals. - If the service talks to backend and you map data between layers, keep transformations in
lib/mappers(do not do mapping in container).
- Hook signature stays
-
index.tsx
- Must export a lowercase service object to avoid collisions with widgets:
export const auth = { service: useContainer }
- Re-export
constants,store,libto supportuseAppActionsauto-binding.
- Must export a lowercase service object to avoid collisions with widgets:
-
store/index.ts
- Only reducers inside
createSlice; no extra functions. initialStateimported fromstructure; do not typeinitialState.- Re-export via
ActionsandReducer(used byuseAppActionsand store assembly).
- Only reducers inside
-
structure/index.ts
- Holds
initialStateonly; no functions; no type declaration for the state object.
- Holds
-
lib/types
- Use
typealiases (no interfaces) withTypesuffix; enums withEnumsuffix. - No function type definitions here; boolean names with is/has/should/can.
- Put request/response DTO adapters here if service interacts with API/persistence.
- Use
-
lib/mappers
- Sole place for DTO ↔ internal model transformations; return
Nullablewhere appropriate.
- Sole place for DTO ↔ internal model transformations; return
-
lib/schemas
- Yup schemas for forms/validation when needed; keys should be enums from
lib/types.
- Yup schemas for forms/validation when needed; keys should be enums from
-
lib/utils
- Lightweight helpers that consume typed data; magic values go to
constants/.
- Lightweight helpers that consume typed data; magic values go to
-
constants/
- SCREAMING_SNAKE_CASE, meaningful names, no single-letter or cryptic abbreviations; re-export through
constants/index.ts. name.tsbuilds a service name fromNAME_FROM_PACKAGE_JSON(service naming, not widget naming).
- SCREAMING_SNAKE_CASE, meaningful names, no single-letter or cryptic abbreviations; re-export through
Store and actions wiring
If you scaffolded without --no-store, the CLI will auto-inject:
- Reducer import + reducer key into
app/application/store/reducers.tsunder// Services: Начало - Actions binding into
app/utils/hooks/useAppActions.ts
If you scaffolded with --no-store:
- CLI will NOT inject reducer/hooks. Keep the service free of Redux usage (or wire it manually if you later add a slice).
Do not confuse templates
- repo root
_template/service/*: scaffolding templates used byill addService - widget-local
templates/*: UI decomposition pieces used by widgets (not applicable to services)
Final checks
- Comments preserved/updated per template; no inline magic values; types/mappers/schemas/constants live in their dedicated files.
- Export name casing: service export is lowercase in
index.tsx. - If the service is app-global: it is included in the
ServiceInjectorlist in/app/root.tsx.