feat(media-supply): add media resource supply marketplace
Desktop Client Build / Resolve Build Metadata (push) Successful in 43s
Frontend CI / Frontend (push) Successful in 3m49s
Backend CI / Backend (push) Failing after 7m10s
Desktop Client Build / Build Desktop Client (push) Successful in 23m4s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 28s
Desktop Client Build / Resolve Build Metadata (push) Successful in 43s
Frontend CI / Frontend (push) Successful in 3m49s
Backend CI / Backend (push) Failing after 7m10s
Desktop Client Build / Build Desktop Client (push) Successful in 23m4s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 28s
Introduce an end-to-end media-supply feature: tenant-side resource sync service/worker backed by a Meijiequan supplier client, ops-side management APIs, and admin/ops web views for resources, orders, favorites and submission. Adds a shared digitocr helper, MediaSupply config blocks for tenant and ops, shared types, and migrations for supplier media resources, price overrides, customer visibility and order refunds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
// image/png is registered by the digitocr package; jpeg/gif are registered
|
||||
// here so a future change of the captcha format still decodes.
|
||||
_ "image/gif"
|
||||
_ "image/jpeg"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/shared/digitocr"
|
||||
)
|
||||
|
||||
// meijiequanChallengeDigits is the fixed length of the meijiequan login captcha.
|
||||
const meijiequanChallengeDigits = 4
|
||||
|
||||
var errMeijiequanChallengeEmpty = errors.New("meijiequan challenge image is empty")
|
||||
|
||||
// DigitOCRMeijiequanChallengeCodeResolver decodes the meijiequan numeric login
|
||||
// captcha locally via the digitocr template matcher, enabling unattended login
|
||||
// without an external OCR service.
|
||||
type DigitOCRMeijiequanChallengeCodeResolver struct{}
|
||||
|
||||
// ResolveCode recognizes the digits in the captcha image. A decode failure is
|
||||
// returned as a non-challenge error so the login flow retries with a fresh
|
||||
// captcha rather than giving up immediately (as the manual resolver does).
|
||||
func (DigitOCRMeijiequanChallengeCodeResolver) ResolveCode(_ context.Context, challenge MeijiequanChallenge) (string, error) {
|
||||
if len(challenge.Image) == 0 {
|
||||
return "", errMeijiequanChallengeEmpty
|
||||
}
|
||||
code, err := digitocr.RecognizeReader(bytes.NewReader(challenge.Image), digitocr.Options{Digits: meijiequanChallengeDigits})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("digitocr resolve meijiequan challenge: %w", err)
|
||||
}
|
||||
return code, nil
|
||||
}
|
||||
Reference in New Issue
Block a user