fast-clean-architecture 1.0.0__py3-none-any.whl → 1.1.2__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 +5 -6
  2. fast_clean_architecture/analytics.py +260 -0
  3. fast_clean_architecture/cli.py +563 -46
  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.2.dist-info}/METADATA +131 -64
  23. fast_clean_architecture-1.1.2.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.2.dist-info}/WHEEL +0 -0
  26. {fast_clean_architecture-1.0.0.dist-info → fast_clean_architecture-1.1.2.dist-info}/entry_points.txt +0 -0
  27. {fast_clean_architecture-1.0.0.dist-info → fast_clean_architecture-1.1.2.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)
@@ -207,11 +335,23 @@ def create_module(
207
335
  if not validate_python_identifier(sanitized_module):
208
336
  raise ValidationError(f"Invalid module name: {module_name}")
209
337
 
210
- # Initialize generators
338
+ # Initialize config updater for validation
211
339
  config_updater = ConfigUpdater(config_path, console)
340
+
341
+ # Validate system exists BEFORE creating any directory structure
342
+ if sanitized_system not in config_updater.config.project.systems:
343
+ raise ValidationError(
344
+ f"System '{sanitized_system}' not found.\n\n"
345
+ f"To create the module, first create the system:\n"
346
+ f' fca-scaffold create-system-context {sanitized_system} --description "[SYSTEM_DESCRIPTION]"\n\n'
347
+ f"Then create your module:\n"
348
+ f" fca-scaffold create-module {sanitized_system} {sanitized_module}"
349
+ )
350
+
351
+ # Initialize package generator
212
352
  package_generator = PackageGenerator(console)
213
353
 
214
- # Create module structure
354
+ # Create module structure (only after validation passes)
215
355
  package_generator.create_module_structure(
216
356
  base_path=project_root,
217
357
  system_name=sanitized_system,
@@ -220,7 +360,7 @@ def create_module(
220
360
  )
221
361
 
222
362
  if not dry_run:
223
- # Update configuration
363
+ # Update configuration (system existence already validated)
224
364
  config_updater.add_module(sanitized_system, sanitized_module, description)
225
365
 
226
366
  console.print(
@@ -234,9 +374,12 @@ def create_module(
234
374
  @app.command()
235
375
  def create_component(
236
376
  location: str = typer.Argument(
237
- ..., help="Component location (system/module/layer/type)"
377
+ ...,
378
+ help="Component location: system/module/layer/type (e.g., user_management/auth/domain/entities)",
379
+ ),
380
+ name: str = typer.Argument(
381
+ ..., help="Component name (e.g., User, AuthService, UserRepository)"
238
382
  ),
239
- name: str = typer.Argument(..., help="Component name"),
240
383
  config_file: str = CONFIG_PATH_OPTION,
241
384
  dry_run: bool = DRY_RUN_OPTION,
242
385
  force: bool = FORCE_OPTION,
@@ -244,10 +387,54 @@ def create_component(
244
387
  ) -> None:
245
388
  """Create a new component.
246
389
 
247
- Location format: system_name/module_name/layer/component_type
248
- Example: user_management/authentication/domain/entities
390
+ Creates components following Clean Architecture patterns. Components are generated
391
+ from templates and placed in the appropriate layer directory.
392
+
393
+ [bold]Location format:[/bold] [cyan]system_name/module_name/layer/component_type[/cyan]
394
+
395
+ [bold]Available layers and component types:[/bold]
396
+ [yellow]domain/[/yellow]
397
+ • [cyan]entities[/cyan] - Domain entities (business objects)
398
+ • [cyan]value_objects[/cyan] - Value objects (immutable data)
399
+ • [cyan]repositories[/cyan] - Repository interfaces
400
+ • [cyan]services[/cyan] - Domain services
401
+
402
+ [yellow]application/[/yellow]
403
+ • [cyan]commands[/cyan] - Command handlers (CQRS)
404
+ • [cyan]queries[/cyan] - Query handlers (CQRS)
405
+ • [cyan]services[/cyan] - Application services
406
+
407
+ [yellow]infrastructure/[/yellow]
408
+ • [cyan]models[/cyan] - Database models and schemas
409
+ • [cyan]repositories[/cyan] - Repository implementations
410
+ • [cyan]external[/cyan] - External service adapters
411
+
412
+ [yellow]presentation/[/yellow]
413
+ • [cyan]api[/cyan] - API endpoints/controllers
414
+ • [cyan]schemas[/cyan] - Request/response schemas
415
+
416
+ [bold]Examples:[/bold]
417
+ [cyan]fca-scaffold create-component admin/auth/domain/entities User[/cyan]
418
+ [cyan]fca-scaffold create-component admin/auth/application/commands CreateUser[/cyan]
419
+ [cyan]fca-scaffold create-component customer/payment_processing/infrastructure/repositories PaymentProcessingRepository[/cyan]
420
+ [cyan]fca-scaffold create-component settings/notification_settings/presentation/api NotificationSettingsAPI[/cyan]
421
+
422
+ [bold]What it creates:[/bold]
423
+ • Python file with component implementation
424
+ • Imports and dependencies based on component type
425
+ • Updates [dim]fca_config.yaml[/dim] with component information
249
426
  """
250
427
  try:
428
+ # Log CLI command start
429
+ logger.info(
430
+ "CLI create_component command started",
431
+ operation="cli_create_component",
432
+ location=location,
433
+ name=name,
434
+ dry_run=dry_run,
435
+ force=force,
436
+ )
437
+
251
438
  project_root = get_project_root()
252
439
  config_path = get_config_path(config_file)
253
440
 
@@ -274,12 +461,18 @@ def create_component(
274
461
  ):
275
462
  raise ValidationError("Invalid names provided")
276
463
 
277
- # Initialize generators
464
+ # Initialize generators using factory pattern
278
465
  config_updater = ConfigUpdater(config_path, console)
279
- component_generator = ComponentGenerator(config_updater.config, console)
466
+ generator_factory = create_generator_factory(config_updater.config, console)
467
+ component_generator = generator_factory.create_generator("component")
468
+
469
+ # Cast to ComponentGeneratorProtocol for type safety
470
+ from .generators import ComponentGeneratorProtocol
471
+
472
+ component_gen = cast(ComponentGeneratorProtocol, component_generator)
280
473
 
281
474
  # Create component
282
- file_path = component_generator.create_component(
475
+ file_path = component_gen.create_component(
283
476
  base_path=project_root,
284
477
  system_name=sanitized_system,
285
478
  module_name=sanitized_module,
@@ -305,19 +498,87 @@ def create_component(
305
498
  f"[green]✅ Component '{sanitized_name}' created at {location}![/green]"
306
499
  )
307
500
 
501
+ # Log successful completion
502
+ logger.info(
503
+ "CLI create_component command completed successfully",
504
+ operation="cli_create_component",
505
+ component_name=sanitized_name,
506
+ location=location,
507
+ file_path=str(file_path) if not dry_run else None,
508
+ )
509
+
510
+ # Track component creation for analytics
511
+ if not dry_run:
512
+ track_component_creation(
513
+ system_name=sanitized_system,
514
+ module_name=sanitized_module,
515
+ layer=layer,
516
+ component_type=component_type,
517
+ component_name=sanitized_name,
518
+ )
519
+
308
520
  except Exception as e:
521
+ # Log CLI error and track it
522
+ logger.error(
523
+ "CLI create_component command failed",
524
+ operation="cli_create_component",
525
+ error=str(e),
526
+ error_type=type(e).__name__,
527
+ location=location,
528
+ name=name,
529
+ )
530
+
531
+ # Track the error for analytics
532
+ track_error(
533
+ error=e,
534
+ context={
535
+ "command": "create_component",
536
+ "location": location,
537
+ "name": name,
538
+ "dry_run": dry_run,
539
+ "force": force,
540
+ },
541
+ operation="cli_create_component",
542
+ )
543
+
309
544
  handle_error(e, verbose)
310
545
 
311
546
 
312
547
  @app.command()
313
548
  def batch_create(
314
- spec_file: str = typer.Argument(..., help="YAML specification file"),
549
+ spec_file: str = typer.Argument(
550
+ ..., help="Path to YAML specification file (see examples/components_spec.yaml)"
551
+ ),
315
552
  config_file: str = CONFIG_PATH_OPTION,
316
553
  dry_run: bool = DRY_RUN_OPTION,
317
554
  force: bool = FORCE_OPTION,
318
555
  verbose: bool = VERBOSE_OPTION,
319
556
  ) -> None:
320
- """Create multiple components from a YAML specification file."""
557
+ """Create multiple components from a YAML specification file.
558
+
559
+ Batch creation allows you to define multiple systems, modules, and components
560
+ in a single YAML file and create them all at once.
561
+
562
+ [bold]Examples:[/bold]
563
+ [cyan]fca-scaffold batch-create components_spec.yaml[/cyan]
564
+ [cyan]fca-scaffold batch-create my-spec.yaml --dry-run[/cyan] # Preview only
565
+
566
+ [bold]Specification file format:[/bold]
567
+ [dim]systems:[/dim]
568
+ [dim] - name: admin[/dim]
569
+ [dim] modules:[/dim]
570
+ [dim] - name: authentication[/dim]
571
+ [dim] components:[/dim]
572
+ [dim] domain:[/dim]
573
+ [dim] entities: [AdminUser, AdminRole][/dim]
574
+ [dim] value_objects: [AdminEmail, AdminPassword][/dim]
575
+ [dim] repositories: [AdminUserRepository][/dim]
576
+ [dim] application:[/dim]
577
+ [dim] commands: [CreateAdminUser, UpdateAdminUser][/dim]
578
+
579
+ [bold]See also:[/bold]
580
+ Check [cyan]examples/components_spec.yaml[/cyan] for a complete example
581
+ """
321
582
  try:
322
583
  import yaml
323
584
 
@@ -332,9 +593,10 @@ def batch_create(
332
593
  with open(spec_path, "r", encoding="utf-8") as f:
333
594
  spec = yaml.safe_load(f)
334
595
 
335
- # Initialize generators
596
+ # Initialize generators using factory pattern
336
597
  config_updater = ConfigUpdater(config_path, console)
337
- component_generator = ComponentGenerator(config_updater.config, console)
598
+ generator_factory = create_generator_factory(config_updater.config, console)
599
+ component_generator = generator_factory.create_generator("component")
338
600
 
339
601
  # Process specification
340
602
  for system_spec in spec.get("systems", []):
@@ -344,8 +606,13 @@ def batch_create(
344
606
  module_name = module_spec["name"]
345
607
  components_spec = module_spec.get("components", {})
346
608
 
609
+ # Cast to ComponentGeneratorProtocol for type safety
610
+ from .protocols import ComponentGeneratorProtocol
611
+
612
+ component_gen = cast(ComponentGeneratorProtocol, component_generator)
613
+
347
614
  # Create components
348
- component_generator.create_multiple_components(
615
+ component_gen.create_multiple_components(
349
616
  base_path=project_root,
350
617
  system_name=system_name,
351
618
  module_name=module_name,
@@ -365,7 +632,22 @@ def status(
365
632
  config_file: str = CONFIG_PATH_OPTION,
366
633
  verbose: bool = VERBOSE_OPTION,
367
634
  ) -> None:
368
- """Show project status and configuration summary."""
635
+ """Show project status and configuration summary.
636
+
637
+ Displays an overview of your FCA project including systems, modules,
638
+ and recent activity. Useful for understanding project structure.
639
+
640
+ [bold]Examples:[/bold]
641
+ [cyan]fca-scaffold status[/cyan] # Show project overview
642
+ [cyan]fca-scaffold status --verbose[/cyan] # Detailed information
643
+ [cyan]fca-scaffold status -c my-config.yaml[/cyan] # Custom config file
644
+
645
+ [bold]Information shown:[/bold]
646
+ • Project name, version, and timestamps
647
+ • Systems and module counts
648
+ • Recent creation/update dates
649
+ • Configuration file location
650
+ """
369
651
  try:
370
652
  config_path = get_config_path(config_file)
371
653
 
@@ -417,11 +699,31 @@ def status(
417
699
 
418
700
  @app.command()
419
701
  def config(
420
- action: str = typer.Argument(..., help="Action: show, edit, validate"),
702
+ action: str = typer.Argument(..., help="Action to perform: show, edit, validate"),
421
703
  config_file: str = CONFIG_PATH_OPTION,
422
704
  verbose: bool = VERBOSE_OPTION,
423
705
  ) -> None:
424
- """Manage project configuration."""
706
+ """Manage project configuration.
707
+
708
+ Provides tools to view, edit, and validate your FCA project configuration.
709
+ The configuration file tracks all systems, modules, and components.
710
+
711
+ [bold]Available actions:[/bold]
712
+ [cyan]show[/cyan] - Display configuration file contents with syntax highlighting
713
+ [cyan]edit[/cyan] - Get instructions for editing the configuration
714
+ [cyan]validate[/cyan] - Check if configuration file is valid YAML and structure
715
+
716
+ [bold]Examples:[/bold]
717
+ [cyan]fca-scaffold config show[/cyan] # View current config
718
+ [cyan]fca-scaffold config validate[/cyan] # Check config validity
719
+ [cyan]fca-scaffold config show -c my-config.yaml[/cyan] # Custom config file
720
+
721
+ [bold]Configuration structure:[/bold]
722
+ • [dim]project[/dim] - Project metadata (name, version, description)
723
+ • [dim]systems[/dim] - System contexts and their modules
724
+ • [dim]components[/dim] - Generated components and their locations
725
+ • [dim]timestamps[/dim] - Creation and modification dates
726
+ """
425
727
  try:
426
728
  config_path = get_config_path(config_file)
427
729
 
@@ -461,10 +763,100 @@ def config(
461
763
  handle_error(e, verbose)
462
764
 
463
765
 
766
+ @app.command()
767
+ def help_guide() -> None:
768
+ """Show comprehensive help and quick reference guide.
769
+
770
+ Displays a detailed guide covering all commands, common workflows,
771
+ and best practices for using Fast Clean Architecture.
772
+
773
+ [bold]Example:[/bold]
774
+ [cyan]fca-scaffold help-guide[/cyan]
775
+
776
+ [bold]Covers:[/bold]
777
+ • Complete workflow from project init to component creation
778
+ • Command reference with examples
779
+ • Clean Architecture layer explanations
780
+ • Best practices and tips
781
+ """
782
+ console.print(
783
+ Panel.fit(
784
+ "[bold blue]Fast Clean Architecture - Complete Guide[/bold blue]\n\n"
785
+ "[bold yellow]📖 Key Definitions:[/bold yellow]\n\n"
786
+ "[yellow]System:[/yellow]\n"
787
+ " A bounded context representing a major business domain.\n"
788
+ " Examples: admin, customer, settings\n\n"
789
+ "[yellow]Module:[/yellow]\n"
790
+ " A functional area within a system that groups related components.\n"
791
+ " Examples: auth, billing, notifications, reporting\n\n"
792
+ "[yellow]Component:[/yellow]\n"
793
+ " Individual code artifacts within Clean Architecture layers:\n\n"
794
+ " [dim]Domain:[/dim]\n"
795
+ " - entities\n"
796
+ " - repositories\n"
797
+ " - value_objects\n\n"
798
+ " [dim]Application:[/dim]\n"
799
+ " - services\n"
800
+ " - commands\n"
801
+ " - queries\n\n"
802
+ " [dim]Infrastructure:[/dim]\n"
803
+ " - models\n"
804
+ " - repositories\n"
805
+ " - external\n\n"
806
+ " [dim]Presentation:[/dim]\n"
807
+ " - api\n"
808
+ " - schemas\n\n"
809
+ "[bold yellow]🚀 Quick Start Workflow:[/bold yellow]\n"
810
+ "1. [cyan]fca-scaffold init my-project[/cyan] - Initialize project\n"
811
+ "2. [cyan]fca-scaffold create-system-context admin[/cyan] - Create system\n"
812
+ "3. [cyan]fca-scaffold create-module admin auth[/cyan] - Create module\n"
813
+ "4. [cyan]fca-scaffold create-component admin/auth/domain/entities AdminUser[/cyan] - Create any component type\n\n"
814
+ "[bold yellow]📋 Available Commands:[/bold yellow]\n"
815
+ "• [cyan]init[/cyan] - Initialize new project\n"
816
+ "• [cyan]create-system-context[/cyan] - Create system (bounded context)\n"
817
+ "• [cyan]create-module[/cyan] - Create module within system\n"
818
+ "• [cyan]create-component[/cyan] - Create individual components (entities, services, repositories, etc.)\n"
819
+ "• [cyan]batch-create[/cyan] - Create multiple components from YAML\n"
820
+ "• [cyan]status[/cyan] - Show project overview\n"
821
+ "• [cyan]config[/cyan] - Manage configuration\n"
822
+ "• [cyan]version[/cyan] - Show version info\n\n"
823
+ "[bold yellow]🏗️ Clean Architecture Layers & Components:[/bold yellow]\n"
824
+ "• [yellow]domain/[/yellow] - Business logic\n"
825
+ " ◦ entities, repositories, value_objects\n"
826
+ "• [yellow]application/[/yellow] - Use cases\n"
827
+ " ◦ services, commands, queries\n"
828
+ "• [yellow]infrastructure/[/yellow] - External concerns\n"
829
+ " ◦ models, repositories, external\n"
830
+ "• [yellow]presentation/[/yellow] - User interface\n"
831
+ " ◦ api, schemas\n\n"
832
+ "[bold yellow]💡 Pro Tips:[/bold yellow]\n"
833
+ "• Use [cyan]--dry-run[/cyan] to preview changes\n"
834
+ "• Use [cyan]--help[/cyan] with any command for detailed info\n"
835
+ "• Check [cyan]fca-scaffold status[/cyan] to see project structure\n"
836
+ "• Validate config with [cyan]fca-scaffold config validate[/cyan]\n\n"
837
+ "[bold yellow]📖 For detailed help on any command:[/bold yellow]\n"
838
+ "[cyan]fca-scaffold [COMMAND] --help[/cyan]",
839
+ title="📚 Fast Clean Architecture - Help Guide",
840
+ )
841
+ )
842
+
843
+
464
844
  @app.command()
465
845
  def version() -> None:
466
- """Show version information."""
467
- from . import __version__, __author__
846
+ """Show version information.
847
+
848
+ Displays the current version of Fast Clean Architecture scaffolding tool
849
+ along with author information.
850
+
851
+ [bold]Example:[/bold]
852
+ [cyan]fca-scaffold version[/cyan]
853
+
854
+ [bold]Useful for:[/bold]
855
+ • Checking which version you're running
856
+ • Bug reports and support requests
857
+ • Ensuring compatibility with documentation
858
+ """
859
+ from . import __author__, __version__
468
860
 
469
861
  console.print(
470
862
  Panel.fit(
@@ -476,5 +868,130 @@ def version() -> None:
476
868
  )
477
869
 
478
870
 
871
+ @app.command()
872
+ def system_status(
873
+ verbose: bool = VERBOSE_OPTION,
874
+ ) -> None:
875
+ """Show system status, health, and usage analytics.
876
+
877
+ Displays comprehensive information about:
878
+ - System health and resource usage
879
+ - Error tracking summary
880
+ - Usage analytics and productivity metrics
881
+
882
+ [bold]Examples:[/bold]
883
+ [cyan]fca-scaffold system-status[/cyan]
884
+ [cyan]fca-scaffold system-status --verbose[/cyan]
885
+ """
886
+ try:
887
+ from .analytics import get_analytics
888
+ from .error_tracking import get_error_tracker
889
+ from .health import get_health_monitor
890
+
891
+ console.print("\n[bold blue]📊 Fast Clean Architecture Status[/bold blue]\n")
892
+
893
+ # FCA System Health
894
+ console.print("[bold yellow]🏥 FCA System Health[/bold yellow]")
895
+ health_monitor = get_health_monitor()
896
+ health_data = health_monitor.get_system_health()
897
+
898
+ if "error" in health_data:
899
+ console.print(f"[red]❌ Health check failed: {health_data['error']}[/red]")
900
+ else:
901
+ process_data = health_data.get("process", {})
902
+
903
+ console.print(
904
+ f" • Memory Usage: {process_data.get('memory_rss_mb', 0):.1f} MB ({process_data.get('memory_percent', 0):.1f}%)"
905
+ )
906
+ console.print(f" • CPU Usage: {process_data.get('cpu_percent', 0):.1f}%")
907
+ console.print(
908
+ f" • Session Duration: {health_data.get('uptime_seconds', 0):.1f} seconds"
909
+ )
910
+
911
+ # Error Tracking
912
+ console.print("\n[bold yellow]🐛 Error Tracking[/bold yellow]")
913
+ error_tracker = get_error_tracker()
914
+ error_summary = error_tracker.get_error_summary()
915
+
916
+ console.print(f" • Total Errors: {error_summary.get('total_errors', 0)}")
917
+ console.print(f" • Unique Errors: {error_summary.get('unique_errors', 0)}")
918
+
919
+ if error_summary.get("most_common_errors"):
920
+ console.print(" • Most Common Errors:")
921
+ for error_info in error_summary["most_common_errors"][:3]:
922
+ console.print(
923
+ f" - {error_info['signature']}: {error_info['count']} times"
924
+ )
925
+
926
+ # Usage Analytics
927
+ console.print("\n[bold yellow]📈 Usage Analytics[/bold yellow]")
928
+ analytics = get_analytics()
929
+ usage_summary = analytics.get_usage_summary()
930
+ productivity = analytics.get_productivity_metrics()
931
+
932
+ session_data = usage_summary.get("session", {})
933
+ console.print(
934
+ f" • Session Duration: {session_data.get('duration_seconds', 0):.1f} seconds"
935
+ )
936
+ console.print(f" • Total Commands: {session_data.get('total_commands', 0)}")
937
+ console.print(
938
+ f" • Components Created: {productivity.get('components_created', 0)}"
939
+ )
940
+ console.print(
941
+ f" • Components/Hour: {productivity.get('components_per_hour', 0):.1f}"
942
+ )
943
+
944
+ if usage_summary.get("commands"):
945
+ console.print(" • Command Usage:")
946
+ for command, count in list(usage_summary["commands"].items())[:3]:
947
+ console.print(f" - {command}: {count} times")
948
+
949
+ if usage_summary.get("component_types"):
950
+ console.print(" • Popular Component Types:")
951
+ for comp_type, count in list(usage_summary["component_types"].items())[:3]:
952
+ console.print(f" - {comp_type}: {count} times")
953
+
954
+ if verbose:
955
+ # Show detailed information
956
+ console.print("\n[bold yellow]🔍 Detailed Information[/bold yellow]")
957
+
958
+ if usage_summary.get("layers"):
959
+ console.print(" • Layer Usage:")
960
+ for layer, count in usage_summary["layers"].items():
961
+ console.print(f" - {layer}: {count} times")
962
+
963
+ if usage_summary.get("systems"):
964
+ console.print(" • System Usage:")
965
+ for system, count in usage_summary["systems"].items():
966
+ console.print(f" - {system}: {count} times")
967
+
968
+ if usage_summary.get("performance"):
969
+ console.print(" • Performance Metrics:")
970
+ for command, perf in usage_summary["performance"].items():
971
+ console.print(
972
+ f" - {command}: avg {perf['average_ms']}ms (min: {perf['min_ms']}ms, max: {perf['max_ms']}ms)"
973
+ )
974
+
975
+ console.print("\n[green]✅ Status check completed[/green]")
976
+
977
+ # Log the status check
978
+ logger.info(
979
+ "System status command executed",
980
+ operation="cli_system_status",
981
+ verbose=verbose,
982
+ )
983
+
984
+ except Exception as e:
985
+ logger.error(
986
+ "System status command failed",
987
+ operation="cli_system_status",
988
+ error=str(e),
989
+ error_type=type(e).__name__,
990
+ )
991
+ handle_error(e, verbose)
992
+
993
+
479
994
  if __name__ == "__main__":
995
+ # Ensure logging is configured
996
+ configure_logging()
480
997
  app()