feat(domain): F004 – expand domain model layer
- need.ts: add SizeRange, MustHaveCriterion, WeightedPreference types; extend Need with desiredLocation, sizeRange, mustHaveCriteria, weightedPreferences, status - futureSignal.ts: add SignalEvidence type; extend FutureSignal with title, evidence, matchabilityScore, reviewStatus - aiOutput.ts: new AIOutput entity with type, inputHash, outputJson, provider/model/promptVersion/schemaVersion, reviewStatus - activityEvent.ts: new ActivityEvent entity with actorId, action, entityType, entityId, timestamp, metadata - unifiedResult.ts: discriminated union (VerifiedPortfolioResult | ExternalMarketResult | FutureAvailabilityResult) - index.ts: export all three new files - Properties.tsx: add LIGHT_INDUSTRIAL + UNKNOWN cases to exhaustive switches Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+101
-6
@@ -1,13 +1,17 @@
|
||||
// ── Asset Types ───────────────────────────────────────────────────────────────
|
||||
export const AssetType = {
|
||||
OFFICE: 'OFFICE',
|
||||
RETAIL: 'RETAIL',
|
||||
GASTRO: 'GASTRO',
|
||||
GASTRO: 'GASTRO', // legacy – kept for mock-data compatibility
|
||||
LIGHT_INDUSTRIAL: 'LIGHT_INDUSTRIAL',
|
||||
LOGISTICS: 'LOGISTICS',
|
||||
PRODUCTION: 'PRODUCTION',
|
||||
MIXED: 'MIXED',
|
||||
UNKNOWN: 'UNKNOWN',
|
||||
} as const
|
||||
export type AssetType = typeof AssetType[keyof typeof AssetType]
|
||||
|
||||
// ── Result Types ──────────────────────────────────────────────────────────────
|
||||
export const ResultType = {
|
||||
VERIFIED_PORTFOLIO: 'VERIFIED_PORTFOLIO',
|
||||
EXTERNAL_MARKET: 'EXTERNAL_MARKET',
|
||||
@@ -15,6 +19,7 @@ export const ResultType = {
|
||||
} as const
|
||||
export type ResultType = typeof ResultType[keyof typeof ResultType]
|
||||
|
||||
// ── Match Strength ─────────────────────────────────────────────────────────────
|
||||
export const MatchStrength = {
|
||||
STRONG: 'STRONG',
|
||||
MODERATE: 'MODERATE',
|
||||
@@ -22,6 +27,17 @@ export const MatchStrength = {
|
||||
} as const
|
||||
export type MatchStrength = typeof MatchStrength[keyof typeof MatchStrength]
|
||||
|
||||
// ── Match Status ──────────────────────────────────────────────────────────────
|
||||
export const MatchStatus = {
|
||||
PENDING_REVIEW: 'PENDING_REVIEW',
|
||||
APPROVED: 'APPROVED',
|
||||
REJECTED: 'REJECTED',
|
||||
SHORTLISTED: 'SHORTLISTED',
|
||||
ARCHIVED: 'ARCHIVED',
|
||||
} as const
|
||||
export type MatchStatus = typeof MatchStatus[keyof typeof MatchStatus]
|
||||
|
||||
// ── Risk Level ────────────────────────────────────────────────────────────────
|
||||
export const RiskLevel = {
|
||||
LOW: 'LOW',
|
||||
MEDIUM: 'MEDIUM',
|
||||
@@ -30,6 +46,26 @@ export const RiskLevel = {
|
||||
} as const
|
||||
export type RiskLevel = typeof RiskLevel[keyof typeof RiskLevel]
|
||||
|
||||
// ── Confidence Level (qualitative) ───────────────────────────────────────────
|
||||
export const ConfidenceLevel = {
|
||||
VERY_HIGH: 'VERY_HIGH', // >= 0.90
|
||||
HIGH: 'HIGH', // >= 0.75
|
||||
MEDIUM: 'MEDIUM', // >= 0.55
|
||||
LOW: 'LOW', // >= 0.35
|
||||
VERY_LOW: 'VERY_LOW', // < 0.35
|
||||
} as const
|
||||
export type ConfidenceLevel = typeof ConfidenceLevel[keyof typeof ConfidenceLevel]
|
||||
|
||||
// ── Data Quality Level (qualitative) ─────────────────────────────────────────
|
||||
export const DataQualityLevel = {
|
||||
HIGH: 'HIGH', // >= 0.80
|
||||
MEDIUM: 'MEDIUM', // >= 0.60
|
||||
LOW: 'LOW', // < 0.60
|
||||
INCOMPLETE: 'INCOMPLETE', // missing critical fields
|
||||
} as const
|
||||
export type DataQualityLevel = typeof DataQualityLevel[keyof typeof DataQualityLevel]
|
||||
|
||||
// ── Availability Status ───────────────────────────────────────────────────────
|
||||
export const AvailabilityStatus = {
|
||||
AVAILABLE_NOW: 'AVAILABLE_NOW',
|
||||
AVAILABLE_SOON: 'AVAILABLE_SOON',
|
||||
@@ -39,13 +75,70 @@ export const AvailabilityStatus = {
|
||||
} as const
|
||||
export type AvailabilityStatus = typeof AvailabilityStatus[keyof typeof AvailabilityStatus]
|
||||
|
||||
export const DataFreshness = {
|
||||
FRESH: 'FRESH',
|
||||
STALE: 'STALE',
|
||||
OUTDATED: 'OUTDATED',
|
||||
// ── Availability Type (structural distinction) ────────────────────────────────
|
||||
export const AvailabilityType = {
|
||||
CONFIRMED: 'CONFIRMED', // verified, date known
|
||||
INDICATIVE: 'INDICATIVE', // external listing, unconfirmed
|
||||
PROBABILISTIC: 'PROBABILISTIC', // AI signal, no confirmed date
|
||||
} as const
|
||||
export type DataFreshness = typeof DataFreshness[keyof typeof DataFreshness]
|
||||
export type AvailabilityType = typeof AvailabilityType[keyof typeof AvailabilityType]
|
||||
|
||||
// ── Source Type ───────────────────────────────────────────────────────────────
|
||||
export const SourceType = {
|
||||
ERP_IMPORT: 'ERP_IMPORT',
|
||||
MANUAL_ENTRY: 'MANUAL_ENTRY',
|
||||
IMMOSCOUT_SCRAPE: 'IMMOSCOUT_SCRAPE',
|
||||
HOMEGATE_SCRAPE: 'HOMEGATE_SCRAPE',
|
||||
NEWHOME_SCRAPE: 'NEWHOME_SCRAPE',
|
||||
MATCHOFFICE_SCRAPE: 'MATCHOFFICE_SCRAPE',
|
||||
MAISON_WORK_SCRAPE: 'MAISON_WORK_SCRAPE',
|
||||
AI_SIGNAL: 'AI_SIGNAL',
|
||||
PARTNER_FEED: 'PARTNER_FEED',
|
||||
UNKNOWN: 'UNKNOWN',
|
||||
} as const
|
||||
export type SourceType = typeof SourceType[keyof typeof SourceType]
|
||||
|
||||
// ── Freshness Status ──────────────────────────────────────────────────────────
|
||||
export const FreshnessStatus = {
|
||||
FRESH: 'FRESH', // updated within 48h
|
||||
STALE: 'STALE', // 2–14 days old
|
||||
OUTDATED: 'OUTDATED', // > 14 days old
|
||||
} as const
|
||||
export type FreshnessStatus = typeof FreshnessStatus[keyof typeof FreshnessStatus]
|
||||
|
||||
/** @deprecated Use FreshnessStatus — kept for mock-data backward compatibility */
|
||||
export const DataFreshness = FreshnessStatus
|
||||
export type DataFreshness = FreshnessStatus
|
||||
|
||||
// ── Review Status ─────────────────────────────────────────────────────────────
|
||||
export const ReviewStatus = {
|
||||
UNREVIEWED: 'UNREVIEWED',
|
||||
IN_REVIEW: 'IN_REVIEW',
|
||||
APPROVED: 'APPROVED',
|
||||
REJECTED: 'REJECTED',
|
||||
FLAGGED: 'FLAGGED',
|
||||
} as const
|
||||
export type ReviewStatus = typeof ReviewStatus[keyof typeof ReviewStatus]
|
||||
|
||||
// ── Sensitivity Level ─────────────────────────────────────────────────────────
|
||||
export const SensitivityLevel = {
|
||||
PUBLIC: 'PUBLIC',
|
||||
INTERNAL: 'INTERNAL',
|
||||
CONFIDENTIAL: 'CONFIDENTIAL',
|
||||
RESTRICTED: 'RESTRICTED',
|
||||
} as const
|
||||
export type SensitivityLevel = typeof SensitivityLevel[keyof typeof SensitivityLevel]
|
||||
|
||||
// ── Shortlist Status ──────────────────────────────────────────────────────────
|
||||
export const ShortlistStatus = {
|
||||
ACTIVE: 'ACTIVE',
|
||||
SHARED: 'SHARED',
|
||||
ARCHIVED: 'ARCHIVED',
|
||||
CONVERTED: 'CONVERTED',
|
||||
} as const
|
||||
export type ShortlistStatus = typeof ShortlistStatus[keyof typeof ShortlistStatus]
|
||||
|
||||
// ── User Role ─────────────────────────────────────────────────────────────────
|
||||
export const UserRole = {
|
||||
SUPER_ADMIN: 'SUPER_ADMIN',
|
||||
ORGANIZATION_ADMIN: 'ORGANIZATION_ADMIN',
|
||||
@@ -56,6 +149,7 @@ export const UserRole = {
|
||||
} as const
|
||||
export type UserRole = typeof UserRole[keyof typeof UserRole]
|
||||
|
||||
// ── Signal Type ───────────────────────────────────────────────────────────────
|
||||
export const SignalType = {
|
||||
EXPANSION: 'EXPANSION',
|
||||
POSSIBLE_MOVE_OUT: 'POSSIBLE_MOVE_OUT',
|
||||
@@ -66,6 +160,7 @@ export const SignalType = {
|
||||
} as const
|
||||
export type SignalType = typeof SignalType[keyof typeof SignalType]
|
||||
|
||||
// ── Workspace ─────────────────────────────────────────────────────────────────
|
||||
export const WorkspaceType = {
|
||||
SUPPLY: 'SUPPLY',
|
||||
DEMAND: 'DEMAND',
|
||||
|
||||
Reference in New Issue
Block a user