package publish import ( "context" "fmt" "sync" "sync/atomic" "apps/backend/internal/module/studio/domain" "github.com/google/uuid" ) // FakeTransport records every Publish call — OB-02 greppable proof. type FakeTransport struct { mu sync.Mutex Calls []domain.PublishRequest Fail bool FailMsg string // FailOnNth fails the Nth call (1-based); 0 = never FailOnNth int n int64 } func NewFake() *FakeTransport { return &FakeTransport{} } func (f *FakeTransport) Publish(ctx context.Context, req domain.PublishRequest) (*domain.PublishResult, error) { _ = ctx n := atomic.AddInt64(&f.n, 1) f.mu.Lock() f.Calls = append(f.Calls, req) fail := f.Fail failNth := f.FailOnNth msg := f.FailMsg f.mu.Unlock() if fail || (failNth > 0 && int(n) == failNth) { if msg == "" { msg = "threads publish failed" } return nil, fmt.Errorf("%s", msg) } return &domain.PublishResult{MediaID: "media_" + uuid.NewString()[:8]}, nil } func (f *FakeTransport) CallCount() int { f.mu.Lock() defer f.mu.Unlock() return len(f.Calls) } func (f *FakeTransport) Reset() { f.mu.Lock() defer f.mu.Unlock() f.Calls = nil atomic.StoreInt64(&f.n, 0) f.Fail = false f.FailOnNth = 0 } // Transport interface used by studio service (context.Context). type Transport interface { Publish(ctx context.Context, req domain.PublishRequest) (*domain.PublishResult, error) } var _ Transport = (*FakeTransport)(nil)