mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-16 01:19:40 +02:00
Phase 3.A des feedback-rewards-and-identity-Plans. Direkter Reziprozitäts- Loop: User kriegt sofort etwas zurück fürs Mitwirken, Originalwunsch- Eulen werden beim Ship belohnt, Reagierer kriegen einen Anteil. mana-credits: - Neuer Endpoint POST /api/v1/internal/credits/grant + grantCredits() Service-Methode mit Idempotency via metadata.referenceId. - transaction_type-Enum erweitert um 'grant' (eigener Typ statt Mismatch mit 'refund'). - Migration 0001_grant_transaction_type.sql + partial-Index auf metadata->>'referenceId' für O(log n) Idempotency-Lookup. mana-analytics: - FeedbackService stempelt sofort +5 Credits beim createFeedback (top- level only, Replies bekommen nichts), wenn Mindest-20-Zeichen erfüllt und Rate-Limit (10/User/24h via feedback_grant_log) nicht überschritten. - adminUpdate triggert beim FRISCHEN Übergang nach 'completed': +500 Credits an Original-Wisher + +25 an alle, die mit 👍 oder 🚀 reagiert haben. Doppel-Pay strukturell unmöglich via referenceId (`<id>_shipped`, `<id>_reaction_<userId>`). - Founder-Whitelist via FEEDBACK_FOUNDER_USER_IDS env (verhindert Self-Reward). - Drop voteCount-Spalte (durch reactions/score seit 0002 ersetzt). - Migration 0003_grant_log_drop_vote_count.sql idempotent, lokal + prod eingespielt. Plan: docs/plans/feedback-rewards-and-identity.md (Phase 3.A-3.F). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
/**
|
|
* mana-analytics — Public-Community Feedback Hub
|
|
*
|
|
* Hono + Bun runtime. Routes:
|
|
* /api/v1/feedback/* — auth-required (jwtAuth via JWKS)
|
|
* /api/v1/public/feedback/* — read-only, no auth, redacted output
|
|
*/
|
|
|
|
import { Hono } from 'hono';
|
|
import { cors } from 'hono/cors';
|
|
import { loadConfig } from './config';
|
|
import { getDb } from './db/connection';
|
|
import { serviceErrorHandler as errorHandler } from '@mana/shared-hono';
|
|
import { jwtAuth } from './middleware/jwt-auth';
|
|
import { FeedbackService } from './services/feedback';
|
|
import { healthRoutes } from './routes/health';
|
|
import { createFeedbackRoutes } from './routes/feedback';
|
|
import { createPublicFeedbackRoutes } from './routes/public';
|
|
|
|
const config = loadConfig();
|
|
const db = getDb(config.databaseUrl);
|
|
|
|
const feedbackService = new FeedbackService(
|
|
db,
|
|
config.manaLlmUrl,
|
|
config.pseudonymSecret,
|
|
config.manaCreditsUrl,
|
|
config.serviceKey,
|
|
config.founderUserIds
|
|
);
|
|
|
|
const app = new Hono();
|
|
|
|
app.onError(errorHandler);
|
|
app.use('*', cors({ origin: config.cors.origins, credentials: true }));
|
|
|
|
app.route('/health', healthRoutes);
|
|
|
|
// Public surface: anonymous reads, no JWT required.
|
|
app.route('/api/v1/public/feedback', createPublicFeedbackRoutes(feedbackService));
|
|
|
|
// Authenticated surface: submit, react, manage own items, admin.
|
|
app.use('/api/v1/feedback/*', jwtAuth(config.manaAuthUrl));
|
|
app.route('/api/v1/feedback', createFeedbackRoutes(feedbackService));
|
|
|
|
console.log(`mana-analytics starting on port ${config.port}...`);
|
|
|
|
export default {
|
|
port: config.port,
|
|
fetch: app.fetch,
|
|
};
|