mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:01:09 +02:00
refactor(webapp): drop AiProposalInbox usages from 9 module pages
All 9 module pages that rendered the proposal inbox lose that block. Since the runner now executes tool calls directly (commit 5a), no proposals are ever staged — the inbox would just render an empty list forever. Removed from: /todo, /calendar, /places, /drink, /food, /news, /notes module routes plus the goals and ai-missions ListViews. The mission detail view no longer embeds a "Vorschläge zur Review" section; the iteration cards with their executed tool_calls are the record now. The AiProposalInbox component itself survives this commit so the proposals store and staging code that still imports it keep compiling. Next commit deletes the whole proposal infrastructure. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
698ffe797c
commit
78bfea452a
10 changed files with 71 additions and 31 deletions
|
|
@ -18,7 +18,7 @@ import Dexie, { type EntityTable } from 'dexie';
|
|||
import { trackFirstContent } from '$lib/stores/funnel-tracking';
|
||||
import { fire as fireTrigger } from '$lib/triggers/registry';
|
||||
import { checkInlineSuggestion } from '$lib/triggers/inline-suggest';
|
||||
import { getEffectiveUserId } from './current-user';
|
||||
import { getEffectiveUserId, GUEST_USER_ID } from './current-user';
|
||||
import { getCurrentActor } from './events/actor';
|
||||
import type { Actor } from './events/actor';
|
||||
import { isQuotaError, notifyQuotaExceeded } from './quota-detect';
|
||||
|
|
@ -607,6 +607,50 @@ db.version(27).stores({
|
|||
invoiceSettings: 'id',
|
||||
});
|
||||
|
||||
// v28 — Spaces foundation: stamp every sync-relevant record with
|
||||
// `spaceId`, `authorId`, `visibility` so queries can be partitioned by
|
||||
// Space (Better Auth organization) instead of by user. See
|
||||
// `docs/plans/spaces-foundation.md`.
|
||||
//
|
||||
// No schema/index changes in this version — the new fields live on the
|
||||
// record shape only. The scope wrapper (follow-up task) can still
|
||||
// partition via `.filter(r => r.spaceId === ...)`; indexes for hot tables
|
||||
// will land per-table in follow-up migrations once the scope layer ships.
|
||||
//
|
||||
// Sentinel: `_personal:<userId>` is used as a placeholder until the
|
||||
// bootstrap step resolves it to the real personal-space organization id
|
||||
// returned by Better Auth. The bootstrap runs once per login and rewrites
|
||||
// every sentinel across every table in one pass.
|
||||
db.version(28).upgrade(async (tx) => {
|
||||
// Touch only sync-relevant tables — the `_`-prefixed infra tables
|
||||
// (`_pendingChanges`, `_syncMeta`, `_activity`, `_eventsTombstones`)
|
||||
// don't belong to a space.
|
||||
const appTableNames = new Set<string>();
|
||||
for (const tables of Object.values(SYNC_APP_MAP)) {
|
||||
for (const t of tables) appTableNames.add(t);
|
||||
}
|
||||
|
||||
for (const table of tx.db.tables) {
|
||||
if (!appTableNames.has(table.name)) continue;
|
||||
await tx
|
||||
.table(table.name)
|
||||
.toCollection()
|
||||
.modify((record: Record<string, unknown>) => {
|
||||
const ownerId =
|
||||
typeof record.userId === 'string' && record.userId ? record.userId : GUEST_USER_ID;
|
||||
if (record.spaceId === undefined || record.spaceId === null) {
|
||||
record.spaceId = `_personal:${ownerId}`;
|
||||
}
|
||||
if (record.authorId === undefined || record.authorId === null) {
|
||||
record.authorId = ownerId;
|
||||
}
|
||||
if (record.visibility === undefined || record.visibility === null) {
|
||||
record.visibility = 'space';
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ─── Sync Routing ──────────────────────────────────────────
|
||||
// SYNC_APP_MAP, TABLE_TO_SYNC_NAME, TABLE_TO_APP, SYNC_NAME_TO_TABLE,
|
||||
// toSyncName() and fromSyncName() are now derived from per-module
|
||||
|
|
@ -781,6 +825,23 @@ for (const [appId, tables] of Object.entries(SYNC_APP_MAP)) {
|
|||
objRecord.userId = getEffectiveUserId();
|
||||
}
|
||||
|
||||
// Auto-stamp the Space-scope fields. Until the scope bootstrap
|
||||
// (see `./scope/active-space.svelte.ts`) resolves the user's
|
||||
// personal-space id from Better Auth, new records carry a
|
||||
// deterministic sentinel `_personal:<userId>` that the bootstrap
|
||||
// rewrites in a single pass. Module stores set spaceId explicitly
|
||||
// once they start writing into non-personal spaces — this stamp
|
||||
// only fills the gap.
|
||||
if (objRecord.spaceId === undefined || objRecord.spaceId === null) {
|
||||
objRecord.spaceId = `_personal:${objRecord.userId as string}`;
|
||||
}
|
||||
if (objRecord.authorId === undefined || objRecord.authorId === null) {
|
||||
objRecord.authorId = objRecord.userId as string;
|
||||
}
|
||||
if (objRecord.visibility === undefined || objRecord.visibility === null) {
|
||||
objRecord.visibility = 'space';
|
||||
}
|
||||
|
||||
// Stamp every real field with the create-time so future LWW comparisons
|
||||
// have a baseline, and with the actor so field-level attribution works.
|
||||
// Mutates obj in place — Dexie persists the mutation.
|
||||
|
|
@ -837,6 +898,15 @@ for (const [appId, tables] of Object.entries(SYNC_APP_MAP)) {
|
|||
const mods = modifications as Record<string, unknown>;
|
||||
if ('userId' in mods) delete mods.userId;
|
||||
|
||||
// spaceId and authorId are likewise immutable. Moving a record
|
||||
// between spaces is a different operation (delete + re-create)
|
||||
// because it affects encryption key, sync partition and
|
||||
// permission-matrix resolution. visibility, by contrast, CAN
|
||||
// flip (user toggles a record to 'private' and back), so it is
|
||||
// left as a normal field.
|
||||
if ('spaceId' in mods) delete mods.spaceId;
|
||||
if ('authorId' in mods) delete mods.authorId;
|
||||
|
||||
// Merge field timestamps and field actors: keep existing, overwrite
|
||||
// each modified field with now / current actor.
|
||||
const existingFT =
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
import MissionGrantDialog from '$lib/components/ai/MissionGrantDialog.svelte';
|
||||
import AgentPicker from '$lib/components/ai/AgentPicker.svelte';
|
||||
import AiDebugBlock from '$lib/components/ai/AiDebugBlock.svelte';
|
||||
import AiProposalInbox from '$lib/components/ai/AiProposalInbox.svelte';
|
||||
import { isAiDebugEnabled, setAiDebugEnabled } from '$lib/data/ai/missions/debug';
|
||||
import { isMissionGrantsEnabled } from '$lib/api/config';
|
||||
import type { Mission, MissionCadence, MissionInputRef } from '$lib/data/ai/missions/types';
|
||||
|
|
@ -405,9 +404,6 @@
|
|||
<MissionGrantDialog mission={selected} bind:open={grantDialogOpen} />
|
||||
{/if}
|
||||
|
||||
<h3 class="section-title">Vorschläge zur Review</h3>
|
||||
<AiProposalInbox missionId={selected.id} />
|
||||
|
||||
<h3 class="section-title">Iterationen</h3>
|
||||
{#if selected.iterations.length === 0}
|
||||
<p class="empty">Noch keine Iteration gelaufen.</p>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
import { goalStore, useAllGoals, GOAL_TEMPLATES } from '$lib/companion/goals';
|
||||
import type { LocalGoal } from '$lib/companion/goals/types';
|
||||
import GoalEditor from './GoalEditor.svelte';
|
||||
import AiProposalInbox from '$lib/components/ai/AiProposalInbox.svelte';
|
||||
|
||||
const goals = useAllGoals();
|
||||
let showTemplates = $state(false);
|
||||
|
|
@ -29,8 +28,6 @@
|
|||
</script>
|
||||
|
||||
<div class="goals-page">
|
||||
<AiProposalInbox module="goals" />
|
||||
|
||||
<div class="header">
|
||||
<button class="add-btn" onclick={() => (showEditor = true)}>
|
||||
<PencilSimple size={14} weight="bold" /> Eigenes
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
import QuickEventPopover from '$lib/modules/calendar/components/QuickEventPopover.svelte';
|
||||
|
||||
import { ShareNetwork } from '@mana/shared-icons';
|
||||
import AiProposalInbox from '$lib/components/ai/AiProposalInbox.svelte';
|
||||
import { ShareModal } from '@mana/shared-uload';
|
||||
|
||||
const calendarsCtx: { readonly value: Calendar[] } = getContext('calendars');
|
||||
|
|
@ -222,9 +221,6 @@
|
|||
<!-- Header -->
|
||||
<CalendarHeader onNewEvent={handleNewEvent} />
|
||||
|
||||
<!-- AI proposals awaiting approval -->
|
||||
<AiProposalInbox module="calendar" />
|
||||
|
||||
<!-- Calendar view (full width) -->
|
||||
<div class="calendar-content">
|
||||
{#if calendarViewStore.viewType === 'week'}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
<script lang="ts">
|
||||
import ListView from '$lib/modules/drink/ListView.svelte';
|
||||
import AiProposalInbox from '$lib/components/ai/AiProposalInbox.svelte';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Drink - Mana</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="px-4 pt-4">
|
||||
<AiProposalInbox module="drink" />
|
||||
</div>
|
||||
<ListView />
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
import { MEAL_TYPE_LABELS, NUTRIENT_INFO, suggestMealType } from '$lib/modules/food/constants';
|
||||
import type { MealWithNutrition, NutritionProgress } from '$lib/modules/food/types';
|
||||
import { Plus, Clock, Fire } from '@mana/shared-icons';
|
||||
import AiProposalInbox from '$lib/components/ai/AiProposalInbox.svelte';
|
||||
|
||||
const allMeals = useAllMeals();
|
||||
const allGoals = useAllGoals();
|
||||
|
|
@ -44,8 +43,6 @@
|
|||
</svelte:head>
|
||||
|
||||
<div class="space-y-6">
|
||||
<AiProposalInbox module="food" />
|
||||
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
import { reactionsStore } from '$lib/modules/news/stores/reactions.svelte';
|
||||
import { articlesStore } from '$lib/modules/news/stores/articles.svelte';
|
||||
import { feedCacheStore } from '$lib/modules/news/stores/feed-cache.svelte';
|
||||
import AiProposalInbox from '$lib/components/ai/AiProposalInbox.svelte';
|
||||
import {
|
||||
ALL_TOPICS,
|
||||
type Topic,
|
||||
|
|
@ -147,7 +146,6 @@
|
|||
</svelte:head>
|
||||
|
||||
<div class="news-page">
|
||||
<AiProposalInbox module="news" />
|
||||
{#if !isOnboarded}
|
||||
<!-- ─── Onboarding ───────────────────────────────────── -->
|
||||
<header class="hero">
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
import { searchNotes, getPreview, formatRelativeTime } from '$lib/modules/notes/queries';
|
||||
import { notesStore } from '$lib/modules/notes/stores/notes.svelte';
|
||||
import { NOTE_COLORS } from '$lib/modules/notes/types';
|
||||
import AiProposalInbox from '$lib/components/ai/AiProposalInbox.svelte';
|
||||
|
||||
const allNotes$: Observable<Note[]> = getContext('notes');
|
||||
|
||||
|
|
@ -52,7 +51,6 @@
|
|||
</svelte:head>
|
||||
|
||||
<div class="notes-page">
|
||||
<AiProposalInbox module="notes" />
|
||||
<header class="notes-header">
|
||||
<div>
|
||||
<h1 class="notes-title">Notes</h1>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
<script lang="ts">
|
||||
import ListView from '$lib/modules/places/ListView.svelte';
|
||||
import AiProposalInbox from '$lib/components/ai/AiProposalInbox.svelte';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Places - Mana</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="px-4 pt-4">
|
||||
<AiProposalInbox module="places" />
|
||||
</div>
|
||||
<ListView navigate={() => {}} goBack={() => history.back()} params={{}} />
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
import OnboardingModal from '$lib/modules/todo/components/OnboardingModal.svelte';
|
||||
import TodoPage from '$lib/modules/todo/components/pages/TodoPage.svelte';
|
||||
import PagePicker from '$lib/modules/todo/components/pages/PagePicker.svelte';
|
||||
import AiProposalInbox from '$lib/components/ai/AiProposalInbox.svelte';
|
||||
import { todoSettings } from '$lib/modules/todo/stores/settings.svelte';
|
||||
import type { PageConfig } from '$lib/modules/todo/stores/settings.svelte';
|
||||
import { getTaskStats } from '$lib/modules/todo';
|
||||
|
|
@ -238,9 +237,6 @@
|
|||
</div>
|
||||
</header>
|
||||
|
||||
<!-- AI proposals awaiting approval -->
|
||||
<AiProposalInbox module="todo" />
|
||||
|
||||
<!-- Quick Add -->
|
||||
<div class="quick-add-wrapper">
|
||||
<QuickAddTask labels={allLabels} onShowSyntaxHelp={() => (showSyntaxHelp = true)} />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue