scaffold-ca-python 0.2.1__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,12 +16,12 @@ from scaffold_ca_python.commands._shared import (
16
16
  )
17
17
  from scaffold_ca_python.core.module_builder import ModuleBuilder
18
18
  from scaffold_ca_python.core.name_utils import validate_module_name
19
- from scaffold_ca_python.core.project_detector import load_project_context
19
+ from scaffold_ca_python.core.project_detector import load_project_context, resolve_tests_root
20
20
  from scaffold_ca_python.factory.simple.model_factory import ModelFactory
21
21
  from scaffold_ca_python.models.context import ModuleContext
22
22
  from scaffold_ca_python.models.layer import Layer
23
23
 
24
- _GM_HELP = "Scaffold a Pydantic v2 domain model and test stub. Alias 'gm'."
24
+ _GM_HELP = "Scaffold a Pydantic v2 domain model, its gateway, and test stubs. Alias 'gm'."
25
25
  _GM_EPILOG = "Example:\n\n * scaffold gm --name order\n\n * scaffold generate-model --name order\n\n"
26
26
 
27
27
 
@@ -31,12 +31,24 @@ def _generate_model_impl(name: str, dry_run: bool) -> None:
31
31
  project_ctx = load_project_context(project_root)
32
32
  module_ctx = ModuleContext(name=name, layer=Layer.DOMAIN_MODEL, project=project_ctx)
33
33
 
34
- src_path = project_root / "src" / project_ctx.python_package / "domain" / "model" / f"{module_ctx.module_name}.py"
34
+ model_root = project_root / "src" / project_ctx.python_package / "domain" / "model"
35
35
  ensure_absent(
36
- src_path,
36
+ model_root / module_ctx.module_name,
37
+ project_root,
38
+ kind="Directory",
39
+ hint="Choose a different name or remove the existing folder first.",
40
+ )
41
+ ensure_absent(
42
+ model_root / f"{module_ctx.module_name}.py",
37
43
  project_root,
38
44
  kind="File",
39
- hint="Choose a different name or remove the existing file first.",
45
+ hint="A model with this name already exists in the legacy flat layout. Remove it or choose a different name.",
46
+ )
47
+ ensure_absent(
48
+ resolve_tests_root(project_root) / "domain" / "model" / module_ctx.module_name,
49
+ project_root,
50
+ kind="Directory",
51
+ hint="Remove the leftover tests folder or choose a different name.",
40
52
  )
41
53
 
42
54
  builder = ModuleBuilder(project_root=project_root, project_ctx=project_ctx, module_ctx=module_ctx, dry_run=dry_run)
@@ -70,7 +82,7 @@ def register(app: typer.Typer) -> None:
70
82
  ),
71
83
  ] = False,
72
84
  ) -> None:
73
- """Scaffold a domain model in domain/model/."""
85
+ """Scaffold a domain model package with its gateway in domain/model/<name>/."""
74
86
  if name is None:
75
87
  typer.echo(ctx.get_help())
76
88
  raise typer.Exit(0)
@@ -10,43 +10,53 @@ from scaffold_ca_python.commands._shared import (
10
10
  build_and_persist,
11
11
  console,
12
12
  ensure_absent,
13
+ fail,
13
14
  print_dry_run_tree,
14
15
  require_project_root,
15
16
  validate_name_or_exit,
16
17
  )
17
18
  from scaffold_ca_python.core.module_builder import ModuleBuilder
18
- from scaffold_ca_python.core.name_utils import to_snake_case, validate_module_name
19
- from scaffold_ca_python.core.project_detector import load_project_context
19
+ from scaffold_ca_python.core.name_utils import strip_usecase_suffix, to_snake_case, validate_module_name
20
+ from scaffold_ca_python.core.project_detector import load_project_context, resolve_tests_root
20
21
  from scaffold_ca_python.factory.simple.use_case_factory import UseCaseFactory
21
22
  from scaffold_ca_python.models.context import ModuleContext
22
23
  from scaffold_ca_python.models.layer import Layer
23
24
 
24
25
  _GUC_HELP = "Scaffold a use case in domain/usecase/. Alias 'guc'."
