chore: archive inactive projects to apps-archived/

Move inactive projects out of active workspace:
- bauntown (community website)
- maerchenzauber (AI story generation)
- memoro (voice memo app)
- news (news aggregation)
- nutriphi (nutrition tracking)
- reader (reading app)
- uload (URL shortener)
- wisekeep (AI wisdom extraction)

Update CLAUDE.md documentation:
- Add presi to active projects
- Document archived projects section
- Update workspace configuration

Archived apps can be re-activated by moving back to apps/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Till-JS 2025-11-29 07:03:59 +01:00
parent b97149ac12
commit 61d181fbc2
3148 changed files with 437 additions and 46640 deletions

View file

@ -0,0 +1,60 @@
import { TextData, AudioVersion } from '~/types/database';
/**
* Migriert alte Audio-Daten zum neuen audioVersions Format
*/
export function migrateAudioData(data: TextData): TextData {
// Wenn bereits audioVersions existiert, keine Migration nötig
if (data.audioVersions && data.audioVersions.length > 0) {
return data;
}
// Wenn alte audio Daten existieren, migriere sie
if (data.audio && data.audio.chunks && data.audio.chunks.length > 0) {
const versionId = `v1-${data.audio.lastGenerated ? new Date(data.audio.lastGenerated).getTime() : Date.now()}`;
const audioVersion: AudioVersion = {
id: versionId,
chunks: data.audio.chunks,
settings: data.audio.settings || {
voice: data.tts?.voice || 'de-DE-Neural2-A',
speed: data.tts?.speed || 1,
},
totalSize: data.audio.totalSize,
hasLocalCache: data.audio.hasLocalCache,
createdAt: data.audio.lastGenerated || new Date().toISOString(),
};
return {
...data,
audioVersions: [audioVersion],
currentAudioVersion: versionId,
};
}
// Keine Audio-Daten vorhanden
return data;
}
/**
* Holt die aktuelle Audio-Version basierend auf currentAudioVersion
*/
export function getCurrentAudioVersion(data: TextData): AudioVersion | null {
if (!data.audioVersions || data.audioVersions.length === 0) {
return null;
}
if (data.currentAudioVersion) {
const version = data.audioVersions.find((v) => v.id === data.currentAudioVersion);
if (version) return version;
}
// Fallback: nimm die neueste Version
return data.audioVersions[data.audioVersions.length - 1];
}
/**
* Generiert eine neue Versions-ID
*/
export function generateVersionId(): string {
return `v${Date.now()}`;
}

View file

@ -0,0 +1,29 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Platform } from 'react-native';
// Platform-specific storage adapter for Supabase
const createStorage = () => {
// For web/SSR environments, use a no-op storage or localStorage
if (Platform.OS === 'web') {
// Check if we're in a browser environment
if (typeof window !== 'undefined' && window.localStorage) {
return {
getItem: async (key: string) => window.localStorage.getItem(key),
setItem: async (key: string, value: string) => window.localStorage.setItem(key, value),
removeItem: async (key: string) => window.localStorage.removeItem(key),
};
} else {
// SSR environment - return no-op storage
return {
getItem: async () => null,
setItem: async () => {},
removeItem: async () => {},
};
}
}
// For native platforms, use AsyncStorage
return AsyncStorage;
};
export const storage = createStorage();

View file

@ -0,0 +1,14 @@
import { createClient } from '@supabase/supabase-js';
import { storage } from './storage';
const supabaseUrl = process.env.EXPO_PUBLIC_SUPABASE_URL;
const supabaseAnonKey = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY;
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
auth: {
storage: storage,
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: false,
},
});