import type { AssetType, ResultType, AvailabilityStatus, AvailabilityType, FreshnessStatus, RiskLevel, SourceType, DataQualityLevel, } from './enums' import { AvailabilityStatus as AS } from './enums' import type { PropertyUnit } from './unit' // Re-export unit types so all existing imports from 'property' continue to work export type { PropertyUnit, UnitBundle, UnitNeedMatch } from './unit' // ── Location / Address ──────────────────────────────────────────────────────── export interface Location { city: string district?: string canton?: string region?: string country: string coordinates?: { lat: number; lng: number } } export interface Address { street: string houseNumber: string postalCode: string city: string country: string } // ── Source Metadata ─────────────────────────────────────────────────────────── export interface SourceMeta { sourceType: SourceType | string sourceLabel?: string sourceUrl?: string sourceUpdatedAt?: string externalId?: string } // ── Data Quality ────────────────────────────────────────────────────────────── export interface DataQuality { score: number qualityLevel?: DataQualityLevel missingCriticalFields: string[] missingOptionalFields: string[] lastVerifiedAt?: string freshness: FreshnessStatus warnings: string[] } // ── Hard Facts ──────────────────────────────────────────────────────────────── export interface PropertyHardFacts { floor?: number fitOut?: 'SHELL' | 'BASIC' | 'FULL' | 'PREMIUM' parking?: number publicTransportScore?: number usageType?: string ceilingHeightM?: number loadingDocksCount?: number powerSupplyKva?: number hasServerRoom?: boolean isBarrierFree?: boolean hasAirConditioning?: boolean hasStorefront?: boolean } // ── Soft Factors ────────────────────────────────────────────────────────────── export interface SoftFactors { prestigeScore?: number visibilityScore?: number footfallScore?: number commuterAccessScore?: number talentAccessScore?: number esgScore?: number flexibilityScore?: number expansionPotentialScore?: number taxEnvironmentScore?: number // Legacy aliases kept for mock-data backward compatibility prestige?: number accessibility?: number talentAccess?: number esgRating?: string passerbyFrequency?: 'LOW' | 'MEDIUM' | 'HIGH' | 'VERY_HIGH' parkingSpots?: number publicTransportMinutes?: number infrastructureNotes?: string } // ── Property ────────────────────────────────────────────────────────────────── export interface Property { id: string organizationId?: string title: string assetType: AssetType resultType: ResultType location: Location address: Address areaSqm: number areaSqmMin?: number areaSqmMax?: number rentPricePerSqm: number rentChfSqmYear?: number totalRentMonthly?: number ancillaryCosts?: number availabilityDate: string availabilityStatus: AvailabilityStatus availabilityType?: AvailabilityType sourceType: string sourceLabel?: string sourceUrl?: string sourceUpdatedAt?: string sourceMeta?: SourceMeta confidenceScore: number dataQuality: DataQuality softFactors?: SoftFactors hardFacts?: PropertyHardFacts // Legacy fields — kept for backward compat floorLevel?: number expansionPotentialSqm?: number contractDurationMonths?: number riskLevel?: RiskLevel description?: string images?: string[] floorPlanUrl?: string leaseContractUrl?: string // link to the signed lease document leaseContractName?: string // display label, e.g. "Mietvertrag 2021–2026" propertyNumber?: string units?: PropertyUnit[] mapImageUrl?: string leaseTerm?: string leaseStartDate?: string leaseEndDate?: string breakoutOption?: boolean breakoutOptionDate?: string currentTenant?: string importedFrom?: string importedAt?: string lastUpdatedAt?: string schattenmarktRelease?: { enabled: boolean; leadTimeMonths?: number } status?: 'ACTIVE' | 'INACTIVE' | 'DRAFT' | 'ARCHIVED' lastReviewedAt?: string createdAt: string updatedAt: string } export type CreatePropertyInput = Omit export type UpdatePropertyInput = Partial /** * Returns the rentable units of a property. * For properties without explicit units, synthesises one unit from property-level data * so that all matching logic can operate uniformly at unit level. */ export function getEffectiveUnits(p: Property): PropertyUnit[] { if (p.units && p.units.length > 0) return p.units return [{ id: p.id, propertyId: p.id, floorLevel: p.hardFacts?.floor ?? p.floorLevel ?? 0, unitLabel: undefined, areaSqm: p.areaSqm, available: p.availabilityStatus === AS.AVAILABLE_NOW || p.availabilityStatus === AS.AVAILABLE_SOON, rentPricePerSqm: p.rentPricePerSqm, currentTenant: p.currentTenant, leaseTerm: p.leaseTerm, leaseEndDate: p.leaseEndDate, schattenmarktRelease: p.schattenmarktRelease?.enabled ? { enabled: true, availableFrom: p.leaseEndDate } : undefined, }] }