Claude-skill-registry impl-service
Implementar serviços de lógica de negócio em services/. Use quando criar service, lógica de negócio, orquestração de repositórios, ou integração com LLM.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/impl-service" ~/.claude/skills/majiayu000-claude-skill-registry-impl-service && rm -rf "$T"
manifest:
skills/data/impl-service/SKILL.mdsource content
Implementar Service (Camada de Lógica de Negócio)
Regras Arquiteturais (NON-NEGOTIABLE)
- TODA lógica de negócio deve estar em services, NUNCA em routers ou repositories
- Validações de negócio (limites, regras, constraints) ficam no service
- Prompts de LLM ficam no service, NUNCA em routers
- Chamadas LLM DEVEM usar tracing Phoenix:
_tracer.start_as_current_span() - Dependency Injection: repositories são injetados no
__init__ - Orquestração: services chamam repositories, NUNCA acessam DB diretamente
- Bloco de validação: todo service DEVE ter
if __name__ == "__main__":
Estrutura de Arquivos
src/synth_lab/services/ ├── {entity}_service.py # Um arquivo por domínio ├── errors.py # Exceções de negócio └── {feature}/ # Subpastas para features complexas ├── __init__.py └── {sub_service}.py
Convenções de nome:
- Arquivo:
(singular, snake_case){entity}_service.py - Classe:
(PascalCase){Entity}Service - Métodos:
(ex:{verbo}_{substantivo}
,create_experiment
)list_synths
Padrões de Código
Service Básico (sem LLM)
""" {Entity} service for synth-lab. Business logic layer for {entity} operations. """ from synth_lab.models.pagination import PaginatedResponse, PaginationParams from synth_lab.repositories.{entity}_repository import {Entity}Repository class {Entity}Service: """Service for {entity} business logic.""" # Constantes de validação NAME_MAX_LENGTH = 100 def __init__(self, repository: {Entity}Repository | None = None): """Initialize with dependency injection.""" self.repository = repository or {Entity}Repository() def list_{entities}( self, params: PaginationParams | None = None, ) -> PaginatedResponse[{Entity}Summary]: """List {entities} with pagination.""" params = params or PaginationParams() return self.repository.list_{entities}(params) def get_{entity}(self, {entity}_id: str) -> {Entity}Detail: """Get {entity} by ID.""" return self.repository.get_by_id({entity}_id) def create_{entity}(self, name: str) -> {Entity}: """Create new {entity} with validation.""" # Validação de negócio if not name or not name.strip(): raise ValueError("name is required") if len(name) > self.NAME_MAX_LENGTH: raise ValueError(f"name exceeds {self.NAME_MAX_LENGTH} chars") # Criar e persistir entity = {Entity}(name=name.strip()) return self.repository.create(entity)
Service com LLM
""" {Feature} LLM service for synth-lab. LLM-powered business logic. """ from loguru import logger from synth_lab.infrastructure.llm_client import LLMClient, get_llm_client from synth_lab.infrastructure.phoenix_tracing import get_tracer _tracer = get_tracer("{feature}_service") class {Feature}Service: """Service with LLM integration.""" def __init__(self, llm_client: LLMClient | None = None): self.llm = llm_client or get_llm_client() self.logger = logger.bind(component="{feature}_service") def generate(self, data: InputData) -> Result: """Generate result using LLM.""" with _tracer.start_as_current_span("generate"): prompt = self._build_prompt(data) response = self.llm.complete_json( messages=[{"role": "user", "content": prompt}], operation_name="generate_result", ) self.logger.info(f"Generated for {data.id}") return self._parse_response(response) def _build_prompt(self, data: InputData) -> str: """Build LLM prompt (private method).""" return f""" Instrução: ... Dados: {data.model_dump_json()} """ def _parse_response(self, response: dict) -> Result: """Parse and validate LLM response.""" return Result(**response)
Bloco de Validação (OBRIGATÓRIO)
if __name__ == "__main__": import sys from synth_lab.infrastructure.config import DB_PATH from synth_lab.infrastructure.database import DatabaseManager all_validation_failures = [] total_tests = 0 if not DB_PATH.exists(): print(f"Database not found at {DB_PATH}") sys.exit(1) db = DatabaseManager(DB_PATH) service = {Entity}Service() # Test 1: Operação básica total_tests += 1 try: result = service.list_{entities}() if result.pagination.total < 0: all_validation_failures.append("Invalid total") except Exception as e: all_validation_failures.append(f"List failed: {e}") # Test 2: Validação de erro total_tests += 1 try: service.get_{entity}("invalid_id") all_validation_failures.append("Should raise NotFoundError") except {Entity}NotFoundError: pass # Expected except Exception as e: all_validation_failures.append(f"Wrong exception: {e}") db.close() if all_validation_failures: print(f"VALIDATION FAILED - {len(all_validation_failures)}/{total_tests}:") for f in all_validation_failures: print(f" - {f}") sys.exit(1) else: print(f"VALIDATION PASSED - All {total_tests} tests OK") sys.exit(0)
Checklist de Verificação
Antes de finalizar, verificar:
- Lógica de negócio está no service (não em router/repository)
- Validações de input (required, max length, format)
- Repository injetado via DI no
__init__ - Chamadas LLM usam
_tracer.start_as_current_span() - Prompts em métodos privados
_build_prompt() - Bloco
com validação realif __name__ == "__main__": - Exceções específicas do domínio (ex:
){Entity}NotFoundError - Docstrings em todos os métodos públicos
- Type hints em parâmetros e retornos