feat(aura): onboarding.first_use (+25) hook in JWT-Branch
Some checks are pending
CI / validate (push) Waiting to run

Cross-App-Hook nach Pageta-Pattern. context.app='wordeck' im Payload.
Bewusst NICHT im dev-stub-Branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-05-18 12:52:29 +02:00
parent 1743fe6453
commit 070cb44de8
2 changed files with 42 additions and 0 deletions

View file

@ -1,5 +1,6 @@
import type { Context, MiddlewareHandler } from 'hono';
import { createRemoteJWKSet, jwtVerify } from 'jose';
import { fireFirstUseOnce } from '../services/aura-client.ts';
/**
* Auth-Middleware der Cards-API (Phase 2 Auth-Föderation).
@ -81,6 +82,9 @@ export const authMiddleware: MiddlewareHandler<{ Variables: AuthVars }> = async
c.set('userId', claims.sub);
c.set('tier', claims.tier);
c.set('authMode', 'jwt');
// Cross-App-Aura-Hook: erste Wordeck-Aktion → 25 Aura einmalig.
// Reason-Katalog: mana/docs/playbooks/AURA_PER_APP_HOOKS.md.
fireFirstUseOnce(claims.sub);
await next();
return;
}

View file

@ -0,0 +1,38 @@
/**
* Aura-Client für Service-to-Service-Calls an mana-admin.
*
* Heute: nur `fireFirstUseOnce` für den Cross-App-Hook
* `onboarding.first_use` (25 Aura, einmalig).
*
* Server-seitig (mana-admin Migration 0003) gibt es UNIQUE-Indizes
* auf `aura_ledger(user_id, reason)` für einmalig-Reasons, also
* sind Doppel-Awards auf DB-Ebene unmöglich. Der Process-Cache
* hier ist reine HTTP-Overhead-Reduktion.
*
* Reason-Katalog: mana/docs/playbooks/AURA_PER_APP_HOOKS.md.
*/
const firedFirstUse = new Set<string>();
export function fireFirstUseOnce(userId: string): void {
if (firedFirstUse.has(userId)) return;
firedFirstUse.add(userId);
const adminUrl = process.env.MANA_ADMIN_URL ?? 'http://localhost:3071';
const serviceKey = process.env.MANA_SERVICE_KEY ?? 'dev-service-key';
fetch(`${adminUrl}/api/v1/internal/aura/award`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Service-Key': serviceKey,
},
body: JSON.stringify({
userId,
delta: 25,
reason: 'onboarding.first_use',
refId: userId,
context: { app: 'wordeck' },
}),
}).catch(() => {});
}