$npx -y skills add maksimzayats/specx --skill specx-add-core-use-caseAdd or refactor a specx core scope use case. Use when implementing an externally meaningful application action under a core scope use_cases package, adding same-file command/query inputs, result DTOs, coordinating services, opening a unit-of-work transaction, or moving behavior o
| 1 | # specx Add Core Use Case |
| 2 | |
| 3 | Use this skill for one application action at a time. Read |
| 4 | `references/use-case.md` before writing the use case. |
| 5 | |
| 6 | ## Workflow |
| 7 | |
| 8 | 1. Name the action directly, for example `CreateInvoiceUseCase`. |
| 9 | 2. Put it under `core/<scope>/use_cases/<action>.py`. |
| 10 | 3. Inherit `BaseUseCase` from `specx.core.foundation.use_case`. |
| 11 | 4. Define exactly one same-file input class: a `Command` for state-changing |
| 12 | use cases or a `Query` for read-only use cases. Even empty inputs are |
| 13 | explicit. |
| 14 | 5. Make commands inherit `specx.core.foundation.command.BaseCommand`, queries inherit |
| 15 | `specx.core.foundation.query.BaseQuery`, and result DTOs inherit |
| 16 | `specx.core.foundation.dto.BaseDTO`. Prefer |
| 17 | `@dataclass(frozen=True, kw_only=True, slots=True)` for all of these core |
| 18 | data classes unless the user asks for another model type. |
| 19 | 6. Treat commands and queries as input contracts, not DTOs. Do not make |
| 20 | commands or queries inherit `BaseDTO`, put them under `dtos/`, or add a |
| 21 | `DTO` suffix. |
| 22 | 7. `execute(...)` accepts exactly one keyword-only argument named `command` or |
| 23 | `query` and returns DTOs, not entities. |
| 24 | 8. Inject services, capabilities, gateways, and UoW managers with |
| 25 | `Injected[...]`. Keep infrastructure/runtime settings out of core use cases; |
| 26 | expose required business policy as a typed core value or collaborator. For |
| 27 | transactional persistence, inject the scope |
| 28 | `UnitOfWorkManager` and open the active unit of work inside `execute(...)`. |
| 29 | Do not inject repositories, SQLAlchemy sessions/engines/session factories, |
| 30 | or concrete infrastructure adapters directly into use cases. |
| 31 | 9. Keep framework schemas, routers, ORM models, Redis clients, HTTP clients, |
| 32 | and entity return types |
| 33 | out of the use case. |
| 34 | 10. Mark secret-bearing dataclass fields with `field(repr=False)` and never log |
| 35 | whole commands, queries, or DTOs that may contain sensitive values. |
| 36 | 11. Add or update flat unit tests for the behavior. The test receives the |
| 37 | native pytest `container` fixture, registers local doubles or inline mocks |
| 38 | before resolution, and resolves the use case with |
| 39 | `container.resolve(UseCaseClass)`. If the use case injects a |
| 40 | `UnitOfWorkManager`, also add a core integration test under |
| 41 | `tests/integration/core/...` against the real persistence graph (and the |
| 42 | transactional database graph when database-backed). |
| 43 | |
| 44 | `CheckReadinessUseCase` may live under `core/health` when readiness checks any |
| 45 | required external dependency or multiple delivery layers reuse the policy. Add |
| 46 | a core `CheckLivenessUseCase` only when framework-independent liveness policy |
| 47 | is genuinely reused across deliveries; keep a simple process-only liveness |
| 48 | response in delivery. HTTP paths, status codes, headers, and schemas always |
| 49 | stay in delivery. |
| 50 | |
| 51 | ## Transaction Rule |
| 52 | |
| 53 | A use case may open one unit-of-work scope inside `execute(...)` when database |
| 54 | work is part of the action. Inject the manager, not `Provider[UnitOfWork]` and |
| 55 | not an active UoW instance, repository, SQLAlchemy session/engine/session |
| 56 | factory, or concrete infrastructure adapter. Read/effect services may receive |
| 57 | the active `unit_of_work`, but services do not open transactions. Repository |
| 58 | calls from a use case stay rooted in the manager-owned `unit_of_work` variable. |
| 59 | |
| 60 | Commands are allowed to change state. Queries are read-only and should not call |
| 61 | repository mutators such as `add`, `save`, `create`, `update`, or `delete`, or |
| 62 | invoke gateways with external write effects. |
| 63 | |
| 64 | ## Code Style |
| 65 | |
| 66 | Use blank lines as logical separators in all code. Keep related statements |
| 67 | together, but separate independent setup, action, assertion, response, branch, |
| 68 | and transformation groups so long blocks stay readable. |
| 69 | |
| 70 | ## References |
| 71 | |
| 72 | - `references/use-case.md` - use-case class shape, DTO examples, UoW examples, |
| 73 | and test guidance. |