/** * Die Termintypen, die Ferdi führt. * * Mit Runde 8 (§4) kommen die Vertragstypen dazu: Ferdi verwaltet nicht mehr * nur allgemeine Erinnerungen, sondern erkennt die Zeitpunkte, an denen ein * Gewerbemietvertrag eine Entscheidung verlangt. * * Die Unterscheidung zwischen echter und unechter Option ist keine Spitzfindigkeit, * sondern der Kern des Ganzen: die **echte Option** gibt dem Mieter ein einseitiges * Gestaltungsrecht — verstreicht die Ausübungsfrist, ist das Recht erloschen, und * zwar unwiderruflich. Die **unechte Option** ist bloss eine Absichtserklärung, * über eine Fortsetzung zu verhandeln; hier gibt es keine Frist, die verfällt, * sondern ein Fenster, in dem verhandelt werden sollte. */ export const ReminderType = { LEASE_EXPIRY: 'LEASE_EXPIRY', BREAK_OPTION: 'BREAK_OPTION', RENT_REVIEW: 'RENT_REVIEW', INSPECTION: 'INSPECTION', INSURANCE_RENEWAL: 'INSURANCE_RENEWAL', MAINTENANCE: 'MAINTENANCE', SCHATTENMARKT_RELEASE: 'SCHATTENMARKT_RELEASE', CUSTOM: 'CUSTOM', // ── Contract Intelligence (Runde 8, §4) ──────────────────────────────────── /** Kündigungsfrist — ab wann eine Kündigung noch fristgerecht möglich ist. */ NOTICE_PERIOD: 'NOTICE_PERIOD', /** Echte Option — verbindlicher Ausübungszeitpunkt, danach erloschen. */ REAL_OPTION: 'REAL_OPTION', /** Unechte Option — Zeitfenster für Verhandlungen über eine Fortsetzung. */ UNREAL_OPTION: 'UNREAL_OPTION', /** Verhandlungsfenster ohne Option, etwa vor einer Staffelmietanpassung. */ NEGOTIATION_WINDOW: 'NEGOTIATION_WINDOW', /** Anstehendes Vertragsgespräch mit dem Mieter. */ CONTRACT_TALK: 'CONTRACT_TALK', } as const export type ReminderType = typeof ReminderType[keyof typeof ReminderType] /** Welche Vertragstypen aus der Dokumentanalyse stammen (Runde 8, §4). */ export const CONTRACT_REMINDER_TYPES: ReminderType[] = [ ReminderType.NOTICE_PERIOD, ReminderType.REAL_OPTION, ReminderType.UNREAL_OPTION, ReminderType.NEGOTIATION_WINDOW, ReminderType.CONTRACT_TALK, ] export const ReminderPriority = { URGENT: 'URGENT', // ≤14 days HIGH: 'HIGH', // 15–30 days MEDIUM: 'MEDIUM', // 31–60 days LOW: 'LOW', // >60 days } as const export type ReminderPriority = typeof ReminderPriority[keyof typeof ReminderPriority] export const ReminderStatus = { ACTIVE: 'ACTIVE', SNOOZED: 'SNOOZED', COMPLETED: 'COMPLETED', DISMISSED: 'DISMISSED', } as const export type ReminderStatus = typeof ReminderStatus[keyof typeof ReminderStatus] export const ShadowMarketRisk = { NONE: 'NONE', LOW: 'LOW', MEDIUM: 'MEDIUM', HIGH: 'HIGH', } as const export type ShadowMarketRisk = typeof ShadowMarketRisk[keyof typeof ShadowMarketRisk] export interface ReminderActivity { at: string // ISO date by: string // user display name action: 'CREATED' | 'SNOOZED' | 'COMPLETED' | 'DISMISSED' | 'NOTED' note?: string } export interface Reminder { id: string type: ReminderType priority: ReminderPriority status: ReminderStatus propertyId: string propertyTitle: string propertyCity: string propertyDistrict?: string tenantName: string dueDate: string // ISO date — when action must be taken eventDate: string // ISO date — contract event date (expiry / review / etc.) contractEndDate?: string // ISO date — lease end breakOptionDate?: string // ISO date areaSqm: number currentRentPerSqm: number currency: 'CHF' shadowMarketRisk: ShadowMarketRisk schattenmarktEnabled: boolean note?: string snoozedUntil?: string // ISO date // ── Contract Intelligence (Runde 8, §4) ──────────────────────────────────── /** * Der Zeitpunkt, an dem tatsächlich entschieden werden muss. * * Bewusst getrennt von `contractEndDate`: Ferdi orientiert sich nicht am * Vertragsende, sondern am früheren Entscheidungs-, Kündigungs-, Options- * oder Verhandlungszeitpunkt. Wer erst am Vertragsende erinnert, erinnert an * etwas, das nicht mehr zu ändern ist. */ decisionDate?: string /** Kündigungsfrist in Monaten, wie im Vertrag vereinbart. */ noticePeriodMonths?: number /** Bei unechten Optionen: ab wann verhandelt werden sollte. */ negotiationWindowFrom?: string /** Bei unechten Optionen: bis wann eine Einigung stehen sollte. */ negotiationWindowTo?: string /** Bezeichnung des Vertrags oder Nachtrags, aus dem der Termin stammt. */ contractRef?: string /** Fundstelle im Dokument — Ziffer, Artikel oder Seite. */ contractClause?: string /** Warum dieser Zeitpunkt relevant ist, in einem Satz. */ relevanceReason?: string /** Die empfohlene nächste Handlung — kein Fazit, ein Auftrag. */ recommendedAction?: string activity: ReminderActivity[] organizationId: string createdAt: string updatedAt: string }