Implement service layer
This commit is contained in:
parent
c14532bd1f
commit
f38aa214d2
16
internal/service/adapters.go
Normal file
16
internal/service/adapters.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import "hash-of-wisdom/internal/pow/challenge"
|
||||||
|
|
||||||
|
// generatorAdapter adapts the real challenge.Generator to our interface
|
||||||
|
type generatorAdapter struct {
|
||||||
|
generator *challenge.Generator
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGeneratorAdapter(generator *challenge.Generator) ChallengeGenerator {
|
||||||
|
return &generatorAdapter{generator: generator}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *generatorAdapter) GenerateChallenge() (*challenge.Challenge, error) {
|
||||||
|
return a.generator.GenerateChallenge()
|
||||||
|
}
|
||||||
86
internal/service/wisdom.go
Normal file
86
internal/service/wisdom.go
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"hash-of-wisdom/internal/pow/challenge"
|
||||||
|
"hash-of-wisdom/internal/quotes"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrResourceRequired = errors.New("resource is required")
|
||||||
|
ErrUnsupportedResource = errors.New("unsupported resource")
|
||||||
|
ErrSolutionRequired = errors.New("solution is required")
|
||||||
|
ErrInvalidChallenge = errors.New("invalid challenge")
|
||||||
|
ErrInvalidSolution = errors.New("invalid proof of work solution")
|
||||||
|
)
|
||||||
|
|
||||||
|
type ChallengeGenerator interface {
|
||||||
|
GenerateChallenge() (*challenge.Challenge, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChallengeVerifier interface {
|
||||||
|
VerifyChallenge(ch *challenge.Challenge) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type QuoteService interface {
|
||||||
|
GetRandomQuote(ctx context.Context) (*quotes.Quote, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type WisdomService struct {
|
||||||
|
challengeGenerator ChallengeGenerator
|
||||||
|
challengeVerifier ChallengeVerifier
|
||||||
|
quoteService QuoteService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWisdomService(
|
||||||
|
generator ChallengeGenerator,
|
||||||
|
verifier ChallengeVerifier,
|
||||||
|
quoteService QuoteService,
|
||||||
|
) *WisdomService {
|
||||||
|
return &WisdomService{
|
||||||
|
challengeGenerator: generator,
|
||||||
|
challengeVerifier: verifier,
|
||||||
|
quoteService: quoteService,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WisdomService) GenerateChallenge(ctx context.Context, resource string) (*challenge.Challenge, error) {
|
||||||
|
if resource == "" {
|
||||||
|
return nil, ErrResourceRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
if resource != "quotes" {
|
||||||
|
return nil, ErrUnsupportedResource
|
||||||
|
}
|
||||||
|
|
||||||
|
ch, err := s.challengeGenerator.GenerateChallenge()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate challenge: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WisdomService) VerifySolution(ctx context.Context, solution *challenge.Solution) error {
|
||||||
|
if solution == nil {
|
||||||
|
return ErrSolutionRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify challenge authenticity and expiration
|
||||||
|
if err := s.challengeVerifier.VerifyChallenge(&solution.Challenge); err != nil {
|
||||||
|
return fmt.Errorf("%w: %v", ErrInvalidChallenge, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify PoW solution
|
||||||
|
if !solution.Verify() {
|
||||||
|
return ErrInvalidSolution
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WisdomService) GetQuote(ctx context.Context) (*quotes.Quote, error) {
|
||||||
|
return s.quoteService.GetRandomQuote(ctx)
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue