Feedback Manager Architecture
This page describes the integration architecture from UI submission to provider persistence.
Layered Design
| Layer | Primary files | Responsibility |
|---|---|---|
| Client UI | src/modules/share-feedback/index.tsx |
Collect validated form input and trigger submit |
| Client service | src/services/FeedbackService.ts |
HTTP transport to platform route |
| API route | src/app/api/platform/feedback/route.ts |
Auth checks, context enrichment, provider execution |
| Provider factory | src/lib/external/FeedbackManager/provider/factory.ts |
Resolve provider from selector env |
| Provider impl | src/lib/external/FeedbackManager/provider/* |
Persist to external destination |
Runtime Sequence

Responsibility Split
Client responsibilities:
- Build and submit
FeedbackClientContext - Handle success and error UI feedback
Server responsibilities:
- Reject unauthenticated or incomplete site context requests
- Add trusted metadata:
timestamp,siteId,siteName,userId - Select and execute provider
- Return provider result with HTTP status mapping
Provider Selection and Lifecycle
Provider selection is controlled by FEEDBACK_PROVIDER:
- Supported value currently implemented:
google-sheets - Unknown or missing value throws
config.missing
Factory caching behavior:
- First call initializes and memoizes a provider promise
- If initialization rejects, cache is cleared and next call retries
- This avoids permanent rejection poisoning after transient startup failure
Extending with New Providers
To add a provider without changing submission flow:
- Implement
FeedbackProviderin a new provider module - Add provider enum value in
SupportedFeedbackProviderEnum - Register the provider in factory switch
- Define and validate provider-owned env vars in provider-local config
- Add provider doc in
providers/<provider-name>.md
No change is required in ShareFeedbackModule, FeedbackService, or API route payload shape for basic provider additions.