feat(infra): add api.mana.how route + Prometheus scrape targets for Go services

- Cloudflare Tunnel: api.mana.how → localhost:3060 (Go API Gateway)
- Prometheus: scrape targets for mana-api-gateway:3060 and mana-matrix-bot:4000

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-27 21:27:04 +01:00
parent c81527c57c
commit a31ccc6c62
11 changed files with 434 additions and 95 deletions

View file

@ -43,6 +43,7 @@
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
"@manacore/shared-icons": "workspace:*",
"@manacore/local-store": "workspace:*",
"@manacore/shared-app-onboarding": "workspace:*",
"@manacore/shared-tailwind": "workspace:*",
"@manacore/shared-theme": "workspace:*",

View file

@ -0,0 +1,51 @@
/**
* Guest seed data for the SkilltTree app.
*
* Provides a demo skill with an activity to showcase the leveling system.
*/
import type { LocalSkill, LocalActivity } from './local-store';
const DEMO_SKILL_ID = 'demo-coding';
export const guestSkills: LocalSkill[] = [
{
id: DEMO_SKILL_ID,
name: 'Programmieren',
description: 'Software-Entwicklung und Coding-Skills',
branch: 'intellect',
icon: '💻',
currentXp: 150,
totalXp: 150,
level: 1,
},
{
id: 'demo-fitness',
name: 'Fitness',
description: 'Körperliche Fitness und Training',
branch: 'body',
icon: '💪',
currentXp: 50,
totalXp: 50,
level: 0,
},
];
export const guestActivities: LocalActivity[] = [
{
id: 'activity-1',
skillId: DEMO_SKILL_ID,
xpEarned: 100,
description: 'TypeScript-Projekt aufgesetzt',
duration: 60,
timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
},
{
id: 'activity-2',
skillId: DEMO_SKILL_ID,
xpEarned: 50,
description: 'Unit Tests geschrieben',
duration: 30,
timestamp: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(),
},
];

View file

@ -0,0 +1,71 @@
/**
* SkilltTree Local-First Data Layer (via @manacore/local-store)
*
* Adds unified sync support alongside the existing idb-based IndexedDB storage.
* Skills, activities, and achievements are synced to the server when authenticated.
*/
import { createLocalStore, type BaseRecord } from '@manacore/local-store';
import { guestSkills, guestActivities } from './guest-seed';
// ─── Types ──────────────────────────────────────────────────
export interface LocalSkill extends BaseRecord {
name: string;
description: string;
branch: 'intellect' | 'body' | 'creativity' | 'social' | 'practical' | 'mindset' | 'custom';
parentId?: string | null;
icon: string;
color?: string | null;
currentXp: number;
totalXp: number;
level: number;
}
export interface LocalActivity extends BaseRecord {
skillId: string;
xpEarned: number;
description: string;
duration?: number | null;
timestamp: string;
}
export interface LocalAchievement extends BaseRecord {
key: string;
name: string;
description: string;
icon: string;
unlockedAt: string;
}
// ─── Store ──────────────────────────────────────────────────
const SYNC_SERVER_URL = import.meta.env.PUBLIC_SYNC_SERVER_URL || 'http://localhost:3050';
export const skilltreeStore = createLocalStore({
appId: 'skilltree',
collections: [
{
name: 'skills',
indexes: ['branch', 'parentId', 'level'],
guestSeed: guestSkills,
},
{
name: 'activities',
indexes: ['skillId', 'timestamp'],
guestSeed: guestActivities,
},
{
name: 'achievements',
indexes: ['key', 'unlockedAt'],
},
],
sync: {
serverUrl: SYNC_SERVER_URL,
},
});
// Typed collection accessors
export const skillCollection = skilltreeStore.collection<LocalSkill>('skills');
export const activityCollection = skilltreeStore.collection<LocalActivity>('activities');
export const achievementCollection = skilltreeStore.collection<LocalAchievement>('achievements');

View file

@ -8,10 +8,17 @@
import { MiniOnboardingModal } from '@manacore/shared-app-onboarding';
import { skilltreeOnboarding } from '$lib/stores/app-onboarding.svelte';
import { SessionExpiredBanner, AuthGate } from '@manacore/shared-auth-ui';
import { skilltreeStore } from '$lib/data/local-store';
let { children } = $props();
async function handleAuthReady() {
// Initialize unified local-store (IndexedDB + sync)
await skilltreeStore.initialize();
if (authStore.isAuthenticated) {
skilltreeStore.startSync(() => authStore.getValidToken());
}
// Initialize existing idb-based stores
await skillStore.initialize();
await achievementStore.initialize();
}