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:
Benjamin SutterandClaude Sonnet 4.6 committed 2026-05-16 21:19:52 +02:00
1 parent 65130efca7
commit 2e68638246
13 files changed
+767 -216

No files matched your search

@@ -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]
},
}