fast-clean-architecture 1.0.0__py3-none-any.whl → 1.1.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.
Files changed (27) hide show
  1. fast_clean_architecture/__init__.py +3 -4
  2. fast_clean_architecture/analytics.py +260 -0
  3. fast_clean_architecture/cli.py +555 -43
  4. fast_clean_architecture/config.py +47 -23
  5. fast_clean_architecture/error_tracking.py +201 -0
  6. fast_clean_architecture/exceptions.py +432 -12
  7. fast_clean_architecture/generators/__init__.py +11 -1
  8. fast_clean_architecture/generators/component_generator.py +407 -103
  9. fast_clean_architecture/generators/config_updater.py +186 -38
  10. fast_clean_architecture/generators/generator_factory.py +223 -0
  11. fast_clean_architecture/generators/package_generator.py +9 -7
  12. fast_clean_architecture/generators/template_validator.py +109 -9
  13. fast_clean_architecture/generators/validation_config.py +5 -3
  14. fast_clean_architecture/generators/validation_metrics.py +10 -6
  15. fast_clean_architecture/health.py +169 -0
  16. fast_clean_architecture/logging_config.py +52 -0
  17. fast_clean_architecture/metrics.py +108 -0
  18. fast_clean_architecture/protocols.py +406 -0
  19. fast_clean_architecture/templates/external.py.j2 +109 -32
  20. fast_clean_architecture/utils.py +50 -31
  21. fast_clean_architecture/validation.py +302 -0
  22. {fast_clean_architecture-1.0.0.dist-info → fast_clean_architecture-1.1.0.dist-info}/METADATA +31 -21
  23. fast_clean_architecture-1.1.0.dist-info/RECORD +38 -0
  24. fast_clean_architecture-1.0.0.dist-info/RECORD +0 -30
  25. {fast_clean_architecture-1.0.0.dist-info → fast_clean_architecture-1.1.0.dist-info}/WHEEL +0 -0
  26. {fast_clean_architecture-1.0.0.dist-info → fast_clean_architecture-1.1.0.dist-info}/entry_points.txt +0 -0
  27. {fast_clean_architecture-1.0.0.dist-info → fast_clean_architecture-1.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,31 +1,98 @@
1
1
  """Command-line interface for fast-clean-architecture."""
2
2
 
3
+ import os
3
4
  import sys
4
5
  from pathlib import Path
5
- from typing import Optional
6
+ from typing import List, NoReturn, Optional, Union, cast
6
7
 
7
8
  import typer
8
9
  from rich.console import Console
9
- from rich.table import Table
10
10
  from rich.panel import Panel
11
- from rich.prompt import Prompt, Confirm
11
+ from rich.progress import Progress, SpinnerColumn, TextColumn
12
+ from rich.prompt import Confirm, Prompt
12
13
  from rich.syntax import Syntax
14
+ from rich.table import Table
15
+ from rich.text import Text
13
16
 
17
+ from .analytics import log_usage_summary, track_command_usage, track_component_creation
14
18
  from .config import Config
15
- from .generators import PackageGenerator, ComponentGenerator, ConfigUpdater
16
- from .utils import (
17
- sanitize_name,
18
- validate_python_identifier,
19
- )
20
- from .exceptions import (
21
- FastCleanArchitectureError,
22
- ValidationError,
23
- )
19
+ from .error_tracking import log_error_summary, track_error
20
+ from .exceptions import FastCleanArchitectureError, ValidationError
21
+ from .generators import ConfigUpdater, PackageGenerator
22
+ from .generators.generator_factory import create_generator_factory
23
+ from .health import log_startup_health
24
+ from .logging_config import configure_logging, get_logger
25
+ from .utils import sanitize_name, validate_name, validate_python_identifier
26
+
27
+ # Configure structured logging
28
+ configure_logging()
29
+ logger = get_logger(__name__)
30
+
31
+ # Log startup health
32
+ log_startup_health()
24
33
 
25
34
  # Create the main Typer app
26
35
  app = typer.Typer(
27
36
  name="fca-scaffold",
28
- help="Fast Clean Architecture scaffolding tool for FastAPI projects",
37
+ help="""[bold blue]Fast Clean Architecture[/bold blue] is a scaffolding tool for FastAPI projects.
38
+
39
+ [bold]Quick Start:[/bold]
40
+ 1. Initialize a new project
41
+ [cyan]fca-scaffold init[/cyan]
42
+
43
+ 2. Create a system context
44
+ [cyan]fca-scaffold create-system-context admin[/cyan]
45
+
46
+ 3. Create a module in the admin system
47
+ [cyan]fca-scaffold create-module admin auth[/cyan]
48
+
49
+ 4. Create a component (e.g., entities, services, repositories)
50
+ [cyan]fca-scaffold create-component admin/auth/domain/entities Admin[/cyan]
51
+
52
+ [bold]Definitions:[/bold]
53
+ [yellow]System:[/yellow]
54
+ A bounded context representing a major business domain.
55
+ Examples: user_management, payment_processing
56
+
57
+ [yellow]Module:[/yellow]
58
+ A functional area within a system that groups related components.
59
+ Examples: auth, billing, notifications
60
+
61
+ [yellow]Component:[/yellow]
62
+ Individual code artifacts within Clean Architecture layers:
63
+
64
+ [dim]Domain:[/dim]
65
+ - entities
66
+ - repositories
67
+ - value_objects
68
+
69
+ [dim]Application:[/dim]
70
+ - services
71
+ - commands
72
+ - queries
73
+
74
+ [dim]Infrastructure:[/dim]
75
+ - models
76
+ - repositories
77
+ - external
78
+
79
+ [dim]Presentation:[/dim]
80
+ - api
81
+ - schemas
82
+
83
+ [bold]Get help for any command:[/bold]
84
+ [cyan]fca-scaffold [COMMAND] --help[/cyan]
85
+
86
+ [bold]Examples:[/bold]
87
+ Initialize a project with a description:
88
+ [dim]fca-scaffold init my-project --description "My FastAPI project"[/dim]
89
+
90
+ Check scaffold status:
91
+ [dim]fca-scaffold status[/dim]
92
+
93
+ Show current config:
94
+ [dim]fca-scaffold config show[/dim]
95
+ """,
29
96
  rich_markup_mode="rich",
30
97
  )
31
98
 
@@ -44,7 +111,7 @@ FORCE_OPTION = typer.Option(
44
111
  )
45
112
  VERBOSE_OPTION = typer.Option(False, "--verbose", "-v", help="Enable verbose output")
46
113
  CONFIG_PATH_OPTION = typer.Option(
47
- "fca-config.yaml", "--config", "-c", help="Path to configuration file"
114
+ "fca_config.yaml", "--config", "-c", help="Path to configuration file"
48
115
  )
49
116
 
50
117
 
@@ -61,7 +128,7 @@ def get_config_path(config_file: str) -> Path:
61
128
  return config_path
62
129
 
63
130
 
64
- def handle_error(error: Exception, verbose: bool = False) -> None:
131
+ def handle_error(error: Exception, verbose: bool = False) -> NoReturn:
65
132
  """Handle and display errors consistently."""
66
133
  if isinstance(error, FastCleanArchitectureError):
67
134
  console.print(f"[red]Error:[/red] {error}")
@@ -76,16 +143,34 @@ def handle_error(error: Exception, verbose: bool = False) -> None:
76
143
 
77
144
  @app.command()
78
145
  def init(
79
- name: Optional[str] = typer.Argument(None, help="Project name"),
146
+ name: Optional[str] = typer.Argument(
147
+ None, help="Project name (will be sanitized for Python compatibility)"
148
+ ),
80
149
  description: Optional[str] = typer.Option(
81
- None, "--description", "--desc", help="Project description"
150
+ None, "--description", "--desc", help="Project description for documentation"
151
+ ),
152
+ version: Optional[str] = typer.Option(
153
+ "0.1.0", "--version", help="Initial project version (semantic versioning)"
82
154
  ),
83
- version: Optional[str] = typer.Option("0.1.0", "--version", help="Project version"),
84
155
  config_file: str = CONFIG_PATH_OPTION,
85
156
  force: bool = FORCE_OPTION,
86
157
  verbose: bool = VERBOSE_OPTION,
87
158
  ) -> None:
88
- """Initialize a new Fast Clean Architecture project."""
159
+ """Initialize a new Fast Clean Architecture project.
160
+
161
+ Creates a new FCA project with configuration file and basic directory structure.
162
+ If no name is provided, you'll be prompted to enter one.
163
+
164
+ [bold]Examples:[/bold]
165
+ [cyan]fca-scaffold init[/cyan] # Interactive mode
166
+ [cyan]fca-scaffold init my-api[/cyan] # With project name
167
+ [cyan]fca-scaffold init my-api --desc "User management API"[/cyan] # With description
168
+ [cyan]fca-scaffold init my-api --version 1.0.0 --force[/cyan] # Overwrite existing
169
+
170
+ [bold]What it creates:[/bold]
171
+ • [dim]fca_config.yaml[/dim] - Project configuration file
172
+ • [dim]systems/[/dim] - Directory for system contexts
173
+ """
89
174
  try:
90
175
  project_root = get_project_root()
91
176
  config_path = get_config_path(config_file)
@@ -139,16 +224,35 @@ def init(
139
224
 
140
225
  @app.command()
141
226
  def create_system_context(
142
- name: str = typer.Argument(..., help="System context name"),
227
+ name: str = typer.Argument(
228
+ ..., help="System context name (e.g., admin, customer, settings)"
229
+ ),
143
230
  description: Optional[str] = typer.Option(
144
- None, "--description", "--desc", help="System description"
231
+ None, "--description", "--desc", help="Description of what this system handles"
145
232
  ),
146
233
  config_file: str = CONFIG_PATH_OPTION,
147
234
  dry_run: bool = DRY_RUN_OPTION,
148
235
  force: bool = FORCE_OPTION,
149
236
  verbose: bool = VERBOSE_OPTION,
150
237
  ) -> None:
151
- """Create a new system context."""
238
+ """Create a new system context.
239
+
240
+ A system context represents a bounded context in your domain, containing related
241
+ business functionality or aimed at different operational context such as admin, customer, settings. Each system can contain multiple modules.
242
+
243
+ [bold]Examples:[/bold]
244
+ [cyan]fca-scaffold create-system-context admin[/cyan]
245
+ [cyan]fca-scaffold create-system-context customer --desc "Customer System"[/cyan]
246
+ [cyan]fca-scaffold create-system-context settings --dry-run[/cyan] # Preview only
247
+
248
+ [bold]What it creates:[/bold]
249
+ • [dim]systems/[SYSTEM_NAME]/[/dim] - System directory
250
+ • [dim]systems/[SYSTEM_NAME]/__init__.py[/dim] - Python package file
251
+ • Updates [dim]fca_config.yaml[/dim] with system information
252
+
253
+ [bold]Next steps:[/bold]
254
+ Create modules with: [cyan]fca-scaffold create-module [SYSTEM_NAME] [MODULE_NAME][/cyan]
255
+ """
152
256
  try:
153
257
  project_root = get_project_root()
154
258
  config_path = get_config_path(config_file)
@@ -183,17 +287,41 @@ def create_system_context(
183
287
 
184
288
  @app.command()
185
289
  def create_module(
186
- system_name: str = typer.Argument(..., help="System context name"),
187
- module_name: str = typer.Argument(..., help="Module name"),
290
+ system_name: str = typer.Argument(..., help="Existing system context name"),
291
+ module_name: str = typer.Argument(
292
+ ..., help="Module name (e.g., authentication, user_profile)"
293
+ ),
188
294
  description: Optional[str] = typer.Option(
189
- None, "--description", "--desc", help="Module description"
295
+ None, "--description", "--desc", help="Description of module functionality"
190
296
  ),
191
297
  config_file: str = CONFIG_PATH_OPTION,
192
298
  dry_run: bool = DRY_RUN_OPTION,
193
299
  force: bool = FORCE_OPTION,
194
300
  verbose: bool = VERBOSE_OPTION,
195
301
  ) -> None:
196
- """Create a new module within a system context."""
302
+ """Create a new module within a system context.
303
+
304
+ Modules organize related functionality within a system context, following
305
+ Clean Architecture layers (domain, application, infrastructure, presentation).
306
+
307
+ [bold]Examples:[/bold]
308
+ [cyan]fca-scaffold create-module admin authentication[/cyan]
309
+ [cyan]fca-scaffold create-module customer payment_processing --desc "Payment processing logic"[/cyan]
310
+ [cyan]fca-scaffold create-module settings notification_settings --dry-run[/cyan] # Preview only
311
+
312
+ [bold]What it creates:[/bold]
313
+ • [dim]systems/[SYSTEM_NAME]/modules/[MODULE_NAME]/[/dim] - Module directory
314
+ • [dim]systems/[SYSTEM_NAME]/modules/[MODULE_NAME]/__init__.py[/dim] - Package file
315
+ • [dim]systems/[SYSTEM_NAME]/modules/[MODULE_NAME]/[MODULE_NAME]_module_api.py[/dim] - Module API file
316
+ • [dim]systems/[SYSTEM_NAME]/modules/[MODULE_NAME]/domain/[/dim] - Domain layer
317
+ • [dim]systems/[SYSTEM_NAME]/modules/[MODULE_NAME]/application/[/dim] - Application layer
318
+ • [dim]systems/[SYSTEM_NAME]/modules/[MODULE_NAME]/infrastructure/[/dim] - Infrastructure layer
319
+ • [dim]systems/[SYSTEM_NAME]/modules/[MODULE_NAME]/presentation/[/dim] - Presentation layer
320
+ • Updates [dim]fca_config.yaml[/dim] with module information
321
+
322
+ [bold]Next steps:[/bold]
323
+ Create components with: [cyan]fca-scaffold create-component [SYSTEM_NAME]/[MODULE_NAME]/[LAYER]/[TYPE] [COMPONENT_NAME][/cyan]
324
+ """
197
325
  try:
198
326
  project_root = get_project_root()
199
327
  config_path = get_config_path(config_file)
@@ -234,9 +362,12 @@ def create_module(
234
362
  @app.command()
235
363
  def create_component(
236
364
  location: str = typer.Argument(
237
- ..., help="Component location (system/module/layer/type)"
365
+ ...,
366
+ help="Component location: system/module/layer/type (e.g., user_management/auth/domain/entities)",
367
+ ),
368
+ name: str = typer.Argument(
369
+ ..., help="Component name (e.g., User, AuthService, UserRepository)"
238
370
  ),
239
- name: str = typer.Argument(..., help="Component name"),
240
371
  config_file: str = CONFIG_PATH_OPTION,
241
372
  dry_run: bool = DRY_RUN_OPTION,
242
373
  force: bool = FORCE_OPTION,
@@ -244,10 +375,54 @@ def create_component(
244
375
  ) -> None:
245
376
  """Create a new component.
246
377
 
247
- Location format: system_name/module_name/layer/component_type
248
- Example: user_management/authentication/domain/entities
378
+ Creates components following Clean Architecture patterns. Components are generated
379
+ from templates and placed in the appropriate layer directory.
380
+
381
+ [bold]Location format:[/bold] [cyan]system_name/module_name/layer/component_type[/cyan]
382
+
383
+ [bold]Available layers and component types:[/bold]
384
+ [yellow]domain/[/yellow]
385
+ • [cyan]entities[/cyan] - Domain entities (business objects)
386
+ • [cyan]value_objects[/cyan] - Value objects (immutable data)
387
+ • [cyan]repositories[/cyan] - Repository interfaces
388
+ • [cyan]services[/cyan] - Domain services
389
+
390
+ [yellow]application/[/yellow]
391
+ • [cyan]commands[/cyan] - Command handlers (CQRS)
392
+ • [cyan]queries[/cyan] - Query handlers (CQRS)
393
+ • [cyan]services[/cyan] - Application services
394
+
395
+ [yellow]infrastructure/[/yellow]
396
+ • [cyan]models[/cyan] - Database models and schemas
397
+ • [cyan]repositories[/cyan] - Repository implementations
398
+ • [cyan]external[/cyan] - External service adapters
399
+
400
+ [yellow]presentation/[/yellow]
401
+ • [cyan]api[/cyan] - API endpoints/controllers
402
+ • [cyan]schemas[/cyan] - Request/response schemas
403
+
404
+ [bold]Examples:[/bold]
405
+ [cyan]fca-scaffold create-component admin/auth/domain/entities User[/cyan]
406
+ [cyan]fca-scaffold create-component admin/auth/application/commands CreateUser[/cyan]
407
+ [cyan]fca-scaffold create-component customer/payment_processing/infrastructure/repositories PaymentProcessingRepository[/cyan]
408
+ [cyan]fca-scaffold create-component settings/notification_settings/presentation/api NotificationSettingsAPI[/cyan]
409
+
410
+ [bold]What it creates:[/bold]
411
+ • Python file with component implementation
412
+ • Imports and dependencies based on component type
413
+ • Updates [dim]fca_config.yaml[/dim] with component information
249
414
  """
250
415
  try:
416
+ # Log CLI command start
417
+ logger.info(
418
+ "CLI create_component command started",
419
+ operation="cli_create_component",
420
+ location=location,
421
+ name=name,
422
+ dry_run=dry_run,
423
+ force=force,
424
+ )
425
+
251
426
  project_root = get_project_root()
252
427
  config_path = get_config_path(config_file)
253
428
 
@@ -274,12 +449,18 @@ def create_component(
274
449
  ):
275
450
  raise ValidationError("Invalid names provided")
276
451
 
277
- # Initialize generators
452
+ # Initialize generators using factory pattern
278
453
  config_updater = ConfigUpdater(config_path, console)
279
- component_generator = ComponentGenerator(config_updater.config, console)
454
+ generator_factory = create_generator_factory(config_updater.config, console)
455
+ component_generator = generator_factory.create_generator("component")
456
+
457
+ # Cast to ComponentGeneratorProtocol for type safety
458
+ from .generators import ComponentGeneratorProtocol
459
+
460
+ component_gen = cast(ComponentGeneratorProtocol, component_generator)
280
461
 
281
462
  # Create component
282
- file_path = component_generator.create_component(
463
+ file_path = component_gen.create_component(
283
464
  base_path=project_root,
284
465
  system_name=sanitized_system,
285
466
  module_name=sanitized_module,
@@ -305,19 +486,87 @@ def create_component(
305
486
  f"[green]✅ Component '{sanitized_name}' created at {location}![/green]"
306
487
  )
307
488
 
489
+ # Log successful completion
490
+ logger.info(
491
+ "CLI create_component command completed successfully",
492
+ operation="cli_create_component",
493
+ component_name=sanitized_name,
494
+ location=location,
495
+ file_path=str(file_path) if not dry_run else None,
496
+ )
497
+
498
+ # Track component creation for analytics
499
+ if not dry_run:
500
+ track_component_creation(
501
+ system_name=sanitized_system,
502
+ module_name=sanitized_module,
503
+ layer=layer,
504
+ component_type=component_type,
505
+ component_name=sanitized_name,
506
+ )
507
+
308
508
  except Exception as e:
509
+ # Log CLI error and track it
510
+ logger.error(
511
+ "CLI create_component command failed",
512
+ operation="cli_create_component",
513
+ error=str(e),
514
+ error_type=type(e).__name__,
515
+ location=location,
516
+ name=name,
517
+ )
518
+
519
+ # Track the error for analytics
520
+ track_error(
521
+ error=e,
522
+ context={
523
+ "command": "create_component",
524
+ "location": location,
525
+ "name": name,
526
+ "dry_run": dry_run,
527
+ "force": force,
528
+ },
529
+ operation="cli_create_component",
530
+ )
531
+
309
532
  handle_error(e, verbose)
310
533
 
311
534
 
312
535
  @app.command()
313
536
  def batch_create(
314
- spec_file: str = typer.Argument(..., help="YAML specification file"),
537
+ spec_file: str = typer.Argument(
538
+ ..., help="Path to YAML specification file (see examples/components_spec.yaml)"
539
+ ),
315
540
  config_file: str = CONFIG_PATH_OPTION,
316
541
  dry_run: bool = DRY_RUN_OPTION,
317
542
  force: bool = FORCE_OPTION,
318
543
  verbose: bool = VERBOSE_OPTION,
319
544
  ) -> None:
320
- """Create multiple components from a YAML specification file."""
545
+ """Create multiple components from a YAML specification file.
546
+
547
+ Batch creation allows you to define multiple systems, modules, and components
548
+ in a single YAML file and create them all at once.
549
+
550
+ [bold]Examples:[/bold]
551
+ [cyan]fca-scaffold batch-create components_spec.yaml[/cyan]
552
+ [cyan]fca-scaffold batch-create my-spec.yaml --dry-run[/cyan] # Preview only
553
+
554
+ [bold]Specification file format:[/bold]
555
+ [dim]systems:[/dim]
556
+ [dim] - name: admin[/dim]
557
+ [dim] modules:[/dim]
558
+ [dim] - name: authentication[/dim]
559
+ [dim] components:[/dim]
560
+ [dim] domain:[/dim]
561
+ [dim] entities: [AdminUser, AdminRole][/dim]
562
+ [dim] value_objects: [AdminEmail, AdminPassword][/dim]
563
+ [dim] repositories: [AdminUserRepository][/dim]
564
+ [dim] application:[/dim]
565
+ [dim] commands: [CreateAdminUser, UpdateAdminUser][/dim]
566
+
567
+ [bold]See also:[/bold]
568
+ Check [cyan]examples/components_spec.yaml[/cyan] for a complete example
569
+ """
321
570
  try:
322
571
  import yaml
323
572
 
@@ -332,9 +581,10 @@ def batch_create(
332
581
  with open(spec_path, "r", encoding="utf-8") as f:
333
582
  spec = yaml.safe_load(f)
334
583
 
335
- # Initialize generators
584
+ # Initialize generators using factory pattern
336
585
  config_updater = ConfigUpdater(config_path, console)
337
- component_generator = ComponentGenerator(config_updater.config, console)
586
+ generator_factory = create_generator_factory(config_updater.config, console)
587
+ component_generator = generator_factory.create_generator("component")
338
588
 
339
589
  # Process specification
340
590
  for system_spec in spec.get("systems", []):
@@ -344,8 +594,13 @@ def batch_create(
344
594
  module_name = module_spec["name"]
345
595
  components_spec = module_spec.get("components", {})
346
596
 
597
+ # Cast to ComponentGeneratorProtocol for type safety
598
+ from .protocols import ComponentGeneratorProtocol
599
+
600
+ component_gen = cast(ComponentGeneratorProtocol, component_generator)
601
+
347
602
  # Create components
348
- component_generator.create_multiple_components(
603
+ component_gen.create_multiple_components(
349
604
  base_path=project_root,
350
605
  system_name=system_name,
351
606
  module_name=module_name,
@@ -365,7 +620,22 @@ def status(
365
620
  config_file: str = CONFIG_PATH_OPTION,
366
621
  verbose: bool = VERBOSE_OPTION,
367
622
  ) -> None:
368
- """Show project status and configuration summary."""
623
+ """Show project status and configuration summary.
624
+
625
+ Displays an overview of your FCA project including systems, modules,
626
+ and recent activity. Useful for understanding project structure.
627
+
628
+ [bold]Examples:[/bold]
629
+ [cyan]fca-scaffold status[/cyan] # Show project overview
630
+ [cyan]fca-scaffold status --verbose[/cyan] # Detailed information
631
+ [cyan]fca-scaffold status -c my-config.yaml[/cyan] # Custom config file
632
+
633
+ [bold]Information shown:[/bold]
634
+ • Project name, version, and timestamps
635
+ • Systems and module counts
636
+ • Recent creation/update dates
637
+ • Configuration file location
638
+ """
369
639
  try:
370
640
  config_path = get_config_path(config_file)
371
641
 
@@ -417,11 +687,31 @@ def status(
417
687
 
418
688
  @app.command()
419
689
  def config(
420
- action: str = typer.Argument(..., help="Action: show, edit, validate"),
690
+ action: str = typer.Argument(..., help="Action to perform: show, edit, validate"),
421
691
  config_file: str = CONFIG_PATH_OPTION,
422
692
  verbose: bool = VERBOSE_OPTION,
423
693
  ) -> None:
424
- """Manage project configuration."""
694
+ """Manage project configuration.
695
+
696
+ Provides tools to view, edit, and validate your FCA project configuration.
697
+ The configuration file tracks all systems, modules, and components.
698
+
699
+ [bold]Available actions:[/bold]
700
+ [cyan]show[/cyan] - Display configuration file contents with syntax highlighting
701
+ [cyan]edit[/cyan] - Get instructions for editing the configuration
702
+ [cyan]validate[/cyan] - Check if configuration file is valid YAML and structure
703
+
704
+ [bold]Examples:[/bold]
705
+ [cyan]fca-scaffold config show[/cyan] # View current config
706
+ [cyan]fca-scaffold config validate[/cyan] # Check config validity
707
+ [cyan]fca-scaffold config show -c my-config.yaml[/cyan] # Custom config file
708
+
709
+ [bold]Configuration structure:[/bold]
710
+ • [dim]project[/dim] - Project metadata (name, version, description)
711
+ • [dim]systems[/dim] - System contexts and their modules
712
+ • [dim]components[/dim] - Generated components and their locations
713
+ • [dim]timestamps[/dim] - Creation and modification dates
714
+ """
425
715
  try:
426
716
  config_path = get_config_path(config_file)
427
717
 
@@ -461,10 +751,100 @@ def config(
461
751
  handle_error(e, verbose)
462
752
 
463
753
 
754
+ @app.command()
755
+ def help_guide() -> None:
756
+ """Show comprehensive help and quick reference guide.
757
+
758
+ Displays a detailed guide covering all commands, common workflows,
759
+ and best practices for using Fast Clean Architecture.
760
+
761
+ [bold]Example:[/bold]
762
+ [cyan]fca-scaffold help-guide[/cyan]
763
+
764
+ [bold]Covers:[/bold]
765
+ • Complete workflow from project init to component creation
766
+ • Command reference with examples
767
+ • Clean Architecture layer explanations
768
+ • Best practices and tips
769
+ """
770
+ console.print(
771
+ Panel.fit(
772
+ "[bold blue]Fast Clean Architecture - Complete Guide[/bold blue]\n\n"
773
+ "[bold yellow]📖 Key Definitions:[/bold yellow]\n\n"
774
+ "[yellow]System:[/yellow]\n"
775
+ " A bounded context representing a major business domain.\n"
776
+ " Examples: admin, customer, settings\n\n"
777
+ "[yellow]Module:[/yellow]\n"
778
+ " A functional area within a system that groups related components.\n"
779
+ " Examples: auth, billing, notifications, reporting\n\n"
780
+ "[yellow]Component:[/yellow]\n"
781
+ " Individual code artifacts within Clean Architecture layers:\n\n"
782
+ " [dim]Domain:[/dim]\n"
783
+ " - entities\n"
784
+ " - repositories\n"
785
+ " - value_objects\n\n"
786
+ " [dim]Application:[/dim]\n"
787
+ " - services\n"
788
+ " - commands\n"
789
+ " - queries\n\n"
790
+ " [dim]Infrastructure:[/dim]\n"
791
+ " - models\n"
792
+ " - repositories\n"
793
+ " - external\n\n"
794
+ " [dim]Presentation:[/dim]\n"
795
+ " - api\n"
796
+ " - schemas\n\n"
797
+ "[bold yellow]🚀 Quick Start Workflow:[/bold yellow]\n"
798
+ "1. [cyan]fca-scaffold init my-project[/cyan] - Initialize project\n"
799
+ "2. [cyan]fca-scaffold create-system-context admin[/cyan] - Create system\n"
800
+ "3. [cyan]fca-scaffold create-module admin auth[/cyan] - Create module\n"
801
+ "4. [cyan]fca-scaffold create-component admin/auth/domain/entities AdminUser[/cyan] - Create any component type\n\n"
802
+ "[bold yellow]📋 Available Commands:[/bold yellow]\n"
803
+ "• [cyan]init[/cyan] - Initialize new project\n"
804
+ "• [cyan]create-system-context[/cyan] - Create system (bounded context)\n"
805
+ "• [cyan]create-module[/cyan] - Create module within system\n"
806
+ "• [cyan]create-component[/cyan] - Create individual components (entities, services, repositories, etc.)\n"
807
+ "• [cyan]batch-create[/cyan] - Create multiple components from YAML\n"
808
+ "• [cyan]status[/cyan] - Show project overview\n"
809
+ "• [cyan]config[/cyan] - Manage configuration\n"
810
+ "• [cyan]version[/cyan] - Show version info\n\n"
811
+ "[bold yellow]🏗️ Clean Architecture Layers & Components:[/bold yellow]\n"
812
+ "• [yellow]domain/[/yellow] - Business logic\n"
813
+ " ◦ entities, repositories, value_objects\n"
814
+ "• [yellow]application/[/yellow] - Use cases\n"
815
+ " ◦ services, commands, queries\n"
816
+ "• [yellow]infrastructure/[/yellow] - External concerns\n"
817
+ " ◦ models, repositories, external\n"
818
+ "• [yellow]presentation/[/yellow] - User interface\n"
819
+ " ◦ api, schemas\n\n"
820
+ "[bold yellow]💡 Pro Tips:[/bold yellow]\n"
821
+ "• Use [cyan]--dry-run[/cyan] to preview changes\n"
822
+ "• Use [cyan]--help[/cyan] with any command for detailed info\n"
823
+ "• Check [cyan]fca-scaffold status[/cyan] to see project structure\n"
824
+ "• Validate config with [cyan]fca-scaffold config validate[/cyan]\n\n"
825
+ "[bold yellow]📖 For detailed help on any command:[/bold yellow]\n"
826
+ "[cyan]fca-scaffold [COMMAND] --help[/cyan]",
827
+ title="📚 Fast Clean Architecture - Help Guide",
828
+ )
829
+ )
830
+
831
+
464
832
  @app.command()
465
833
  def version() -> None:
466
- """Show version information."""
467
- from . import __version__, __author__
834
+ """Show version information.
835
+
836
+ Displays the current version of Fast Clean Architecture scaffolding tool
837
+ along with author information.
838
+
839
+ [bold]Example:[/bold]
840
+ [cyan]fca-scaffold version[/cyan]
841
+
842
+ [bold]Useful for:[/bold]
843
+ • Checking which version you're running
844
+ • Bug reports and support requests
845
+ • Ensuring compatibility with documentation
846
+ """
847
+ from . import __author__, __version__
468
848
 
469
849
  console.print(
470
850
  Panel.fit(
@@ -476,5 +856,137 @@ def version() -> None:
476
856
  )
477
857
 
478
858
 
859
+ @app.command()
860
+ def system_status(
861
+ verbose: bool = VERBOSE_OPTION,
862
+ ) -> None:
863
+ """Show system status, health, and usage analytics.
864
+
865
+ Displays comprehensive information about:
866
+ - System health and resource usage
867
+ - Error tracking summary
868
+ - Usage analytics and productivity metrics
869
+
870
+ [bold]Examples:[/bold]
871
+ [cyan]fca-scaffold system-status[/cyan]
872
+ [cyan]fca-scaffold system-status --verbose[/cyan]
873
+ """
874
+ try:
875
+ from .analytics import get_analytics
876
+ from .error_tracking import get_error_tracker
877
+ from .health import get_health_monitor
878
+
879
+ console.print("\n[bold blue]📊 Fast Clean Architecture Status[/bold blue]\n")
880
+
881
+ # Health Status
882
+ console.print("[bold yellow]🏥 System Health[/bold yellow]")
883
+ health_monitor = get_health_monitor()
884
+ health_data = health_monitor.get_system_health()
885
+
886
+ if "error" in health_data:
887
+ console.print(f"[red]❌ Health check failed: {health_data['error']}[/red]")
888
+ else:
889
+ process_data = health_data.get("process", {})
890
+ system_data = health_data.get("system", {})
891
+
892
+ console.print(
893
+ f" • Memory Usage: {process_data.get('memory_rss_mb', 0):.1f} MB ({process_data.get('memory_percent', 0):.1f}%)"
894
+ )
895
+ console.print(f" • CPU Usage: {process_data.get('cpu_percent', 0):.1f}%")
896
+ console.print(
897
+ f" • System Memory: {system_data.get('memory_used_percent', 0):.1f}% used"
898
+ )
899
+ console.print(
900
+ f" • Disk Space: {system_data.get('disk_used_percent', 0):.1f}% used"
901
+ )
902
+ console.print(
903
+ f" • Uptime: {health_data.get('uptime_seconds', 0):.1f} seconds"
904
+ )
905
+
906
+ # Error Tracking
907
+ console.print("\n[bold yellow]🐛 Error Tracking[/bold yellow]")
908
+ error_tracker = get_error_tracker()
909
+ error_summary = error_tracker.get_error_summary()
910
+
911
+ console.print(f" • Total Errors: {error_summary.get('total_errors', 0)}")
912
+ console.print(f" • Unique Errors: {error_summary.get('unique_errors', 0)}")
913
+
914
+ if error_summary.get("most_common_errors"):
915
+ console.print(" • Most Common Errors:")
916
+ for error_info in error_summary["most_common_errors"][:3]:
917
+ console.print(
918
+ f" - {error_info['signature']}: {error_info['count']} times"
919
+ )
920
+
921
+ # Usage Analytics
922
+ console.print("\n[bold yellow]📈 Usage Analytics[/bold yellow]")
923
+ analytics = get_analytics()
924
+ usage_summary = analytics.get_usage_summary()
925
+ productivity = analytics.get_productivity_metrics()
926
+
927
+ session_data = usage_summary.get("session", {})
928
+ console.print(
929
+ f" • Session Duration: {session_data.get('duration_seconds', 0):.1f} seconds"
930
+ )
931
+ console.print(f" • Total Commands: {session_data.get('total_commands', 0)}")
932
+ console.print(
933
+ f" • Components Created: {productivity.get('components_created', 0)}"
934
+ )
935
+ console.print(
936
+ f" • Components/Hour: {productivity.get('components_per_hour', 0):.1f}"
937
+ )
938
+
939
+ if usage_summary.get("commands"):
940
+ console.print(" • Command Usage:")
941
+ for command, count in list(usage_summary["commands"].items())[:3]:
942
+ console.print(f" - {command}: {count} times")
943
+
944
+ if usage_summary.get("component_types"):
945
+ console.print(" • Popular Component Types:")
946
+ for comp_type, count in list(usage_summary["component_types"].items())[:3]:
947
+ console.print(f" - {comp_type}: {count} times")
948
+
949
+ if verbose:
950
+ # Show detailed information
951
+ console.print("\n[bold yellow]🔍 Detailed Information[/bold yellow]")
952
+
953
+ if usage_summary.get("layers"):
954
+ console.print(" • Layer Usage:")
955
+ for layer, count in usage_summary["layers"].items():
956
+ console.print(f" - {layer}: {count} times")
957
+
958
+ if usage_summary.get("systems"):
959
+ console.print(" • System Usage:")
960
+ for system, count in usage_summary["systems"].items():
961
+ console.print(f" - {system}: {count} times")
962
+
963
+ if usage_summary.get("performance"):
964
+ console.print(" • Performance Metrics:")
965
+ for command, perf in usage_summary["performance"].items():
966
+ console.print(
967
+ f" - {command}: avg {perf['average_ms']}ms (min: {perf['min_ms']}ms, max: {perf['max_ms']}ms)"
968
+ )
969
+
970
+ console.print("\n[green]✅ Status check completed[/green]")
971
+
972
+ # Log the status check
973
+ logger.info(
974
+ "System status command executed",
975
+ operation="cli_system_status",
976
+ verbose=verbose,
977
+ )
978
+
979
+ except Exception as e:
980
+ logger.error(
981
+ "System status command failed",
982
+ operation="cli_system_status",
983
+ error=str(e),
984
+ error_type=type(e).__name__,
985
+ )
986
+ handle_error(e, verbose)
987
+
988
+
479
989
  if __name__ == "__main__":
990
+ # Ensure logging is configured
991
+ configure_logging()
480
992
  app()