chore: archive 17 standalone app servers (replaced by unified API)

All app compute servers have been consolidated into apps/api/ (unified
Hono/Bun server). Old servers moved to apps/*/apps/server-archived/.

Archived: cards, chat, contacts, context, calendar, guides, moodlit,
mukke, news, nutriphi, picture, planta, presi, questions, storage, todo, traces

Still active: uload (separate domain), memoro (Supabase-based)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-02 21:37:45 +02:00
parent 9363063cd7
commit 3556fc18be
104 changed files with 153 additions and 65 deletions

View file

@ -237,7 +237,7 @@
bottom: 4.5rem;
left: 50%;
transform: translateX(-50%);
z-index: 45;
z-index: 91;
display: flex;
align-items: center;
gap: 0.25rem;

View file

@ -132,7 +132,7 @@
</div>
{/each}
{#if todayEvents.length === 0 && !showNewEvent}
{#if todayEvents.length === 0}
<p class="empty">Keine Termine heute</p>
{/if}
</div>

View file

@ -7,6 +7,10 @@
import { db } from '$lib/data/database';
import type { LocalContact } from './types';
// ─── Constants ────────────────────────────────────────────
export const SELF_CONTACT_ID = 'self-contact';
// ─── Collection Accessors ──────────────────────────────────
export const contactTable = db.table<LocalContact>('contacts');

View file

@ -10,6 +10,7 @@
import {
Star,
Users,
User,
Cake,
Heart,
Envelope,
@ -20,6 +21,7 @@
} from '@manacore/shared-icons';
import { PageShell } from '$lib/components/page-carousel';
import type { Contact } from '../../types';
import { SELF_CONTACT_ID } from '../../collections';
import {
getDisplayName,
getInitials,
@ -38,7 +40,8 @@
| 'has-phone'
| 'with-company'
| 'with-address'
| 'recent';
| 'recent'
| 'my-profile';
interface Props {
pageId: ContactPageId;
@ -132,6 +135,12 @@
return days <= 14;
},
},
'my-profile': {
title: 'Mein Profil',
color: '#8B5CF6',
icon: User,
filterFn: (c) => c.id === SELF_CONTACT_ID,
},
};
let meta = $derived(PAGE_META[pageId]);

View file

@ -18,5 +18,5 @@ export {
applyContactFilter,
groupByLetter,
} from './queries';
export { contactTable, CONTACTS_GUEST_SEED } from './collections';
export { contactTable, CONTACTS_GUEST_SEED, SELF_CONTACT_ID } from './collections';
export type { LocalContact, Contact, SortField, ContactFilter, ContactView } from './types';

View file

@ -5,11 +5,12 @@
* This store only exposes mutations that write to IndexedDB.
*/
import { contactTable } from '../collections';
import { contactTable, SELF_CONTACT_ID } from '../collections';
import { toContact } from '../queries';
import { createArchiveOps } from '@manacore/shared-stores';
import { ContactsEvents } from '@manacore/shared-utils/analytics';
import type { LocalContact, Contact } from '../types';
import type { UserProfile } from '$lib/api/profile';
/** Archive/soft-delete ops for contacts. */
export const contactArchive = createArchiveOps({ table: () => contactTable });
@ -110,4 +111,49 @@ export const contactsStore = {
await contactArchive.toggleArchive(id);
ContactsEvents.contactArchived();
},
/**
* Ensure the self-contact exists and is synced with the user's profile.
* Creates the contact if missing, updates it if profile data changed.
*/
async ensureSelfContact(profile: UserProfile): Promise<void> {
const nameParts = (profile.name || '').split(' ');
const firstName = nameParts[0] || undefined;
const lastName = nameParts.slice(1).join(' ') || undefined;
const existing = await contactTable.get(SELF_CONTACT_ID);
if (!existing) {
const self: LocalContact = {
id: SELF_CONTACT_ID,
firstName,
lastName,
email: profile.email || undefined,
photoUrl: profile.image || undefined,
isFavorite: true,
isArchived: false,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
};
await contactTable.add(self);
return;
}
// Sync profile fields if they changed
const needsUpdate =
existing.firstName !== firstName ||
existing.lastName !== lastName ||
existing.email !== (profile.email || undefined) ||
existing.photoUrl !== (profile.image || undefined);
if (needsUpdate) {
await contactTable.update(SELF_CONTACT_ID, {
firstName,
lastName,
email: profile.email || undefined,
photoUrl: profile.image || undefined,
updatedAt: new Date().toISOString(),
});
}
},
};

View file

@ -1,8 +1,11 @@
<script lang="ts">
import { setContext } from 'svelte';
import { setContext, onMount } from 'svelte';
import type { Snippet } from 'svelte';
import { useAllContacts } from '$lib/modules/contacts/queries';
import { contactsFilterStore } from '$lib/modules/contacts/stores/filter.svelte';
import { contactsStore } from '$lib/modules/contacts/stores/contacts.svelte';
import { profileService } from '$lib/api/profile';
import { authStore } from '$lib/stores/auth.svelte';
let { children }: { children: Snippet } = $props();
@ -14,6 +17,17 @@
// Initialize filter state from localStorage
contactsFilterStore.initialize();
// Ensure self-contact exists and stays synced with profile
onMount(async () => {
if (!authStore.isAuthenticated) return;
try {
const profile = await profileService.getProfile();
await contactsStore.ensureSelfContact(profile);
} catch {
// Profile fetch may fail for guest users — that's OK
}
});
</script>
{@render children()}

Some files were not shown because too many files have changed in this diff Show more