feat(auth): add organization management endpoints

Add missing organization features for Teams functionality:
- PUT /auth/organizations/:id - update organization
- DELETE /auth/organizations/:id - delete organization
- PATCH /auth/organizations/:orgId/members/:memberId/role - update member role
- GET /auth/organizations/:id/invitations - list org invitations
- GET /auth/invitations - list user invitations
- DELETE /auth/invitations/:id - cancel or reject invitation
This commit is contained in:
Till-JS 2026-02-16 12:43:38 +01:00
parent 9d618b107c
commit 5fe16b5eec
13 changed files with 1163 additions and 0 deletions

View file

@ -0,0 +1,135 @@
/**
* PWA Configuration Factory
*
* Creates a complete @vite-pwa/sveltekit configuration with sensible defaults
* and preset-based caching strategies.
*
* @example
* ```ts
* import { createPWAConfig } from '@manacore/shared-pwa';
* import { SvelteKitPWA } from '@vite-pwa/sveltekit';
*
* export default defineConfig({
* plugins: [
* sveltekit(),
* SvelteKitPWA(createPWAConfig({
* name: 'Calendar - Kalender',
* shortName: 'Calendar',
* description: 'Kalender mit Offline-Unterstützung',
* themeColor: '#3b82f6',
* preset: 'standard',
* })),
* ],
* });
* ```
*/
import type { PWAConfigOptions, PWAConfig, ManifestConfig, WorkboxConfig } from './types.js';
import {
DEFAULT_BACKGROUND_COLOR,
DEFAULT_CATEGORIES,
DEFAULT_INCLUDE_ASSETS,
DEFAULT_GLOB_PATTERNS,
DEFAULT_GLOB_IGNORES,
DEFAULT_NAVIGATE_FALLBACK_DENYLIST,
DEFAULT_ICONS,
} from './defaults.js';
import { getPresetRuntimeCaching } from './presets.js';
/**
* Create a complete PWA configuration for SvelteKit apps
*/
export function createPWAConfig(options: PWAConfigOptions): PWAConfig {
const {
name,
shortName,
description,
themeColor,
backgroundColor = DEFAULT_BACKGROUND_COLOR,
preset = 'standard',
shortcuts = [],
categories = DEFAULT_CATEGORIES,
includeAssets = [],
globIgnores = [],
additionalRuntimeCaching = [],
navigateFallback = '/offline',
navigateFallbackDenylist = DEFAULT_NAVIGATE_FALLBACK_DENYLIST,
devEnabled = true,
registerType = 'autoUpdate',
lang = 'de',
startUrl = '/',
} = options;
// Build manifest
const manifest: ManifestConfig = {
name,
short_name: shortName,
description,
theme_color: themeColor,
background_color: backgroundColor,
display: 'standalone',
orientation: 'any',
scope: '/',
start_url: startUrl,
lang,
categories,
icons: DEFAULT_ICONS,
};
// Add shortcuts if provided
if (shortcuts.length > 0) {
manifest.shortcuts = shortcuts.map((shortcut) => ({
name: shortcut.name,
short_name: shortcut.short_name,
description: shortcut.description,
url: shortcut.url,
icons: [{ src: 'pwa-192x192.png', sizes: '192x192' }],
}));
}
// Build workbox config
const workbox: WorkboxConfig = {
globPatterns: DEFAULT_GLOB_PATTERNS,
globIgnores: [...DEFAULT_GLOB_IGNORES, ...globIgnores],
cleanupOutdatedCaches: true,
clientsClaim: true,
skipWaiting: true,
navigateFallback,
navigateFallbackDenylist,
runtimeCaching: [...getPresetRuntimeCaching(preset), ...additionalRuntimeCaching],
};
// Return complete config
return {
registerType,
devOptions: {
enabled: devEnabled,
},
includeAssets: [...DEFAULT_INCLUDE_ASSETS, ...includeAssets],
manifest,
workbox,
};
}
/**
* Create PWA config with SQLite WASM support (for offline-first apps)
* Adds proper glob ignores and OPFS configuration
*/
export function createOfflineFirstPWAConfig(
options: PWAConfigOptions & {
/**
* Additional packages to exclude from precaching
*/
excludePackages?: string[];
}
): PWAConfig {
const { excludePackages = [], globIgnores = [], ...rest } = options;
// Add SQLite-specific ignores
const allGlobIgnores = ['**/*sqlite*', '**/*wasm*', ...excludePackages.map((pkg) => `**/${pkg}/**`), ...globIgnores];
return createPWAConfig({
...rest,
globIgnores: allGlobIgnores,
});
}

View file

