@corbat-tech/coding-standards-mcp 1.0.3 → 2.0.0

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 (99) hide show
  1. package/README.md +233 -337
  2. package/dist/agent.d.ts +5 -6
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +95 -217
  5. package/dist/agent.js.map +1 -1
  6. package/dist/analysis/code-analyzer.d.ts +44 -0
  7. package/dist/analysis/code-analyzer.d.ts.map +1 -0
  8. package/dist/analysis/code-analyzer.js +528 -0
  9. package/dist/analysis/code-analyzer.js.map +1 -0
  10. package/dist/errors.d.ts +58 -0
  11. package/dist/errors.d.ts.map +1 -0
  12. package/dist/errors.js +112 -0
  13. package/dist/errors.js.map +1 -0
  14. package/dist/guardrails.d.ts +35 -0
  15. package/dist/guardrails.d.ts.map +1 -0
  16. package/dist/guardrails.js +303 -0
  17. package/dist/guardrails.js.map +1 -0
  18. package/dist/index.js +1 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/logger.d.ts +36 -0
  21. package/dist/logger.d.ts.map +1 -0
  22. package/dist/logger.js +63 -0
  23. package/dist/logger.js.map +1 -0
  24. package/dist/metrics.d.ts +40 -0
  25. package/dist/metrics.d.ts.map +1 -0
  26. package/dist/metrics.js +97 -0
  27. package/dist/metrics.js.map +1 -0
  28. package/dist/profiles.d.ts +1 -1
  29. package/dist/profiles.d.ts.map +1 -1
  30. package/dist/profiles.js +239 -108
  31. package/dist/profiles.js.map +1 -1
  32. package/dist/prompts.js +1 -1
  33. package/dist/prompts.js.map +1 -1
  34. package/dist/tools/definitions.d.ts +143 -0
  35. package/dist/tools/definitions.d.ts.map +1 -0
  36. package/dist/tools/definitions.js +229 -0
  37. package/dist/tools/definitions.js.map +1 -0
  38. package/dist/tools/handlers/get-context.d.ts +12 -0
  39. package/dist/tools/handlers/get-context.d.ts.map +1 -0
  40. package/dist/tools/handlers/get-context.js +233 -0
  41. package/dist/tools/handlers/get-context.js.map +1 -0
  42. package/dist/tools/handlers/health.d.ts +11 -0
  43. package/dist/tools/handlers/health.d.ts.map +1 -0
  44. package/dist/tools/handlers/health.js +57 -0
  45. package/dist/tools/handlers/health.js.map +1 -0
  46. package/dist/tools/handlers/index.d.ts +12 -0
  47. package/dist/tools/handlers/index.d.ts.map +1 -0
  48. package/dist/tools/handlers/index.js +12 -0
  49. package/dist/tools/handlers/index.js.map +1 -0
  50. package/dist/tools/handlers/init.d.ts +12 -0
  51. package/dist/tools/handlers/init.d.ts.map +1 -0
  52. package/dist/tools/handlers/init.js +102 -0
  53. package/dist/tools/handlers/init.js.map +1 -0
  54. package/dist/tools/handlers/profiles.d.ts +11 -0
  55. package/dist/tools/handlers/profiles.d.ts.map +1 -0
  56. package/dist/tools/handlers/profiles.js +25 -0
  57. package/dist/tools/handlers/profiles.js.map +1 -0
  58. package/dist/tools/handlers/search.d.ts +12 -0
  59. package/dist/tools/handlers/search.d.ts.map +1 -0
  60. package/dist/tools/handlers/search.js +58 -0
  61. package/dist/tools/handlers/search.js.map +1 -0
  62. package/dist/tools/handlers/validate.d.ts +15 -0
  63. package/dist/tools/handlers/validate.d.ts.map +1 -0
  64. package/dist/tools/handlers/validate.js +71 -0
  65. package/dist/tools/handlers/validate.js.map +1 -0
  66. package/dist/tools/handlers/verify.d.ts +38 -0
  67. package/dist/tools/handlers/verify.d.ts.map +1 -0
  68. package/dist/tools/handlers/verify.js +172 -0
  69. package/dist/tools/handlers/verify.js.map +1 -0
  70. package/dist/tools/index.d.ts +22 -0
  71. package/dist/tools/index.d.ts.map +1 -0
  72. package/dist/tools/index.js +75 -0
  73. package/dist/tools/index.js.map +1 -0
  74. package/dist/tools/schemas.d.ts +29 -0
  75. package/dist/tools/schemas.d.ts.map +1 -0
  76. package/dist/tools/schemas.js +20 -0
  77. package/dist/tools/schemas.js.map +1 -0
  78. package/dist/tools.js +2 -2
  79. package/dist/tools.js.map +1 -1
  80. package/dist/types.d.ts +141 -71
  81. package/dist/types.d.ts.map +1 -1
  82. package/dist/types.js +92 -40
  83. package/dist/types.js.map +1 -1
  84. package/package.json +2 -2
  85. package/profiles/examples/microservice-kafka.yaml +122 -0
  86. package/profiles/examples/startup-fast.yaml +67 -0
  87. package/profiles/examples/strict-enterprise.yaml +62 -0
  88. package/profiles/templates/angular.yaml +614 -0
  89. package/profiles/templates/csharp-dotnet.yaml +529 -0
  90. package/profiles/templates/flutter.yaml +547 -0
  91. package/profiles/templates/go.yaml +1276 -0
  92. package/profiles/templates/java-spring-backend.yaml +326 -0
  93. package/profiles/templates/kotlin-spring.yaml +417 -0
  94. package/profiles/templates/nextjs.yaml +536 -0
  95. package/profiles/templates/nodejs.yaml +594 -0
  96. package/profiles/templates/python.yaml +546 -0
  97. package/profiles/templates/react.yaml +456 -0
  98. package/profiles/templates/rust.yaml +508 -0
  99. package/profiles/templates/vue.yaml +483 -0
