managarten/packages/feedback/src/api.ts
Till JS c9b122076a feat(feedback): public feed types + ReactionBar + service split
@mana/feedback wird zur Pflege-SSOT für Public-Community-Hub.

- PublicFeedbackItem-Typ: anonymisiertes Item, das nur display_name +
  reactions + status führt — kein userId, displayHash, deviceInfo.
- ReactionEmoji ('👍' '❤️' '🚀' '🤔' '🎉') + REACTION_LABELS mit DE-Labels.
- CreateFeedbackInput erweitert um moduleContext + parentId. Reactions
  + score auf Feedback-Type optional gemacht.
- Service-Split:
  createFeedbackService    — auth-required Submit/React/Manage,
                            getPublicFeed (auth-enriched mit myReactions)
  createPublicFeedbackService — anonymous, SSR-only, getFeed/getItem.
  toggleReaction(emoji) statt vote/unvote (legacy-Shims bleiben für
  back-compat zu vote → '👍'-Toggle).
- ReactionBar.svelte: Slack-Style emoji-row mit Active-Highlighting für
  myReactions, ReadOnly-Mode für Public-SSR. Auto-disabled-Tooltip.
- index.ts re-exportiert die neuen Typen + ReactionBar; FeedbackVote
  rausgeschmissen (durch FeedbackReactions im Server-Schema ersetzt).

FeedbackCard + FeedbackPage minimal angepasst, damit svelte-check
clean bleibt — die Legacy-Komponenten bleiben funktional, werden aber
in Phase 3 zu @mana/feedback's neuen Modul-Views ausgemistet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:01:06 +02:00

82 lines
1.7 KiB
TypeScript

/**
* API request/response types for feedback.
*/
import type {
Feedback,
FeedbackCategory,
FeedbackStatus,
PublicFeedbackItem,
ReactionEmoji,
} from './feedback';
export interface CreateFeedbackInput {
title?: string;
feedbackText: string;
category?: FeedbackCategory;
/**
* Whether the submission shows up in the public community list.
* Defaults to `true` server-side. Set `false` for private intake
* categories like `onboarding-wish` (private mode) or `churn-feedback`.
*/
isPublic?: boolean;
/** Module that triggered the inline FeedbackHook submission. */
moduleContext?: string;
/** If set, submission is a reply to that feedback item. */
parentId?: string;
deviceInfo?: Record<string, unknown>;
}
export interface FeedbackQueryParams {
appId?: string;
moduleContext?: string;
status?: FeedbackStatus;
category?: FeedbackCategory;
sort?: 'score' | 'recent';
limit?: number;
offset?: number;
}
export interface FeedbackResponse {
success?: boolean;
feedback?: Feedback;
error?: string;
[key: string]: unknown;
}
export interface FeedbackListResponse {
success?: boolean;
items: Feedback[];
total?: number;
error?: string;
}
export interface PublicFeedListResponse {
items: PublicFeedbackItem[];
}
export interface PublicItemResponse {
item: PublicFeedbackItem;
replies: PublicFeedbackItem[];
}
export interface ReactionResponse {
reactions: Partial<Record<string, number>>;
score: number;
userHasReacted: boolean;
}
export interface AdminPatchInput {
status?: FeedbackStatus;
adminResponse?: string;
isPublic?: boolean;
}
export type ReactInput = { emoji: ReactionEmoji };
export interface VoteResponse {
success: boolean;
newVoteCount?: number;
userHasVoted?: boolean;
error?: string;
}