Files
Momento/memento-note/lib/types.ts
sepehr b92f6384a4
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 1m11s
fix: chat memory lost between messages + per-note history
Chat (AIChat floating widget): conversationId was never captured from
the API response, so every message created a new conversation with no
context. Now creates the conversation upfront before streaming (same
pattern as ChatContainer) so the ID persists across messages.

Note history: was stored globally in UserAISettings, so enabling
history on one note enabled it for ALL notes. Now each Note has its
own historyEnabled boolean field. The "Enable history" action only
affects the specific note. A migration adds the column with default
false.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 22:18:46 +02:00

234 lines
6.8 KiB
TypeScript

export interface CheckItem {
id: string;
text: string;
checked: boolean;
}
/**
* Notebook model for organizing notes
*/
export interface Notebook {
id: string;
name: string;
icon: string | null;
color: string | null;
order: number;
userId: string;
createdAt: Date;
updatedAt: Date;
// Relations
notes?: Note[];
labels?: Label[];
}
/**
* Label model - contextual to notebooks
*/
export interface Label {
id: string;
name: string;
color: LabelColorName;
notebookId: string | null; // NEW: Belongs to a notebook
userId?: string | null; // DEPRECATED: Kept for backward compatibility
createdAt: Date;
updatedAt: Date;
// Relations
notebook?: Notebook | null;
}
export interface LinkMetadata {
url: string;
title?: string;
description?: string;
imageUrl?: string;
siteName?: string;
}
export interface Note {
id: string;
title: string | null;
content: string;
color: string;
isPinned: boolean;
isArchived: boolean;
trashedAt?: Date | null;
type: 'text' | 'checklist';
checkItems: CheckItem[] | null;
labels: string[] | null; // DEPRECATED: Array of label names stored as JSON string
images: string[] | null;
links: LinkMetadata[] | null;
reminder: Date | null;
isReminderDone: boolean;
reminderRecurrence: string | null;
reminderLocation: string | null;
isMarkdown: boolean;
dismissedFromRecent?: boolean;
size: NoteSize;
order: number;
createdAt: Date;
updatedAt: Date;
contentUpdatedAt: Date;
sharedWith?: string[];
userId?: string | null;
// Notebook relation (optional - null = "General Notes" / Inbox)
notebookId?: string | null;
notebook?: Notebook | null;
autoGenerated?: boolean | null;
aiProvider?: string | null;
historyEnabled?: boolean;
// Search result metadata (optional)
matchType?: 'exact' | 'related' | null;
searchScore?: number | null;
}
export interface NoteHistoryEntry {
id: string;
noteId: string;
userId: string;
version: number;
reason: string | null;
title: string | null;
content: string;
color: string;
isPinned: boolean;
isArchived: boolean;
type: 'text' | 'checklist';
checkItems: CheckItem[] | null;
labels: string[] | null;
images: string[] | null;
links: LinkMetadata[] | null;
isMarkdown: boolean;
size: NoteSize;
notebookId: string | null;
createdAt: Date;
}
export type NoteSize = 'small' | 'medium' | 'large';
export interface LabelWithColor {
name: string;
color: LabelColorName;
}
export const LABEL_COLORS = {
gray: {
bg: 'bg-zinc-100 dark:bg-zinc-800',
text: 'text-zinc-700 dark:text-zinc-300',
border: 'border-zinc-200 dark:border-zinc-700',
icon: 'text-zinc-500 dark:text-zinc-400'
},
red: {
bg: 'bg-rose-100 dark:bg-rose-900/40',
text: 'text-rose-700 dark:text-rose-300',
border: 'border-rose-200 dark:border-rose-800',
icon: 'text-rose-500 dark:text-rose-400'
},
orange: {
bg: 'bg-orange-100 dark:bg-orange-900/40',
text: 'text-orange-700 dark:text-orange-300',
border: 'border-orange-200 dark:border-orange-800',
icon: 'text-orange-500 dark:text-orange-400'
},
yellow: {
bg: 'bg-amber-100 dark:bg-amber-900/40',
text: 'text-amber-700 dark:text-amber-300',
border: 'border-amber-200 dark:border-amber-800',
icon: 'text-amber-500 dark:text-amber-400'
},
green: {
bg: 'bg-emerald-100 dark:bg-emerald-900/40',
text: 'text-emerald-700 dark:text-emerald-300',
border: 'border-emerald-200 dark:border-emerald-800',
icon: 'text-emerald-500 dark:text-emerald-400'
},
teal: {
bg: 'bg-teal-100 dark:bg-teal-900/40',
text: 'text-teal-700 dark:text-teal-300',
border: 'border-teal-200 dark:border-teal-800',
icon: 'text-teal-500 dark:text-teal-400'
},
blue: {
bg: 'bg-sky-100 dark:bg-sky-900/40',
text: 'text-sky-700 dark:text-sky-300',
border: 'border-sky-200 dark:border-sky-800',
icon: 'text-sky-500 dark:text-sky-400'
},
purple: {
bg: 'bg-violet-100 dark:bg-violet-900/40',
text: 'text-violet-700 dark:text-violet-300',
border: 'border-violet-200 dark:border-violet-800',
icon: 'text-violet-500 dark:text-violet-400'
},
pink: {
bg: 'bg-fuchsia-100 dark:bg-fuchsia-900/40',
text: 'text-fuchsia-700 dark:text-fuchsia-300',
border: 'border-fuchsia-200 dark:border-fuchsia-800',
icon: 'text-fuchsia-500 dark:text-fuchsia-400'
},
} as const;
export type LabelColorName = keyof typeof LABEL_COLORS
export const NOTE_COLORS = {
default: {
bg: 'bg-white dark:bg-zinc-900',
hover: 'hover:bg-gray-50 dark:hover:bg-zinc-800',
card: 'bg-white dark:bg-zinc-900 border-gray-200 dark:border-zinc-700'
},
red: {
bg: 'bg-red-50 dark:bg-red-950/30',
hover: 'hover:bg-red-100 dark:hover:bg-red-950/50',
card: 'bg-red-50 dark:bg-red-950/30 border-red-100 dark:border-red-900/50'
},
orange: {
bg: 'bg-orange-50 dark:bg-orange-950/30',
hover: 'hover:bg-orange-100 dark:hover:bg-orange-950/50',
card: 'bg-orange-50 dark:bg-orange-950/30 border-orange-100 dark:border-orange-900/50'
},
yellow: {
bg: 'bg-yellow-50 dark:bg-yellow-950/30',
hover: 'hover:bg-yellow-100 dark:hover:bg-yellow-950/50',
card: 'bg-yellow-50 dark:bg-yellow-950/30 border-yellow-100 dark:border-yellow-900/50'
},
green: {
bg: 'bg-green-50 dark:bg-green-950/30',
hover: 'hover:bg-green-100 dark:hover:bg-green-950/50',
card: 'bg-green-50 dark:bg-green-950/30 border-green-100 dark:border-green-900/50'
},
teal: {
bg: 'bg-teal-50 dark:bg-teal-950/30',
hover: 'hover:bg-teal-100 dark:hover:bg-teal-950/50',
card: 'bg-teal-50 dark:bg-teal-950/30 border-teal-100 dark:border-teal-900/50'
},
blue: {
bg: 'bg-blue-50 dark:bg-blue-950/30',
hover: 'hover:bg-blue-100 dark:hover:bg-blue-950/50',
card: 'bg-blue-50 dark:bg-blue-950/30 border-blue-100 dark:border-blue-900/50'
},
purple: {
bg: 'bg-purple-50 dark:bg-purple-950/30',
hover: 'hover:bg-purple-100 dark:hover:bg-purple-950/50',
card: 'bg-purple-50 dark:bg-purple-950/30 border-purple-100 dark:border-purple-900/50'
},
pink: {
bg: 'bg-pink-50 dark:bg-pink-950/30',
hover: 'hover:bg-pink-100 dark:hover:bg-pink-950/50',
card: 'bg-pink-50 dark:bg-pink-950/30 border-pink-100 dark:border-pink-900/50'
},
gray: {
bg: 'bg-gray-100 dark:bg-gray-800/50',
hover: 'hover:bg-gray-200 dark:hover:bg-gray-700/50',
card: 'bg-gray-100 dark:bg-gray-800/50 border-gray-200 dark:border-gray-700'
},
} as const;
export type NoteColor = keyof typeof NOTE_COLORS;
/**
* Query types for adaptive search weighting
* - 'exact': User searched with quotes, looking for exact match (e.g., "Error 404")
* - 'conceptual': User is asking a question or looking for concepts (e.g., "how to cook")
* - 'mixed': No specific pattern detected, use default weights
*/
export type QueryType = 'exact' | 'conceptual' | 'mixed';