@ -0,0 +1,66 @@
/**
* Default PWA Configuration Values
*/
import type { ManifestIcon } from './types.js';
/**
* Default dark background color for ManaCore apps
*/
export const DEFAULT_BACKGROUND_COLOR = '#09090b';
/**
* Default app categories
*/
export const DEFAULT_CATEGORIES = ['productivity', 'utilities'];
/**
* Default assets to include in PWA
*/
export const DEFAULT_INCLUDE_ASSETS = ['favicon.png', 'favicon.svg'];
/**
* Default glob patterns for precaching
*/
export const DEFAULT_GLOB_PATTERNS = ['**/*.{js,css,html,ico,png,svg,woff,woff2}'];
/**
* Default URL patterns to exclude from navigate fallback
*/
export const DEFAULT_NAVIGATE_FALLBACK_DENYLIST = [/^\/api/, /^\/auth/];
/**
* Default glob ignores (SQLite WASM for offline-first apps)
*/
export const DEFAULT_GLOB_IGNORES = ['**/*sqlite*'];
/**
* Standard PWA icon configuration
*/
export const DEFAULT_ICONS: ManifestIcon[] = [
{
src: 'pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'maskable',
},
];
/**
* Apple touch icon configuration
*/
export const APPLE_TOUCH_ICON = {
src: 'apple-touch-icon.png',
sizes: '180x180',
type: 'image/png',
};

View file

@ -0,0 +1,53 @@
/**
* @manacore/shared-pwa
*
* Unified PWA configuration for all ManaCore SvelteKit apps.
* Provides factory functions, presets, and defaults for consistent PWA setup.
*
* @example
* ```ts
* import { createPWAConfig } from '@manacore/shared-pwa';
* import { SvelteKitPWA } from '@vite-pwa/sveltekit';
*
* export default defineConfig({
* plugins: [
* sveltekit(),
* SvelteKitPWA(createPWAConfig({
* name: 'My App',
* shortName: 'MyApp',
* description: 'My awesome app',
* themeColor: '#3b82f6',
* })),
* ],
* });
* ```
*/
// Main factory functions
export { createPWAConfig, createOfflineFirstPWAConfig } from './config.js';
// Presets and cache strategies
export { getPresetRuntimeCaching, cacheStrategies } from './presets.js';
// Default values
export {
DEFAULT_BACKGROUND_COLOR,
DEFAULT_CATEGORIES,
DEFAULT_INCLUDE_ASSETS,
DEFAULT_GLOB_PATTERNS,
DEFAULT_GLOB_IGNORES,
DEFAULT_NAVIGATE_FALLBACK_DENYLIST,
DEFAULT_ICONS,
APPLE_TOUCH_ICON,
} from './defaults.js';
// Types
export type {
PWAConfigOptions,
PWAConfig,
PWAShortcut,
WorkboxPreset,
ManifestConfig,
ManifestIcon,
WorkboxConfig,
} from './types.js';

View file

@ -0,0 +1,124 @@
/**
* Workbox Runtime Caching Presets
*
* Provides pre-configured caching strategies for different app types:
* - minimal: Static assets only
* - standard: + API + Images
* - full: + Fonts + External resources
*/
import type { RuntimeCaching } from 'workbox-build';
import type { WorkboxPreset } from './types.js';
/**
* API caching strategy - NetworkFirst with fallback
* Used for all *.mana.how API endpoints
*/
const API_CACHE: RuntimeCaching = {
urlPattern: /^https:\/\/.*\.mana\.how\/api\/.*/i,
handler: 'NetworkFirst',
options: {
cacheName: 'api-cache',
expiration: {
maxEntries: 100,
maxAgeSeconds: 60 * 60 * 24, // 24 hours
},
cacheableResponse: {
statuses: [0, 200],
},
},
};
/**
* Image caching strategy - CacheFirst for performance
* Caches images for 30 days
*/
const IMAGE_CACHE: RuntimeCaching = {
urlPattern: /\.(?:png|jpg|jpeg|svg|gif|webp)$/i,
handler: 'CacheFirst',
options: {
cacheName: 'image-cache',
expiration: {
maxEntries: 200,
maxAgeSeconds: 60 * 60 * 24 * 30, // 30 days
},
},
};
/**
* Font caching strategy - CacheFirst with long expiration
* For Google Fonts and other web fonts
*/
const FONT_CACHE: RuntimeCaching = {
urlPattern: /^https:\/\/fonts\.(?:googleapis|gstatic)\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'font-cache',
expiration: {
maxEntries: 30,
maxAgeSeconds: 60 * 60 * 24 * 365, // 1 year
},
cacheableResponse: {
statuses: [0, 200],
},
},
};
/**
* External resources caching - StaleWhileRevalidate
* For CDN resources and external APIs
*/
const EXTERNAL_CACHE: RuntimeCaching = {
urlPattern: /^https:\/\/cdn\..*/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'external-cache',
expiration: {
maxEntries: 50,
maxAgeSeconds: 60 * 60 * 24 * 7, // 7 days
},
cacheableResponse: {
statuses: [0, 200],
},
},
};
/**
* Preset configurations for different caching strategies
*/
const PRESETS: Record<WorkboxPreset, RuntimeCaching[]> = {
/**
* Minimal preset - Only static assets (precached)
* Use for simple apps without API calls
*/
minimal: [],
/**
* Standard preset - Static + API + Images
* Recommended for most apps
*/
standard: [API_CACHE, IMAGE_CACHE],
/**
* Full preset - Standard + Fonts + External resources
* Use for apps with custom fonts or external CDN resources
*/
full: [API_CACHE, IMAGE_CACHE, FONT_CACHE, EXTERNAL_CACHE],
};
/**
* Get runtime caching rules for a preset
*/
export function getPresetRuntimeCaching(preset: WorkboxPreset): RuntimeCaching[] {
return PRESETS[preset] ?? PRESETS.standard;
}
/**
* Export individual cache strategies for custom configurations
*/
export const cacheStrategies = {
api: API_CACHE,
images: IMAGE_CACHE,
fonts: FONT_CACHE,
external: EXTERNAL_CACHE,
};