25
26
  _GUC_EPILOG = (
26
- "Example:\n\n * scaffold guc --name create_order\n\n * scaffold generate-use-case --name create_order\n\n"
27
+ "Example:\n\n * scaffold guc --name create_order (creates domain/usecase/create_order_usecase.py)\n\n"
28
+ " * scaffold generate-use-case --name create_order\n\n"
27
29
  )
28
30
 
29
31
 
30
32
  def _generate_use_case_impl(name: str, dry_run: bool) -> None:
31
33
  validate_name_or_exit(name, validate_module_name)
34
+ base = strip_usecase_suffix(to_snake_case(name))
35
+ if not base:
36
+ fail(
37
+ f"Use case name '{name}' is only the 'usecase' suffix.",
38
+ hint="Use a descriptive name such as 'create_order'.",
39
+ )
32
40
  project_root = require_project_root()
33
41
  project_ctx = load_project_context(project_root)
34
- module_ctx = ModuleContext(name=name, layer=Layer.DOMAIN_USECASE, project=project_ctx)
42
+ module_ctx = ModuleContext(name=base, layer=Layer.DOMAIN_USECASE, project=project_ctx)
35
43
 
36
- snake = to_snake_case(name)
37
- src_path = project_root / "src" / project_ctx.python_package / "domain" / "usecase" / f"{snake}.py"
38
- ensure_absent(
39
- src_path,
40
- project_root,
41
- kind="File",
42
- hint="Choose a different name or remove the existing file first.",
43
- )
44
+ module = f"{base}_usecase"
45
+ src_path = project_root / "src" / project_ctx.python_package / "domain" / "usecase" / f"{module}.py"
46
+ test_path = resolve_tests_root(project_root) / "domain" / "usecase" / f"test_{module}.py"
47
+ for path in (src_path, test_path):
48
+ ensure_absent(
49
+ path,
50
+ project_root,
51
+ kind="File",
52
+ hint="Choose a different name or remove the existing file first.",
53
+ )
44
54
 
45
55
  builder = ModuleBuilder(project_root=project_root, project_ctx=project_ctx, module_ctx=module_ctx, dry_run=dry_run)
46
56
  created = build_and_persist(UseCaseFactory(), builder)
47
57
 
48
58
  if dry_run:
49
- print_dry_run_tree(snake, created, project_root)
59
+ print_dry_run_tree(module, created, project_root)
50
60
  return
51
61
 