@@ -510,3 +510,329 @@ technologies:
510
510
  useArchUnit: true
511
511
  testNamingPattern: "should_ExpectedBehavior_When_Condition"
512
512
  integrationTestSuffix: "IT"
513
+
514
+ # ----------------------------------------------------------------------------
515
+ # CODE EXAMPLES - For AI Learning
516
+ # ----------------------------------------------------------------------------
517
+ codeExamples:
518
+ valueObject: |
519
+ // Value Object using Java Record (immutable, self-validating)
520
+ public record Money(BigDecimal amount, Currency currency) {
521
+ public Money {
522
+ Objects.requireNonNull(amount, "Amount cannot be null");
523
+ Objects.requireNonNull(currency, "Currency cannot be null");
524
+ if (amount.compareTo(BigDecimal.ZERO) < 0) {
525
+ throw new IllegalArgumentException("Amount cannot be negative");
526
+ }
527
+ }
528
+
529
+ public Money add(Money other) {
530
+ if (!this.currency.equals(other.currency)) {
531
+ throw new IllegalArgumentException("Cannot add different currencies");
532
+ }
533
+ return new Money(this.amount.add(other.amount), this.currency);
534
+ }
535
+ }
536
+
537
+ entity: |
538
+ // Domain Entity with encapsulated business logic
539
+ public class Order {
540
+ private final OrderId id;
541
+ private final CustomerId customerId;
542
+ private OrderStatus status;
543
+ private final List<OrderLine> lines;
544
+ private Money total;
545
+
546
+ public Order(OrderId id, CustomerId customerId) {
547
+ this.id = Objects.requireNonNull(id);
548
+ this.customerId = Objects.requireNonNull(customerId);
549
+ this.status = OrderStatus.DRAFT;
550
+ this.lines = new ArrayList<>();
551
+ this.total = Money.ZERO;
552
+ }
553
+
554
+ public void addLine(Product product, Quantity quantity) {
555
+ if (status != OrderStatus.DRAFT) {
556
+ throw new InvalidOperationException("Cannot modify non-draft order");
557
+ }
558
+ var line = new OrderLine(product, quantity);
559
+ lines.add(line);
560
+ recalculateTotal();
561
+ }
562
+
563
+ public void confirm() {
564
+ if (lines.isEmpty()) {
565
+ throw new BusinessRuleViolationException("Cannot confirm empty order");
566
+ }
567
+ this.status = OrderStatus.CONFIRMED;
568
+ // Publish domain event
569
+ DomainEvents.publish(new OrderConfirmed(this.id, this.total));
570
+ }
571
+ }
572
+
573
+ useCase: |
574
+ // Use Case / Application Service
575
+ @RequiredArgsConstructor
576
+ @Transactional
577
+ public class CreateOrderUseCase {
578
+ private final OrderRepository orderRepository;
579
+ private final CustomerRepository customerRepository;
580
+ private final DomainEventPublisher eventPublisher;
581
+
582
+ public OrderId execute(CreateOrderCommand command) {
583
+ // 1. Validate customer exists
584
+ var customer = customerRepository.findById(command.customerId())
585
+ .orElseThrow(() -> new EntityNotFoundException("Customer", command.customerId()));
586
+
587
+ // 2. Create order (domain logic)
588
+ var order = new Order(OrderId.generate(), customer.getId());
589
+ for (var item : command.items()) {
590
+ order.addLine(item.product(), item.quantity());
591
+ }
592
+
593
+ // 3. Save
594
+ orderRepository.save(order);
595
+
596
+ // 4. Publish events
597
+ eventPublisher.publishAll(order.getDomainEvents());
598
+
599
+ return order.getId();
600
+ }
601
+ }
602
+
603
+ controller: |
604
+ // REST Controller (Infrastructure Layer)
605
+ @RestController
606
+ @RequestMapping("/api/v1/orders")
607
+ @RequiredArgsConstructor
608
+ public class OrderController {
609
+ private final CreateOrderUseCase createOrderUseCase;
610
+ private final GetOrderQuery getOrderQuery;
611
+
612
+ @PostMapping
613
+ @ResponseStatus(HttpStatus.CREATED)
614
+ public ResponseEntity<OrderResponse> create(@Valid @RequestBody CreateOrderRequest request) {
615
+ var command = new CreateOrderCommand(
616
+ new CustomerId(request.customerId()),
617
+ request.items().stream()
618
+ .map(i -> new OrderItem(new ProductId(i.productId()), new Quantity(i.quantity())))
619
+ .toList()
620
+ );
621
+
622
+ var orderId = createOrderUseCase.execute(command);
623
+ var order = getOrderQuery.execute(orderId);
624
+
625
+ return ResponseEntity
626
+ .created(URI.create("/api/v1/orders/" + orderId.value()))
627
+ .body(order);
628
+ }
629
+ }
630
+
631
+ test: |
632
+ // Unit Test with Arrange-Act-Assert pattern
633
+ @ExtendWith(MockitoExtension.class)
634
+ class CreateOrderUseCaseTest {
635
+ @Mock
636
+ private OrderRepository orderRepository;
637
+ @Mock
638
+ private CustomerRepository customerRepository;
639
+ @Mock
640
+ private DomainEventPublisher eventPublisher;
641
+
642
+ @InjectMocks
643
+ private CreateOrderUseCase useCase;
644
+
645
+ @Test
646
+ void should_CreateOrder_When_CustomerExistsAndItemsValid() {
647
+ // Arrange
648
+ var customerId = new CustomerId(UUID.randomUUID());
649
+ var customer = new Customer(customerId, "John Doe");
650
+ var command = new CreateOrderCommand(customerId, List.of(
651
+ new OrderItem(ProductId.of("PROD-1"), Quantity.of(2))
652
+ ));
653
+
654
+ when(customerRepository.findById(customerId)).thenReturn(Optional.of(customer));
655
+ when(orderRepository.save(any())).thenAnswer(i -> i.getArgument(0));
656
+
657
+ // Act
658
+ var orderId = useCase.execute(command);
659
+
660
+ // Assert
661
+ assertThat(orderId).isNotNull();
662
+ verify(orderRepository).save(argThat(order ->
663
+ order.getCustomerId().equals(customerId) &&
664
+ order.getLines().size() == 1
665
+ ));
666
+ verify(eventPublisher).publishAll(anyList());
667
+ }
668
+
669
+ @Test
670
+ void should_ThrowException_When_CustomerNotFound() {
671
+ // Arrange
672
+ var command = new CreateOrderCommand(
673
+ new CustomerId(UUID.randomUUID()),
674
+ List.of()
675
+ );
676
+ when(customerRepository.findById(any())).thenReturn(Optional.empty());
677
+
678
+ // Act & Assert
679
+ assertThatThrownBy(() -> useCase.execute(command))
680
+ .isInstanceOf(EntityNotFoundException.class)
681
+ .hasMessageContaining("Customer");
682
+ }
683
+ }
684
+
685
+ repository: |
686
+ // Repository Interface (Domain Layer - Port)
687
+ public interface OrderRepository {
688
+ Optional<Order> findById(OrderId id);
689
+ Order save(Order order);
690
+ List<Order> findByCustomerId(CustomerId customerId);
691
+ }
692
+
693
+ // Repository Implementation (Infrastructure Layer - Adapter)
694
+ @Repository
695
+ @RequiredArgsConstructor
696
+ class JpaOrderRepository implements OrderRepository {
697
+ private final OrderJpaRepository jpaRepository;
698
+ private final OrderMapper mapper;
699
+
700
+ @Override
701
+ public Optional<Order> findById(OrderId id) {
702
+ return jpaRepository.findById(id.value())
703
+ .map(mapper::toDomain);
704
+ }
705
+
706
+ @Override
707
+ public Order save(Order order) {
708
+ var entity = mapper.toEntity(order);
709
+ var saved = jpaRepository.save(entity);
710
+ return mapper.toDomain(saved);
711
+ }
712
+ }
713
+
714
+ # ----------------------------------------------------------------------------
715
+ # ANTI-PATTERNS - What NOT to do
716
+ # ----------------------------------------------------------------------------
717
+ antiPatterns:
718
+ anemicDomainModel:
719
+ description: "Domain objects with only getters/setters, no business logic"
720
+ example: |
721
+ // BAD: Anemic domain model
722
+ public class Order {
723
+ private OrderStatus status;
724
+ public OrderStatus getStatus() { return status; }
725
+ public void setStatus(OrderStatus status) { this.status = status; }
726
+ }
727
+
728
+ // Service does all the work
729
+ public class OrderService {
730
+ public void confirmOrder(Order order) {
731
+ if (order.getLines().isEmpty()) throw new Exception();
732
+ order.setStatus(OrderStatus.CONFIRMED); // Logic outside domain!
733
+ }
734
+ }
735
+ fix: "Move business logic INTO the domain entity"
736
+
737
+ primitiveObsession:
738
+ description: "Using primitives instead of Value Objects"
739
+ example: |
740
+ // BAD: Using primitives
741
+ public class Order {
742
+ private String customerId; // Just a String!
743
+ private double amount; // Precision issues!
744
+ private String currency; // No validation!
745
+ }
746
+ fix: "Use Value Objects: CustomerId, Money(amount, currency)"
747
+
748
+ godClass:
749
+ description: "Class with too many responsibilities"
750
+ example: |
751
+ // BAD: God class doing everything
752
+ public class OrderService {
753
+ public Order createOrder() { ... }
754
+ public void sendEmail() { ... }
755
+ public void generatePdf() { ... }
756
+ public void processPayment() { ... }
757
+ public void updateInventory() { ... }
758
+ public void notifyWarehouse() { ... }
759
+ }
760
+ fix: "Split into focused services: OrderService, NotificationService, PaymentService, etc."
761
+
762
+ fieldInjection:
763
+ description: "Using @Autowired on fields instead of constructor"
764
+ example: |
765
+ // BAD: Field injection
766
+ @Service
767
+ public class OrderService {
768
+ @Autowired
769
+ private OrderRepository repository; // Hard to test!
770
+
771
+ @Autowired
772
+ private PaymentService paymentService;
773
+ }
774
+ fix: |
775
+ // GOOD: Constructor injection
776
+ @Service
777
+ @RequiredArgsConstructor
778
+ public class OrderService {
779
+ private final OrderRepository repository;
780
+ private final PaymentService paymentService;
781
+ }
782
+
783
+ catchingGenericException:
784
+ description: "Catching Exception instead of specific types"
785
+ example: |
786
+ // BAD: Catching generic Exception
787
+ try {
788
+ processOrder(order);
789
+ } catch (Exception e) { // Catches EVERYTHING including NPE, OOM
790
+ log.error("Error", e);
791
+ }
792
+ fix: |
793
+ // GOOD: Catch specific exceptions
794
+ try {
795
+ processOrder(order);
796
+ } catch (OrderNotFoundException e) {
797
+ throw new ResponseStatusException(NOT_FOUND, e.getMessage());
798
+ } catch (InsufficientInventoryException e) {
799
+ throw new ResponseStatusException(CONFLICT, e.getMessage());
800
+ }
801
+
802
+ businessLogicInController:
803
+ description: "Putting business logic in REST controllers"
804
+ example: |
805
+ // BAD: Logic in controller
806
+ @PostMapping("/orders/{id}/confirm")
807
+ public void confirm(@PathVariable Long id) {
808
+ Order order = repository.findById(id);
809
+ if (order.getLines().isEmpty()) {
810
+ throw new BadRequestException("Empty order");
811
+ }
812
+ order.setStatus(CONFIRMED);
813
+ order.setConfirmedAt(Instant.now());
814
+ repository.save(order);
815
+ emailService.sendConfirmation(order);
816
+ }
817
+ fix: "Controllers should only delegate to use cases/services"
818
+
819
+ nPlusOneQueries:
820
+ description: "Loading related entities in a loop"
821
+ example: |
822
+ // BAD: N+1 queries
823
+ List<Order> orders = orderRepository.findAll();
824
+ for (Order order : orders) {
825
+ List<OrderLine> lines = lineRepository.findByOrderId(order.getId());
826
+ // This executes N additional queries!
827
+ }
828
+ fix: "Use JOIN FETCH or @EntityGraph to load in single query"
829
+
830
+ returningEntitiesFromControllers:
831
+ description: "Exposing JPA entities in API responses"
832
+ example: |
833
+ // BAD: Returning entity
834
+ @GetMapping("/orders/{id}")
835
+ public OrderEntity getOrder(@PathVariable Long id) {
836
+ return orderRepository.findById(id); // Exposes internal structure!
837
+ }
838
+ fix: "Use DTOs/Response objects to control API shape"