View file

@ -0,0 +1,180 @@
/**
* PWA Configuration Types for ManaCore Apps
*/
import type { SvelteKitPWAOptions } from '@vite-pwa/sveltekit';
import type { RuntimeCaching, ManifestEntry } from 'workbox-build';
/**
* Workbox preset types for different caching strategies
*/
export type WorkboxPreset = 'minimal' | 'standard' | 'full';
/**
* PWA manifest shortcut
*/
export interface PWAShortcut {
name: string;
short_name?: string;
description?: string;
url: string;
}
/**
* Configuration options for createPWAConfig
*/
export interface PWAConfigOptions {
/**
* Full name of the app (displayed in install prompts, app switcher)
* @example "Calendar - Kalender"
*/
name: string;
/**
* Short name for home screen icons (max ~12 chars)
* @example "Calendar"
*/
shortName: string;
/**
* App description for store listings
*/
description: string;
/**
* Primary theme color (address bar, splash screen)
* @example "#3b82f6"
*/
themeColor: string;
/**
* Background color for splash screen
* @default "#09090b"
*/
backgroundColor?: string;
/**
* Workbox caching preset
* - minimal: Only static assets (simple apps without API)
* - standard: + API (NetworkFirst) + Images (CacheFirst)
* - full: + Fonts + External Resources
* @default "standard"
*/
preset?: WorkboxPreset;
/**
* App shortcuts for quick actions
*/
shortcuts?: PWAShortcut[];
/**
* App categories for store listings
* @default ["productivity", "utilities"]
*/
categories?: string[];
/**
* Additional assets to include (besides default icons)
*/
includeAssets?: string[];
/**
* Additional glob patterns to ignore in precaching
*/
globIgnores?: string[];
/**
* Additional runtime caching rules
*/
additionalRuntimeCaching?: RuntimeCaching[];
/**
* Custom navigate fallback path
* @default "/offline"
*/
navigateFallback?: string;
/**
* URL patterns to exclude from navigate fallback
* @default [/^\/api/, /^\/auth/]
*/
navigateFallbackDenylist?: RegExp[];
/**
* Enable PWA in development mode
* @default true
*/
devEnabled?: boolean;
/**
* Service worker register type
* @default "autoUpdate"
*/
registerType?: 'autoUpdate' | 'prompt';
/**
* App language
* @default "de"
*/
lang?: string;
/**
* Start URL when app is launched
* @default "/"
*/
startUrl?: string;
}
/**
* Internal manifest icon configuration
*/
export interface ManifestIcon {
src: string;
sizes: string;
type: string;
purpose?: 'any' | 'maskable' | 'monochrome';
}
/**
* Full manifest configuration
*/
export interface ManifestConfig {
name: string;
short_name: string;
description: string;
theme_color: string;
background_color: string;
display: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
orientation: 'any' | 'portrait' | 'landscape';
scope: string;
start_url: string;
lang: string;
categories: string[];
icons: ManifestIcon[];
shortcuts?: Array<{
name: string;
short_name?: string;
description?: string;
url: string;
icons?: Array<{ src: string; sizes: string }>;
}>;
}
/**
* Workbox configuration subset
*/
export interface WorkboxConfig {
globPatterns: string[];
globIgnores?: string[];
cleanupOutdatedCaches: boolean;
clientsClaim: boolean;
skipWaiting: boolean;
navigateFallback: string;
navigateFallbackDenylist: RegExp[];
runtimeCaching: RuntimeCaching[];
}
/**
* Complete PWA configuration result
*/
export type PWAConfig = SvelteKitPWAOptions;