52
62
  msg = (
@@ -4,13 +4,15 @@ from __future__ import annotations
4
4
 
5
5
  from pathlib import Path
6
6
 
7
+ from scaffold_ca_python.core.name_utils import strip_usecase_suffix
7
8
  from scaffold_ca_python.core.project_detector import resolve_tests_root
8
9
 
9
10
 
10
11
  def find_module_targets(project_root: Path, pkg: str, snake: str) -> list[tuple[Path, Path | None]]:
11
12
  """Return ``(src_path, test_path | None)`` pairs for every match of *snake*.
12
13
 
13
- Searches in order: domain/model, domain/usecase, driven_adapters,
14
+ Searches in order: domain/model/<snake>/ (package), domain/model/<snake>.py (legacy flat),
15
+ domain/usecase (``<base>_usecase.py`` first, then legacy ``<snake>.py``), driven_adapters,
14
16
  entry_points, helpers.
15
17
  """
16
18
  src_root = project_root / "src" / pkg
@@ -18,9 +20,30 @@ def find_module_targets(project_root: Path, pkg: str, snake: str) -> list[tuple[
18
20
 
19
21
  candidates: list[tuple[Path, Path | None]] = []
20
22
 
23
+ model_pkg = src_root / "domain" / "model" / snake
24
+ if model_pkg.is_dir():
25
+ model_pkg_test = tests_root / "domain" / "model" / snake
26
+ candidates.append((model_pkg, model_pkg_test if model_pkg_test.exists() else None))
27
+
28
+ usecase_pairs: list[tuple[Path, Path]] = []
29
+ base = strip_usecase_suffix(snake)
30
+ if base:
31
+ usecase_pairs.append(
32
+ (
33
+ src_root / "domain" / "usecase" / f"{base}_usecase.py",
34
+ tests_root / "domain" / "usecase" / f"test_{base}_usecase.py",
35
+ )
36
+ )
37
+ legacy_usecase = (
38
+ src_root / "domain" / "usecase" / f"{snake}.py",
39
+ tests_root / "domain" / "usecase" / f"test_{snake}.py",
40
+ )
41
+ if legacy_usecase not in usecase_pairs:
42
+ usecase_pairs.append(legacy_usecase)
43
+
21
44
  for src_rel, test_rel in [
22
45
  (src_root / "domain" / "model" / f"{snake}.py", tests_root / "domain" / "model" / f"test_{snake}.py"),
23
- (src_root / "domain" / "usecase" / f"{snake}.py", tests_root / "domain" / "usecase" / f"test_{snake}.py"),
46
+ *usecase_pairs,
24
47
  ]:
25
48
  if src_rel.exists():
26
49
  candidates.append((src_rel, test_rel if test_rel.exists() else None))
@@ -9,6 +9,9 @@ NAME_RE = re.compile(r"^[a-z][a-z0-9]*([_-][a-z0-9]+)*$")
9
9
  # Stricter pattern for module/class-generating commands: snake_case only (no hyphens).
10
10
  MODULE_NAME_RE = re.compile(r"^[a-z][a-z0-9]*(_[a-z0-9]+)*$")
11
11
 
12
+ # Trailing use case suffixes (applied to "_" + name so a bare "usecase" also matches)
13
+ _USECASE_SUFFIX_RE = re.compile(r"(?:_(?:usecase|use_case))+$")
14
+
12
15
  # Matches transitions: lowercase→uppercase and letter→digit boundary runs
13
16
  _CAMEL_BOUNDARY_RE = re.compile(r"(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])")
14
17
 
@@ -50,6 +53,11 @@ def to_snake_case(name: str) -> str:
50
53
  return s.lower()
51
54
 
52
55
 
56
+ def strip_usecase_suffix(name: str) -> str:
57
+ """Remove every trailing ``_usecase`` / ``_use_case`` suffix from *name* (may return an empty string)."""
58
+ return _USECASE_SUFFIX_RE.sub("", f"_{name}").removeprefix("_")
59
+
60
+
53
61
  def to_kebab_case(name: str) -> str:
54
62
  """Convert *name* (PascalCase, snake_case, or already kebab-case) to kebab-case."""
55
63
  # Normalise underscores to hyphens first (snake_case support)
@@ -6,8 +6,8 @@ import shutil
6
6
  from pathlib import Path
7
7
  from typing import TYPE_CHECKING
8
8
 
9
+ from scaffold_ca_python.core.module_locator import find_module_targets
9
10
  from scaffold_ca_python.core.name_utils import to_snake_case
10
- from scaffold_ca_python.core.project_detector import resolve_tests_root
11
11
  from scaffold_ca_python.factory import ModuleFactory
12
12
 
13
13
  if TYPE_CHECKING:
@@ -21,8 +21,8 @@ class DeleteModuleFactory(ModuleFactory):
21
21
  """Build deletion operations for a module.
22
22
 
23
23
  Finds and deletes modules across:
24
- - domain/model/<snake>.py
25
- - domain/usecase/<snake>.py
24
+ - domain/model/<snake>/ (package) or domain/model/<snake>.py (legacy)
25
+ - domain/usecase/<base>_usecase.py or domain/usecase/<snake>.py (legacy)
26
26
  - infrastructure/driven_adapters/<snake>/
27
27
  - infrastructure/entry_points/<snake>/
28
28
  - infrastructure/helpers/<snake>/
@@ -34,41 +34,7 @@ class DeleteModuleFactory(ModuleFactory):
34
34
  module_name = builder.module_ctx.name if builder.module_ctx else "Module"
35
35
  snake_name = to_snake_case(module_name)
36
36
 
37
- src_root = project_root / "src" / pkg
38
- tests_root = resolve_tests_root(project_root)
39
-
40
- # Build list of possible module locations
41
- candidates: list[tuple[Path, Path | None]] = []
42
-
43
- # Single-file layers (domain/model, domain/usecase)
44
- model_src = src_root / "domain" / "model" / f"{snake_name}.py"
45
- model_test = tests_root / "domain" / "model" / f"test_{snake_name}.py"
46
- usecase_src = src_root / "domain" / "usecase" / f"{snake_name}.py"
47
- usecase_test = tests_root / "domain" / "usecase" / f"test_{snake_name}.py"
48
- for src_rel, test_rel in [
49
- (model_src, model_test),
50
- (usecase_src, usecase_test),
51
- ]:
52
- if src_rel.exists():
53
- candidates.append((src_rel, test_rel if test_rel.exists() else None))
54
-
55
- # Directory-based layers (infrastructure sub-dirs)
56
- for src_rel, test_rel in [
57
- (
58
- src_root / "infrastructure" / "driven_adapters" / snake_name,
59
- tests_root / "infrastructure" / "driven_adapters" / snake_name,
60
- ),
61
- (
62
- src_root / "infrastructure" / "entry_points" / snake_name,
63
- tests_root / "infrastructure" / "entry_points" / snake_name,
64
- ),
65
- (
66
- src_root / "infrastructure" / "helpers" / snake_name,
67
- tests_root / "infrastructure" / "helpers" / snake_name,
68
- ),
69
- ]:
70
- if src_rel.exists():
71
- candidates.append((src_rel, test_rel if test_rel.exists() else None))
37
+ candidates = find_module_targets(project_root, pkg, snake_name)
72
38
 
73
39
  if not builder.dry_run:
74
40
  for src_path, test_path in candidates:
@@ -15,43 +15,48 @@ class ModelFactory(ModuleFactory):
15
15
  """Factory for domain model generation."""
16
16
 
17
17
  def build(self, builder: ModuleBuilder) -> None:
18
- """Build domain model files.
18
+ """Build domain model package files.
19
19
 
20
20
  Queues files:
21
- - src/domain/model/{module_name}.py
22
- - tests/domain/model/test_{module_name}.py
21
+ - src/domain/model/{module_name}/__init__.py
22
+ - src/domain/model/{module_name}/{module_name}.py
23
+ - src/domain/model/{module_name}/gateways/__init__.py
24
+ - src/domain/model/{module_name}/gateways/{module_name}_repository.py
25
+ - tests/domain/model/{module_name}/test_{module_name}.py
26
+ - tests/domain/model/{module_name}/gateways/test_{module_name}_repository.py
23
27
 
24
28
  No dependencies injected (pydantic is already a project dependency).
25
29
  """
26
30
  project_root = builder.project_root
27
31
  pkg = builder.project_ctx.python_package
28
32
 
29
- # Get module name from module context
30
33
  module_name = builder.module_ctx.module_name if builder.module_ctx else "model"
31
34
 
32
- # Setup directory paths
33
- src_dir = project_root / "src" / pkg / "domain" / "model"
34
- test_dir = resolve_tests_root(project_root) / "domain" / "model"
35
+ src_dir = project_root / "src" / pkg / "domain" / "model" / module_name
36
+ gateways_dir = src_dir / "gateways"
37
+ test_dir = resolve_tests_root(project_root) / "domain" / "model" / module_name
38
+ test_gateways_dir = test_dir / "gateways"
35
39
 
36
- # Template base path
37
40
  base = "model"
38
41
 
39
- # Build context dict from module context
40
42
  ctx_dict = {}
41
43
  if builder.module_ctx:
42
44
  ctx_dict.update(builder.module_ctx.model_dump())
43
45
 
44
- # Add source file
45
- builder.add_file(
46
- src_dir / f"{module_name}.py",
47
- builder.render(f"{base}/model.py.jinja2", ctx_dict),
48
- template_name=f"{base}/model.py.jinja2",
49
- )
50
-
51
- # Add test file
52
- builder.add_file(
53
- test_dir / f"test_{module_name}.py",
54
- builder.render(f"{base}/test_model.py.jinja2", ctx_dict),
55
- template_name=f"{base}/test_model.py.jinja2",
56
- is_test=True,
57
- )
46
+ # (target path, template file name, is_test)
47
+ files = [
48
+ (src_dir / "__init__.py", "__init__.py.jinja2", False),
49
+ (src_dir / f"{module_name}.py", "model.py.jinja2", False),
50
+ (gateways_dir / "__init__.py", "gateways_init.py.jinja2", False),
51
+ (gateways_dir / f"{module_name}_repository.py", "gateway.py.jinja2", False),
52
+ (test_dir / f"test_{module_name}.py", "test_model.py.jinja2", True),
53
+ (test_gateways_dir / f"test_{module_name}_repository.py", "test_gateway.py.jinja2", True),
54
+ ]
55
+ for path, template, is_test in files:
56
+ template_name = f"{base}/{template}"
57
+ builder.add_file(
58
+ path,
59
+ builder.render(template_name, ctx_dict),
60
+ template_name=template_name,
61
+ is_test=is_test,
62
+ )
@@ -19,8 +19,8 @@ class UseCaseFactory(ModuleFactory):
19
19
  """Build domain use case files.
20
20
 
21
21
  Queues files:
22
- - src/domain/usecase/{snake_name}.py
23
- - tests/domain/usecase/test_{snake_name}.py
22
+ - src/domain/usecase/{snake_name}_usecase.py
23
+ - tests/domain/usecase/test_{snake_name}_usecase.py
24
24
 
25
25
  No dependencies injected (async/await are built-in).
26
26
  """
@@ -45,14 +45,14 @@ class UseCaseFactory(ModuleFactory):
45
45
 
46
46
  # Add source file
47
47
  builder.add_file(
48
- src_dir / f"{snake_name}.py",
48
+ src_dir / f"{snake_name}_usecase.py",
49
49
  builder.render(f"{base}/use_case.py.jinja2", ctx_dict),
50
50
  template_name=f"{base}/use_case.py.jinja2",
51
51
  )
52
52
 
53
53
  # Add test file
54
54
  builder.add_file(
55
- test_dir / f"test_{snake_name}.py",
55
+ test_dir / f"test_{snake_name}_usecase.py",
56
56
  builder.render(f"{base}/test_use_case.py.jinja2", ctx_dict),
57
57
  template_name=f"{base}/test_use_case.py.jinja2",
58
58
  is_test=True,
@@ -0,0 +1 @@
1
+ """{{ class_name }} domain model package."""
@@ -0,0 +1,7 @@
1
+ """{{ class_name }} gateway."""
2
+
3
+ from abc import ABC
4
+
5
+
6
+ class {{ class_name }}Repository(ABC):
7
+ """Repository contract for {{ class_name }}. Add the operations your domain needs."""
@@ -0,0 +1 @@
1
+ """{{ class_name }} gateways."""
@@ -0,0 +1,9 @@
1
+ """Tests for {{ class_name }}Repository gateway."""
2
+
3
+ from abc import ABC
4
+
5
+ from {{ project.python_package }}.domain.model.{{ module_name }}.gateways.{{ module_name }}_repository import {{ class_name }}Repository
6
+
7
+
8
+ def test_{{ module_name }}_repository_is_abstract_contract() -> None:
9
+ assert issubclass({{ class_name }}Repository, ABC)
@@ -1,6 +1,6 @@
1
1
  """Tests for {{ class_name }} domain model."""
2
2
 
3
- from {{ project.python_package }}.domain.model.{{ module_name }} import {{ class_name }}
3
+ from {{ project.python_package }}.domain.model.{{ module_name }}.{{ module_name }} import {{ class_name }}
4
4
 
5
5
 
6
6
  def test_{{ module_name }}_can_be_instantiated() -> None:
@@ -2,7 +2,7 @@
2
2
 
3
3
  import pytest
4
4
 
5
- from {{ project.python_package }}.domain.usecase.{{ module_name }} import {{ class_name }}UseCase
5
+ from {{ project.python_package }}.domain.usecase.{{ module_name }}_usecase import {{ class_name }}UseCase
6
6
 
7
7
 
8
8
  @pytest.mark.asyncio
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: scaffold-ca-python
3
- Version: 0.2.1
3
+ Version: 0.4.0
4
4
  Summary: Scaffolder to generate Clean Architecture apps
5
5
  Project-URL: Homepage, https://github.com/bancolombia/scaffold-clean-architecture-py
6
6
  Project-URL: Repository, https://github.com/bancolombia/scaffold-clean-architecture-py
@@ -105,19 +105,30 @@ scaffold ca --name my-project --dry-run
105
105
 
106
106
  ### scaffold gm
107
107
 
108
- Scaffold a Pydantic v2 domain model and its test stub.
108
+ Scaffold a Pydantic v2 domain model, its gateway (an empty abstract repository contract), and test stubs.
109
109
 
110
110
  ```bash
111
111
  scaffold gm --name order
112
112
  ```
113
113
 
114
+ Generated structure:
115
+
116
+ ```text
117
+ domain/model/order/
118
+ ├── __init__.py
119
+ ├── order.py
120
+ └── gateways/
121
+ ├── __init__.py
122
+ └── order_repository.py
123
+ ```
124
+
114
125
  ```bash
115
126
  scaffold gm --name order --dry-run
116
127
  ```
117
128
 
118
129
  ### scaffold guc
119
130
 
120
- Scaffold a use case in `domain/usecase/`.
131
+ Scaffold a use case in `domain/usecase/`. The module is always named `<name>_usecase.py` and the class `<Name>UseCase`. Writing `_usecase` in `--name` is optional and the suffix is never duplicated: `create_order`, `create_order_usecase` and `create_order_use_case` all create `create_order_usecase.py` with `CreateOrderUseCase`.
121
132
 
122
133
  ```bash
123
134
  scaffold guc --name create_order
@@ -8,18 +8,18 @@ scaffold_ca_python/commands/delete_module.py,sha256=J-nkA_o9mY2AOOzQBg3kyTEWm6el
8
8
  scaffold_ca_python/commands/generate_driven_adapter.py,sha256=IRGXCinpa694_9W7WXL7k43hOm9V52Jk87DVgayzeEs,4215
9
9
  scaffold_ca_python/commands/generate_entry_point.py,sha256=NvHF1auzB0bfcx9KzaHCx3Z_pA0FLswwDB9yW3LdKG8,9449
10
10
  scaffold_ca_python/commands/generate_helper.py,sha256=O98ua5Fj3judGxF_vmTYbm_j-qEAxGd4eA0F1YYtPqM,2884
11
- scaffold_ca_python/commands/generate_model.py,sha256=1oKXtRz7JkPPNZkmE-Kw1sOBUQgWnKo6IXYHxPf4-60,2839
11
+ scaffold_ca_python/commands/generate_model.py,sha256=GBHPkoTYrABNdmdILWGLuQFM4ppzYbuHyunjhc-o4Dc,3387
12
12
  scaffold_ca_python/commands/generate_pipeline.py,sha256=Ip-rN4nSbwaUbtJ49awAs4LDURsrDTQsZdG5kBCLdyE,3773
13
13
  scaffold_ca_python/commands/generate_project.py,sha256=5KRsPI_WiWQVY1d_0AblUHKdDQCWpXJA7MaOCHae0fE,5312
14
- scaffold_ca_python/commands/generate_use_case.py,sha256=N72h2BAyNgbCLiphryrwF1aDXkDL5NNj14Lsq7D3YFE,2947
14
+ scaffold_ca_python/commands/generate_use_case.py,sha256=3uKYZik9eF23Z9QMM2psGNWuW2AhxkB468urum5N8WA,3441
15
15
  scaffold_ca_python/commands/update_project.py,sha256=7bu2neRasxEtYK2rIvx0CFISSx9D64BNCkijp90zWGk,2367
16
16
  scaffold_ca_python/commands/validate_structure.py,sha256=p_bYTgOl4_TrC80z-v2teSsssc9xghlkCYlUp3SuzHo,2526
17
17
  scaffold_ca_python/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  scaffold_ca_python/core/file_writer.py,sha256=KdnNrq33Jsvqs1IQf0jbUKdXls4jBSWAizw4uJhMalU,5561
19
19
  scaffold_ca_python/core/mcp_tool_spec.py,sha256=mPLN7vOSgWFWxHQQxmr0fWEaimHWI-9A0oP7ob73-rU,10602
20
20
  scaffold_ca_python/core/module_builder.py,sha256=AHC3szEdfS3i3q74IM6USZTHWEUK6QizL6NEKcHCrrI,6837
21
- scaffold_ca_python/core/module_locator.py,sha256=VEZapvZqk11-5brsHJvPdIsKlEWSTdwS6T9XF9o0acE,1657
22
- scaffold_ca_python/core/name_utils.py,sha256=195Qb36CafP4CGRomzSAm3Hmm0C-Qld3I90boPAV-7A,2583
21
+ scaffold_ca_python/core/module_locator.py,sha256=FFAwA7Vajxg0JgHoVXc1HpvdB67clvkv_BFVwiQDxHA,2552
22
+ scaffold_ca_python/core/name_utils.py,sha256=IpXAieBKFe7QbOY4K8gNsjr4NXUfJX5MBCy2bQyPIk4,2958
23
23
  scaffold_ca_python/core/openapi_routes.py,sha256=RCQS7mHufWJZgbLI1cxGli-xGbU7p7WI95fHJhDnIss,1098
24
24
  scaffold_ca_python/core/project_detector.py,sha256=vcDAFCGgQVDMQ2MivJVUmn5Yyj58vGpTbzKhZTBQNtw,3524
25
25
  scaffold_ca_python/core/pyproject_writer.py,sha256=zpxgubt-XSZR5domgL4LG_9AWD9b_cNrDM8fuHmZRzE,7792
@@ -40,10 +40,10 @@ scaffold_ca_python/factory/entry_points/ep_restapi.py,sha256=PFkt9TH1aN6YO8w4zAe
40
40
  scaffold_ca_python/factory/pipelines/__init__.py,sha256=0YPpPGsZ6A3-udHTSZDyUHleLFLQQh1V5IL6AB0qJ6g,557
41
41
  scaffold_ca_python/factory/pipelines/pipeline_factory.py,sha256=s4fpuyhdxXiwko-LlM6Pv-QJdRGQJb17KVrC-DW6ojo,842
42
42
  scaffold_ca_python/factory/simple/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
- scaffold_ca_python/factory/simple/delete_module_factory.py,sha256=lw4_XCJegvDqxlZ7o6kDJ792rugOiUijCH1tVsiwRJI,3119
43
+ scaffold_ca_python/factory/simple/delete_module_factory.py,sha256=v_Kl-m7bxvCwUsdQuCPq66uPksuLFLYvbsTNdE4Cs8Q,1696
44
44
  scaffold_ca_python/factory/simple/helper_factory.py,sha256=nBVOu_kGBVrEGnXFa918GPo-UFlcW-Y5-Uk6bwYWuhQ,2295
45
- scaffold_ca_python/factory/simple/model_factory.py,sha256=cgI3TRCUNfNUBQY5mO-9mhNOwW5LWEVk6Y9rsx120Tg,1807
46
- scaffold_ca_python/factory/simple/use_case_factory.py,sha256=znCyynIGmWgc4P8icJXfb2xSiNZB2Cu4SGVacDrpSdY,1954
45
+ scaffold_ca_python/factory/simple/model_factory.py,sha256=YdUpBvGgUrz4zzXMG2p8d6PWit62B9esjLZG49dT5PU,2467
46
+ scaffold_ca_python/factory/simple/use_case_factory.py,sha256=CUY2SkneFWv-KukK-Cdn2KoLZwgYukNa25Hv15SQYx8,1986
47
47
  scaffold_ca_python/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
48
  scaffold_ca_python/models/context.py,sha256=Itp-YyPgY-0yNYA9YlCXrmPfa5nEVklGAOJQGHfBdHE,1909
49
49
  scaffold_ca_python/models/file_operation.py,sha256=R5Tu3KBvUnSmH5QZXBQTPoQjvr4YdH1YOKsKS9ICH_Q,1698
@@ -94,8 +94,12 @@ scaffold_ca_python/templates/entry_point/restapi/test_server.py.jinja2,sha256=7_
94
94
  scaffold_ca_python/templates/helper/__init__.py.jinja2,sha256=LA4hikmh30a_8LgZ8h18zdC3NEfDPNJeZOSBJ4RZBwU,39
95
95
  scaffold_ca_python/templates/helper/helper.py.jinja2,sha256=rPaSM5Y4U25Ht8nshnw9m_fc3FXkx-CHA_egJM7QDmc,110
96
96
  scaffold_ca_python/templates/helper/test_helper.py.jinja2,sha256=5nmkjej1FQngXh5JAoftdRvE8kdad0Knjxf25Lb--RI,268
97
+ scaffold_ca_python/templates/model/__init__.py.jinja2,sha256=fz54Iv6Z8sDtCMgIz8eFBXokdDz0SA2uhQMf8IGYUcs,45
98
+ scaffold_ca_python/templates/model/gateway.py.jinja2,sha256=o2FNIfFseauf_5REavVnM-Qe7k8rjoXRqSuqtOI0vIk,184
99
+ scaffold_ca_python/templates/model/gateways_init.py.jinja2,sha256=8bO2y7wFlMVRMURwxLD9ubAHuu71YXCRhGtfSjkWtcM,33
97
100
  scaffold_ca_python/templates/model/model.py.jinja2,sha256=pvzy78xH5-qWJ6IQb-9bY-dnqPj4FPBsQ-Kalh_mFr0,151
98
- scaffold_ca_python/templates/model/test_model.py.jinja2,sha256=55F0CUHb2A3D5ikSNgPveNZ1Jt11gwfzKqGKHYjuzLo,263
101
+ scaffold_ca_python/templates/model/test_gateway.py.jinja2,sha256=xedkiihpUCARhGSKEPLmAlbJ0yOxS2uvDwpIdLbmSFg,338
102
+ scaffold_ca_python/templates/model/test_model.py.jinja2,sha256=Wdz84c8Yt6aeUFQIINdfsq0K9Ihk7GT_ZVzpEGrQ4uM,281
99
103
  scaffold_ca_python/templates/pipeline/azure/azure_pipelines.yml.jinja2,sha256=ecbvubtMhoyqxiM69PunOYwOOBBLUFqSBsoqJsIqyDI,555
100
104
  scaffold_ca_python/templates/pipeline/github/ci.yml.jinja2,sha256=y20dpIoOHlZNCIXzyJdjsTgq2HiyCjHpcg2UPKZuQRg,672
101
105
  scaffold_ca_python/templates/project/README.jinja2,sha256=HazR7Ls3utOfMFjxDsVS1-WMCPG1OR4XR2ftn02Fnuo,696
@@ -115,10 +119,10 @@ scaffold_ca_python/templates/project/application/config/container.py.jinja2,sha2
115
119
  scaffold_ca_python/templates/project/application/config/driven_adapters_container.py.jinja2,sha256=WhRpupvLP8tOJgp4IJ0A5RitntfRPVFjCDUjhAhBt8U,464
116
120
  scaffold_ca_python/templates/project/application/config/resource_container.py.jinja2,sha256=k3wy8uSD7GJZNEf379fv2lMEzdq5eaNqmoaOw9Jq1vs,643
117
121
  scaffold_ca_python/templates/project/application/config/usecases_container.py.jinja2,sha256=3fEHe6mkXkDHlfO5nhLqzLB7ccTpqwtjHZfLyfysbro,527
118
- scaffold_ca_python/templates/use_case/test_use_case.py.jinja2,sha256=3K1bNKDBQc29rcv8UHUZnROCUmcFSCwJhbm0xP9Uako,364
122
+ scaffold_ca_python/templates/use_case/test_use_case.py.jinja2,sha256=spomnRHeXWiWjy3QHQt839yIMFDUqA7h-Wq4KfZxAyg,372
119
123
  scaffold_ca_python/templates/use_case/use_case.py.jinja2,sha256=KPtaK1wvZ-7qHdDZyuVfqXTPYwJdNUMPXQZGuKZFA7Y,217
120
- scaffold_ca_python-0.2.1.dist-info/METADATA,sha256=VxmJhT8bnSFEI4UGZznCyJSHD5QqDaVDrdWtxstKtYc,6960
121
- scaffold_ca_python-0.2.1.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
122
- scaffold_ca_python-0.2.1.dist-info/entry_points.txt,sha256=4PyYg6mNCvAlt2yF_o1-QR2CBXiowYGpNyqcP88tu6I,104
123
- scaffold_ca_python-0.2.1.dist-info/licenses/LICENSE,sha256=3ZZEP7DK_h3lEjS8r-DvQCec2q7zAqqq7HmSq6cuL0E,1068
124
- scaffold_ca_python-0.2.1.dist-info/RECORD,,
124
+ scaffold_ca_python-0.4.0.dist-info/METADATA,sha256=7LQgO7e31QQ8vmmP1PfqwXgaWnQRrLIIpengbcw8mf4,7475
125
+ scaffold_ca_python-0.4.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
126
+ scaffold_ca_python-0.4.0.dist-info/entry_points.txt,sha256=4PyYg6mNCvAlt2yF_o1-QR2CBXiowYGpNyqcP88tu6I,104
127
+ scaffold_ca_python-0.4.0.dist-info/licenses/LICENSE,sha256=3ZZEP7DK_h3lEjS8r-DvQCec2q7zAqqq7HmSq6cuL0E,1068
128
+ scaffold_ca_python-0.4.0.dist-info/RECORD,,