Skip to content
Back to skills

Scaffold Models

ASecurity

Scaffold ArchiPy models under models/: domain/repository DTOs, errors, optional entities and types. Use for "add DTO/schema/request/response model", "new error type", or "SQLAlchemy entity".

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 24, 2026
developmentpythongosqlgitapi

Works with

  • claude code
  • cursor
  • api

Security analysis

A100/100

Scanned October 4, 2026

npx -y skills add SyntaxArc/archipy-plugin --skill scaffold-models --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Scaffold Models?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Scaffold Models
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/syntaxarc-scaffold-models/badge)](https://www.skillsdirectory.com/skills/syntaxarc-scaffold-models)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: scaffold-models
description: >-
  Scaffold ArchiPy models under models/: domain/repository DTOs, errors, optional
  entities and types. Use for "add DTO/schema/request/response model", "new error type",
  or "SQLAlchemy entity".
---

# Scaffold ArchiPy Models

## Scope

**Only** `models/`. Do not create repositories, logics, services, or helpers here.

## Read first

Read these plugin rules in full before generating files (paths relative to this skill directory; Claude Code: `${CLAUDE_SKILL_DIR}/../../rules/`):

- `../../rules/using-archipy-models.mdc`
- `../../rules/architecture-for-apps.mdc`
- `../../rules/using-archipy-utils.mdc`

## Before writing files

1. Inspect existing `models/` (DTOs, errors, entities, types), neighboring domains, and the installed ArchiPy version.
2. Infer domain name, DTO naming, and error grouping from existing modules.
3. Ask only for unresolved domain / operation names.
4. Preserve existing model modules; do not overwrite.

## Generate

```text
models/
├── dtos/<domain>/
│   ├── domain/v{n}/
│   │   ├── <op>_input_dto.py
│   │   └── <op>_output_dto.py
│   └── repository/
│       ├── <action>_command_dto.py
│       └── <action>_query_dto.py
├── errors/
│   └── <domain>_errors.py
├── entities/                    # optional
│   └── <domain>_entity.py
└── types/                       # optional
    └── <domain>_types.py
```

Naming: `*InputDTO` / `*OutputDTO` for domain (versioned under `domain/v{n}/`); `*CommandDTO` / `*QueryDTO` /
`*ResponseDTO` for repository (never versioned). Any repository method with two or more parameters takes a single
`*CommandDTO` (write) / `*QueryDTO` (read) instead of positional arguments. Entities/DTOs for JWT-authenticated writes carry an explicit `actor_uuid` that fills `created_by*`/`updated_by*`
(actor from `current_actor`/`act` first, token `user_id`/`sub` second; never a path owner uuid).
Prefer ArchiPy `BaseDTO` and the exported `BaseError` hierarchy.
Verify imports against the app's installed ArchiPy version before writing.

Example shapes (`order` → rename):

```python
# models/dtos/order/domain/v1/order_create_input_dto.py
from pydantic import Field, PositiveInt

from archipy.models.dtos.base_dtos import BaseDTO


class OrderCreateInputDTO(BaseDTO):
    """Domain input crossing the service → logic boundary."""

    customer_id: str = Field(min_length=1)
    sku: str = Field(min_length=1)
    quantity: PositiveInt
```

```python
# models/dtos/order/domain/v1/order_create_output_dto.py
from archipy.models.dtos.base_dtos import BaseDTO


class OrderCreateOutputDTO(BaseDTO):
    """Domain output returned to the service layer."""

    order_id: str
    status: str
```

```python
# models/dtos/order/repository/order_create_command_dto.py
from pydantic import PositiveInt

from archipy.models.dtos.base_dtos import BaseDTO


class OrderCreateCommandDTO(BaseDTO):
    """Repository write command — mapped from domain input inside the logic."""

    customer_id: str
    sku: str
    quantity: PositiveInt
```

```python
# models/errors/order_errors.py
from archipy.models.errors import InvalidArgumentError, NotFoundError


class OrderNotFoundError(NotFoundError):
    """Raised when an order cannot be located."""


class OrderInvalidArgumentError(InvalidArgumentError):
    """Raised when order input fails domain validation."""
```

Prefer Pydantic's constrained types over `int = Field(gt=0)` / bare `str`: `PositiveInt`, `NonNegativeInt`,
`NonNegativeFloat`, `SecretStr` (tokens, passwords, API keys — never log or serialize the raw value), `HttpUrl`,
`EmailStr`, `UUID4`, `StringConstraints`, and the specific date/time types: `NaiveDatetime` (default for
timestamps; no timezone-aware fields), `PastDatetime`, `FutureDatetime`, `PastDate`, `FutureDate` — never bare `datetime` / `date`
when a stricter type fits. Reach for `pydantic-extra-types` (`PhoneNumber`,
`Country`, `Currency`, `Coordinate`, …) before hand-rolled validators; add it to the app's dependencies first. Read raw
secrets only at the boundary with `.get_secret_value()`. Reference: https://docs.pydantic.dev/latest/api/types/

Make DTOs reject invalid states at construction so downstream code and tests only see valid inputs: use
`@field_validator` for single-field rules and `@model_validator(mode="after")` for cross-field rules (ranges,
exactly-one-of, conditionally required fields). Prefer a type over a validator, and a discriminated union /
`Literal` / `StrEnum` over optional fields plus runtime `if`s. Validators are pure (no I/O; uniqueness and existence
checks stay in logics). Cover each validator with one invalid example at the DTO boundary.

For gRPC payloads extend `BaseProtobufDTO` instead of `BaseDTO` and set `_proto_class`. Unset proto3 scalars arrive
as `""` / `0`, so constrain them (`PositiveInt`, `StringConstraints(min_length=1)`); `to_proto` masks `SecretStr`, so
keep secrets out of response DTOs.

`BaseDTO` is frozen — do not mutate instances after validation. Prefer existing ArchiPy errors over near-duplicates.
Export public app errors from `models/errors/__init__.py` when other layers consume them. Prefer ArchiPy pagination /
sort / search DTOs before inventing page or cursor shapes.

## Do not

- Data structures only — no I/O, no business rules, no adapters, no DB sessions, no HTTP/gRPC types.
- Never import repositories, logics, or services from models.
- Do not version repository DTOs.
- Double quotes, Google-style docstrings, Python 3.14+ typing.
- No I/O, business rules, adapters, DB sessions, or HTTP/gRPC types in models.
- Do not mutate frozen `BaseDTO` instances after validation.

## Verify

1. Run the repository's formatter and linter on generated Python.
2. Confirm DTO naming, versioned domain vs unversioned repository layout, and error subclassing.
3. Import the new modules without constructing infrastructure.
4. Run the `archipy-reviewer` subagent on the changes and fix every **Must fix** finding it reports.
5. Report files and commands run.

## Docs

- https://syntaxarc.github.io/ArchiPy/getting-started/project_structure/
- https://syntaxarc.github.io/ArchiPy/tutorials/error_handling/
- Bundled: `../archipy-docs/reference.md` (DTO naming)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.