mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
- Remove nested git repository from bugulma/frontend/.git - Add all frontend files to main repository tracking - Convert from separate frontend/backend repos to unified monorepo - Preserve all frontend code and development history as tracked files - Eliminate nested repository complexity for simpler development workflow This creates a proper monorepo structure with frontend and backend coexisting in the same repository for easier development and deployment.
170 lines
6.2 KiB
TypeScript
170 lines
6.2 KiB
TypeScript
import { z } from 'zod';
|
|
import {
|
|
createBackendEntitySchema,
|
|
idSchema,
|
|
timestampSchema,
|
|
nonNegativeNumberSchema,
|
|
positiveNumberSchema,
|
|
optionalUrlSchema,
|
|
scoreSchema,
|
|
} from '@/schemas/common';
|
|
|
|
/**
|
|
* Backend-aligned Match schemas
|
|
* Matches the Go backend domain.Match struct and related types
|
|
*
|
|
* Uses Zod v4's composition features and common schemas for DRY code
|
|
*/
|
|
|
|
/**
|
|
* Match status enum
|
|
* Uses Zod v4's improved enum support
|
|
*/
|
|
export const matchStatusSchema = z
|
|
.enum(['suggested', 'negotiating', 'reserved', 'contracted', 'live', 'failed', 'cancelled'])
|
|
.describe('Match status');
|
|
export type MatchStatus = z.infer<typeof matchStatusSchema>;
|
|
|
|
/**
|
|
* Transportation estimate schema
|
|
* Uses Zod v4's composition with common schemas
|
|
*/
|
|
export const transportationEstimateSchema = z
|
|
.object({
|
|
cost_per_year: nonNegativeNumberSchema.describe('Annual transportation cost'),
|
|
method: z.string().describe('Transportation method (piping, truck, tanker)'),
|
|
feasibility_score: scoreSchema.describe('Feasibility score (0-1)'),
|
|
})
|
|
.describe('Transportation estimate');
|
|
|
|
export type TransportationEstimate = z.infer<typeof transportationEstimateSchema>;
|
|
|
|
/**
|
|
* Risk assessment schema
|
|
* Uses Zod v4's composition with score validation
|
|
*/
|
|
export const riskAssessmentSchema = z
|
|
.object({
|
|
technical_risk: scoreSchema.describe('Technical risk (0-1)'),
|
|
regulatory_risk: scoreSchema.describe('Regulatory risk (0-1)'),
|
|
market_risk: scoreSchema.optional().describe('Market risk (0-1)'),
|
|
counterparty_risk: scoreSchema.optional().describe('Counterparty risk (0-1)'),
|
|
})
|
|
.describe('Risk assessment');
|
|
|
|
export type RiskAssessment = z.infer<typeof riskAssessmentSchema>;
|
|
|
|
/**
|
|
* Economic impact schema
|
|
* Uses Zod v4's composition with common number schemas
|
|
*/
|
|
export const economicImpactSchema = z
|
|
.object({
|
|
annual_savings: nonNegativeNumberSchema.optional().describe('Annual savings (€/year)'),
|
|
npv: z.number().optional().describe('Net Present Value'),
|
|
irr: z.number().optional().describe('Internal Rate of Return (%)'),
|
|
payback_years: positiveNumberSchema.optional().describe('Payback period (years)'),
|
|
co2_avoided_tonnes: nonNegativeNumberSchema.optional().describe('CO2 avoided (tonnes/year)'),
|
|
capex_required: nonNegativeNumberSchema.optional().describe('Initial investment (CAPEX)'),
|
|
opex_per_year: nonNegativeNumberSchema.optional().describe('Annual operational cost (OPEX)'),
|
|
})
|
|
.describe('Economic impact analysis');
|
|
|
|
export type EconomicImpact = z.infer<typeof economicImpactSchema>;
|
|
|
|
/**
|
|
* Match history entry schema
|
|
* Uses Zod v4's composition with timestamp validation
|
|
*/
|
|
export const matchHistoryEntrySchema = z
|
|
.object({
|
|
timestamp: timestampSchema.describe('Entry timestamp'),
|
|
actor: idSchema.describe('User ID who performed the action'),
|
|
action: z.string().describe('Action type (status_change, comment, update)'),
|
|
notes: z.string().optional().describe('Additional notes'),
|
|
old_value: z.string().optional().describe('Previous value'),
|
|
new_value: z.string().optional().describe('New value'),
|
|
})
|
|
.describe('Match history entry');
|
|
|
|
export type MatchHistoryEntry = z.infer<typeof matchHistoryEntrySchema>;
|
|
|
|
/**
|
|
* Contract details schema
|
|
* Uses Zod v4's composition with timestamp and URL validation
|
|
*/
|
|
export const contractDetailsSchema = z
|
|
.object({
|
|
contract_id: idSchema.optional().describe('Contract identifier'),
|
|
signed_at: timestampSchema.optional().describe('Contract signing timestamp'),
|
|
effective_from: timestampSchema.optional().describe('Contract effective date'),
|
|
value_per_year: nonNegativeNumberSchema.optional().describe('Annual contract value'),
|
|
terms_url: optionalUrlSchema.describe('URL to contract terms'),
|
|
})
|
|
.describe('Contract details');
|
|
|
|
export type ContractDetails = z.infer<typeof contractDetailsSchema>;
|
|
|
|
/**
|
|
* Backend Match schema
|
|
* Uses Zod v4's composition with common entity schema
|
|
*/
|
|
export const backendMatchSchema = createBackendEntitySchema({
|
|
SourceResourceID: idSchema.describe('Source resource flow ID'),
|
|
TargetResourceID: idSchema.describe('Target resource flow ID'),
|
|
CompatibilityScore: scoreSchema.describe('Overall compatibility score (0-1)'),
|
|
TemporalOverlapScore: scoreSchema.optional().describe('Temporal overlap score (0-1)'),
|
|
QualityScore: scoreSchema.optional().describe('Quality compatibility score (0-1)'),
|
|
EconomicValue: z.number().describe('Economic value'),
|
|
DistanceKm: nonNegativeNumberSchema.describe('Distance in kilometers'),
|
|
Status: matchStatusSchema,
|
|
Priority: z.number().int().describe('Match priority'),
|
|
TransportationEstimate: transportationEstimateSchema.optional(),
|
|
RiskAssessment: riskAssessmentSchema.optional(),
|
|
EconomicImpact: economicImpactSchema.optional(),
|
|
History: z.array(matchHistoryEntrySchema).optional().describe('Match history'),
|
|
ContractDetails: contractDetailsSchema.optional(),
|
|
ReservedUntil: timestampSchema.optional().describe('Reservation expiration timestamp'),
|
|
FailureReason: z.string().optional().describe('Reason for failure (if failed)'),
|
|
Version: z.number().int().optional().describe('Optimistic locking version'),
|
|
});
|
|
|
|
export type BackendMatch = z.infer<typeof backendMatchSchema>;
|
|
|
|
/**
|
|
* Response schema for find matches endpoint
|
|
* Uses Zod v4's composition
|
|
*/
|
|
export const findMatchesResponseSchema = z.object({
|
|
resource_id: idSchema.describe('Resource flow ID (from handler)'),
|
|
matches: z.array(backendMatchSchema).describe('Matching resource flows'),
|
|
count: z.number().int().nonnegative().describe('Total match count'),
|
|
});
|
|
|
|
export type FindMatchesResponse = z.infer<typeof findMatchesResponseSchema>;
|
|
|
|
/**
|
|
* Query parameters for finding matches
|
|
* Uses Zod v4's coerce and common number schemas
|
|
*/
|
|
export const findMatchesQuerySchema = z.object({
|
|
max_distance_km: z.coerce
|
|
.number()
|
|
.pipe(positiveNumberSchema)
|
|
.optional()
|
|
.describe('Maximum distance in kilometers'),
|
|
min_score: z.coerce
|
|
.number()
|
|
.pipe(scoreSchema)
|
|
.optional()
|
|
.describe('Minimum compatibility score (0-1)'),
|
|
limit: z.coerce
|
|
.number()
|
|
.int()
|
|
.pipe(positiveNumberSchema)
|
|
.optional()
|
|
.describe('Maximum number of results'),
|
|
});
|
|
|
|
export type FindMatchesQuery = z.infer<typeof findMatchesQuerySchema>;
|