feat: F016 future availability workspace
2-panel workspace at /supply/future-availability: filterable signal list with FutureSignalCard (type/sensitivity/review badges + mandatory disclaimer) and collapsible detail panel with full evidence, review workflow (IN_REVIEW→APPROVED/REJECTED), shortlist action, and review task creation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
import type { FutureSignal } from '../domain/futureSignal'
|
||||
import type { SignalType } from '../domain/enums'
|
||||
import type { SignalType, ReviewStatus } from '../domain/enums'
|
||||
|
||||
export interface FutureSignalFilters {
|
||||
signalType?: SignalType
|
||||
minProbability?: number
|
||||
organizationId?: string
|
||||
isVerified?: boolean
|
||||
sensitivityLevel?: string
|
||||
reviewStatus?: ReviewStatus
|
||||
maxTimeHorizonMonths?: number
|
||||
}
|
||||
|
||||
export interface IFutureSignalProvider {
|
||||
@@ -13,4 +16,5 @@ export interface IFutureSignalProvider {
|
||||
getById(id: string): Promise<FutureSignal | null>
|
||||
getByProperty(propertyId: string): Promise<FutureSignal[]>
|
||||
verify(id: string, verifiedBy: string): Promise<FutureSignal>
|
||||
updateReviewStatus(id: string, status: ReviewStatus): Promise<FutureSignal>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { IFutureSignalProvider, FutureSignalFilters } from './IFutureSignalProvider'
|
||||
import type { FutureSignal } from '../domain/futureSignal'
|
||||
import type { ReviewStatus } from '../domain/enums'
|
||||
import { mockFutureSignals } from '../mock-data/futureSignals'
|
||||
|
||||
const store: FutureSignal[] = [...mockFutureSignals]
|
||||
@@ -11,6 +12,9 @@ export const MockupFutureSignalProvider: IFutureSignalProvider = {
|
||||
if (filters?.minProbability !== undefined) results = results.filter(s => s.probability >= filters.minProbability!)
|
||||
if (filters?.organizationId) results = results.filter(s => s.organizationId === filters.organizationId)
|
||||
if (filters?.isVerified !== undefined) results = results.filter(s => s.isVerified === filters.isVerified)
|
||||
if (filters?.sensitivityLevel) results = results.filter(s => s.sensitivityLevel === filters.sensitivityLevel)
|
||||
if (filters?.reviewStatus) results = results.filter(s => (s.reviewStatus ?? 'UNREVIEWED') === filters.reviewStatus)
|
||||
if (filters?.maxTimeHorizonMonths !== undefined) results = results.filter(s => s.timeHorizonMonths <= filters.maxTimeHorizonMonths!)
|
||||
return results.sort((a, b) => b.probability - a.probability)
|
||||
},
|
||||
async getById(id) {
|
||||
@@ -24,4 +28,9 @@ export const MockupFutureSignalProvider: IFutureSignalProvider = {
|
||||
store[idx] = { ...store[idx], isVerified: true, verifiedBy, verifiedAt: new Date().toISOString(), updatedAt: new Date().toISOString() }
|
||||
return store[idx]
|
||||
},
|
||||
async updateReviewStatus(id, status: ReviewStatus) {
|
||||
const idx = store.findIndex(s => s.id === id)
|
||||
store[idx] = { ...store[idx], reviewStatus: status, updatedAt: new Date().toISOString() }
|
||||
return store[idx]
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user