Add improved production UI 3
This commit is contained in:
275
frontend/src/api/hooks/qualityTemplates.ts
Normal file
275
frontend/src/api/hooks/qualityTemplates.ts
Normal file
@@ -0,0 +1,275 @@
|
||||
// frontend/src/api/hooks/qualityTemplates.ts
|
||||
/**
|
||||
* React hooks for Quality Check Template API integration
|
||||
*/
|
||||
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { qualityTemplateService } from '../services/qualityTemplates';
|
||||
import type {
|
||||
QualityCheckTemplate,
|
||||
QualityCheckTemplateCreate,
|
||||
QualityCheckTemplateUpdate,
|
||||
QualityTemplateQueryParams,
|
||||
ProcessStage,
|
||||
QualityCheckExecutionRequest
|
||||
} from '../types/qualityTemplates';
|
||||
|
||||
// Query Keys
|
||||
export const qualityTemplateKeys = {
|
||||
all: ['qualityTemplates'] as const,
|
||||
lists: () => [...qualityTemplateKeys.all, 'list'] as const,
|
||||
list: (tenantId: string, params?: QualityTemplateQueryParams) =>
|
||||
[...qualityTemplateKeys.lists(), tenantId, params] as const,
|
||||
details: () => [...qualityTemplateKeys.all, 'detail'] as const,
|
||||
detail: (tenantId: string, templateId: string) =>
|
||||
[...qualityTemplateKeys.details(), tenantId, templateId] as const,
|
||||
forStage: (tenantId: string, stage: ProcessStage) =>
|
||||
[...qualityTemplateKeys.all, 'stage', tenantId, stage] as const,
|
||||
forRecipe: (tenantId: string, recipeId: string) =>
|
||||
[...qualityTemplateKeys.all, 'recipe', tenantId, recipeId] as const,
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to fetch quality check templates
|
||||
*/
|
||||
export function useQualityTemplates(
|
||||
tenantId: string,
|
||||
params?: QualityTemplateQueryParams,
|
||||
options?: { enabled?: boolean }
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: qualityTemplateKeys.list(tenantId, params),
|
||||
queryFn: () => qualityTemplateService.getTemplates(tenantId, params),
|
||||
enabled: !!tenantId && (options?.enabled ?? true),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to fetch a specific quality check template
|
||||
*/
|
||||
export function useQualityTemplate(
|
||||
tenantId: string,
|
||||
templateId: string,
|
||||
options?: { enabled?: boolean }
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: qualityTemplateKeys.detail(tenantId, templateId),
|
||||
queryFn: () => qualityTemplateService.getTemplate(tenantId, templateId),
|
||||
enabled: !!tenantId && !!templateId && (options?.enabled ?? true),
|
||||
staleTime: 10 * 60 * 1000, // 10 minutes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to fetch templates for a specific process stage
|
||||
*/
|
||||
export function useQualityTemplatesForStage(
|
||||
tenantId: string,
|
||||
stage: ProcessStage,
|
||||
isActive: boolean = true,
|
||||
options?: { enabled?: boolean }
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: qualityTemplateKeys.forStage(tenantId, stage),
|
||||
queryFn: () => qualityTemplateService.getTemplatesForStage(tenantId, stage, isActive),
|
||||
enabled: !!tenantId && !!stage && (options?.enabled ?? true),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to fetch templates organized by stages for recipe configuration
|
||||
*/
|
||||
export function useQualityTemplatesForRecipe(
|
||||
tenantId: string,
|
||||
recipeId: string,
|
||||
options?: { enabled?: boolean }
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: qualityTemplateKeys.forRecipe(tenantId, recipeId),
|
||||
queryFn: () => qualityTemplateService.getTemplatesForRecipe(tenantId, recipeId),
|
||||
enabled: !!tenantId && !!recipeId && (options?.enabled ?? true),
|
||||
staleTime: 10 * 60 * 1000, // 10 minutes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to create a quality check template
|
||||
*/
|
||||
export function useCreateQualityTemplate(tenantId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (templateData: QualityCheckTemplateCreate) =>
|
||||
qualityTemplateService.createTemplate(tenantId, templateData),
|
||||
onSuccess: (newTemplate) => {
|
||||
// Invalidate and refetch quality template lists
|
||||
queryClient.invalidateQueries({ queryKey: qualityTemplateKeys.lists() });
|
||||
|
||||
// Add to cache
|
||||
queryClient.setQueryData(
|
||||
qualityTemplateKeys.detail(tenantId, newTemplate.id),
|
||||
newTemplate
|
||||
);
|
||||
|
||||
toast.success('Plantilla de calidad creada exitosamente');
|
||||
},
|
||||
onError: (error: any) => {
|
||||
console.error('Error creating quality template:', error);
|
||||
toast.error(error.response?.data?.detail || 'Error al crear la plantilla de calidad');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to update a quality check template
|
||||
*/
|
||||
export function useUpdateQualityTemplate(tenantId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ templateId, templateData }: {
|
||||
templateId: string;
|
||||
templateData: QualityCheckTemplateUpdate;
|
||||
}) => qualityTemplateService.updateTemplate(tenantId, templateId, templateData),
|
||||
onSuccess: (updatedTemplate, { templateId }) => {
|
||||
// Update cached data
|
||||
queryClient.setQueryData(
|
||||
qualityTemplateKeys.detail(tenantId, templateId),
|
||||
updatedTemplate
|
||||
);
|
||||
|
||||
// Invalidate lists to refresh
|
||||
queryClient.invalidateQueries({ queryKey: qualityTemplateKeys.lists() });
|
||||
|
||||
toast.success('Plantilla de calidad actualizada exitosamente');
|
||||
},
|
||||
onError: (error: any) => {
|
||||
console.error('Error updating quality template:', error);
|
||||
toast.error(error.response?.data?.detail || 'Error al actualizar la plantilla de calidad');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to delete a quality check template
|
||||
*/
|
||||
export function useDeleteQualityTemplate(tenantId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (templateId: string) =>
|
||||
qualityTemplateService.deleteTemplate(tenantId, templateId),
|
||||
onSuccess: (_, templateId) => {
|
||||
// Remove from cache
|
||||
queryClient.removeQueries({
|
||||
queryKey: qualityTemplateKeys.detail(tenantId, templateId)
|
||||
});
|
||||
|
||||
// Invalidate lists to refresh
|
||||
queryClient.invalidateQueries({ queryKey: qualityTemplateKeys.lists() });
|
||||
|
||||
toast.success('Plantilla de calidad eliminada exitosamente');
|
||||
},
|
||||
onError: (error: any) => {
|
||||
console.error('Error deleting quality template:', error);
|
||||
toast.error(error.response?.data?.detail || 'Error al eliminar la plantilla de calidad');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to duplicate a quality check template
|
||||
*/
|
||||
export function useDuplicateQualityTemplate(tenantId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (templateId: string) =>
|
||||
qualityTemplateService.duplicateTemplate(tenantId, templateId),
|
||||
onSuccess: (duplicatedTemplate) => {
|
||||
// Add to cache
|
||||
queryClient.setQueryData(
|
||||
qualityTemplateKeys.detail(tenantId, duplicatedTemplate.id),
|
||||
duplicatedTemplate
|
||||
);
|
||||
|
||||
// Invalidate lists to refresh
|
||||
queryClient.invalidateQueries({ queryKey: qualityTemplateKeys.lists() });
|
||||
|
||||
toast.success('Plantilla de calidad duplicada exitosamente');
|
||||
},
|
||||
onError: (error: any) => {
|
||||
console.error('Error duplicating quality template:', error);
|
||||
toast.error(error.response?.data?.detail || 'Error al duplicar la plantilla de calidad');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to execute a quality check
|
||||
*/
|
||||
export function useExecuteQualityCheck(tenantId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (executionData: QualityCheckExecutionRequest) =>
|
||||
qualityTemplateService.executeQualityCheck(tenantId, executionData),
|
||||
onSuccess: (result, executionData) => {
|
||||
// Invalidate production batch data to refresh status
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['production', 'batches', tenantId]
|
||||
});
|
||||
|
||||
// Invalidate quality check history
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['qualityChecks', tenantId, executionData.batch_id]
|
||||
});
|
||||
|
||||
const message = result.overall_pass
|
||||
? 'Control de calidad completado exitosamente'
|
||||
: 'Control de calidad completado con observaciones';
|
||||
|
||||
if (result.overall_pass) {
|
||||
toast.success(message);
|
||||
} else {
|
||||
toast.error(message);
|
||||
}
|
||||
},
|
||||
onError: (error: any) => {
|
||||
console.error('Error executing quality check:', error);
|
||||
toast.error(error.response?.data?.detail || 'Error al ejecutar el control de calidad');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to get default templates for a product category
|
||||
*/
|
||||
export function useDefaultQualityTemplates(
|
||||
tenantId: string,
|
||||
productCategory: string,
|
||||
options?: { enabled?: boolean }
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: [...qualityTemplateKeys.all, 'defaults', tenantId, productCategory],
|
||||
queryFn: () => qualityTemplateService.getDefaultTemplates(tenantId, productCategory),
|
||||
enabled: !!tenantId && !!productCategory && (options?.enabled ?? true),
|
||||
staleTime: 15 * 60 * 1000, // 15 minutes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to validate template configuration
|
||||
*/
|
||||
export function useValidateQualityTemplate(tenantId: string) {
|
||||
return useMutation({
|
||||
mutationFn: (templateData: Partial<QualityCheckTemplateCreate | QualityCheckTemplateUpdate>) =>
|
||||
qualityTemplateService.validateTemplate(tenantId, templateData),
|
||||
onError: (error: any) => {
|
||||
console.error('Error validating quality template:', error);
|
||||
},
|
||||
});
|
||||
}
|
||||
205
frontend/src/api/services/qualityTemplates.ts
Normal file
205
frontend/src/api/services/qualityTemplates.ts
Normal file
@@ -0,0 +1,205 @@
|
||||
// frontend/src/api/services/qualityTemplates.ts
|
||||
/**
|
||||
* Quality Check Template API service
|
||||
*/
|
||||
|
||||
import { apiClient } from '../client';
|
||||
import type {
|
||||
QualityCheckTemplate,
|
||||
QualityCheckTemplateCreate,
|
||||
QualityCheckTemplateUpdate,
|
||||
QualityCheckTemplateList,
|
||||
QualityTemplateQueryParams,
|
||||
ProcessStage,
|
||||
QualityCheckExecutionRequest,
|
||||
QualityCheckExecutionResponse
|
||||
} from '../types/qualityTemplates';
|
||||
|
||||
class QualityTemplateService {
|
||||
private readonly baseURL = '/production/api/v1/quality-templates';
|
||||
|
||||
/**
|
||||
* Create a new quality check template
|
||||
*/
|
||||
async createTemplate(
|
||||
tenantId: string,
|
||||
templateData: QualityCheckTemplateCreate
|
||||
): Promise<QualityCheckTemplate> {
|
||||
const response = await apiClient.post(this.baseURL, templateData, {
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quality check templates with filtering and pagination
|
||||
*/
|
||||
async getTemplates(
|
||||
tenantId: string,
|
||||
params?: QualityTemplateQueryParams
|
||||
): Promise<QualityCheckTemplateList> {
|
||||
const response = await apiClient.get(this.baseURL, {
|
||||
params,
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific quality check template
|
||||
*/
|
||||
async getTemplate(
|
||||
tenantId: string,
|
||||
templateId: string
|
||||
): Promise<QualityCheckTemplate> {
|
||||
const response = await apiClient.get(`${this.baseURL}/${templateId}`, {
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a quality check template
|
||||
*/
|
||||
async updateTemplate(
|
||||
tenantId: string,
|
||||
templateId: string,
|
||||
templateData: QualityCheckTemplateUpdate
|
||||
): Promise<QualityCheckTemplate> {
|
||||
const response = await apiClient.put(`${this.baseURL}/${templateId}`, templateData, {
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a quality check template
|
||||
*/
|
||||
async deleteTemplate(tenantId: string, templateId: string): Promise<void> {
|
||||
await apiClient.delete(`${this.baseURL}/${templateId}`, {
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get templates applicable to a specific process stage
|
||||
*/
|
||||
async getTemplatesForStage(
|
||||
tenantId: string,
|
||||
stage: ProcessStage,
|
||||
isActive: boolean = true
|
||||
): Promise<QualityCheckTemplateList> {
|
||||
const response = await apiClient.get(`${this.baseURL}/stages/${stage}`, {
|
||||
params: { is_active: isActive },
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate an existing quality check template
|
||||
*/
|
||||
async duplicateTemplate(
|
||||
tenantId: string,
|
||||
templateId: string
|
||||
): Promise<QualityCheckTemplate> {
|
||||
const response = await apiClient.post(`${this.baseURL}/${templateId}/duplicate`, {}, {
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a quality check using a template
|
||||
*/
|
||||
async executeQualityCheck(
|
||||
tenantId: string,
|
||||
executionData: QualityCheckExecutionRequest
|
||||
): Promise<QualityCheckExecutionResponse> {
|
||||
const response = await apiClient.post('/production/api/v1/quality-checks/execute', executionData, {
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quality check history for a batch
|
||||
*/
|
||||
async getQualityCheckHistory(
|
||||
tenantId: string,
|
||||
batchId: string,
|
||||
stage?: ProcessStage
|
||||
): Promise<any[]> {
|
||||
const response = await apiClient.get('/production/api/v1/quality-checks', {
|
||||
params: { batch_id: batchId, process_stage: stage },
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quality check templates for recipe configuration
|
||||
*/
|
||||
async getTemplatesForRecipe(
|
||||
tenantId: string,
|
||||
recipeId: string
|
||||
): Promise<Record<ProcessStage, QualityCheckTemplate[]>> {
|
||||
const allTemplates = await this.getTemplates(tenantId, { is_active: true });
|
||||
|
||||
// Group templates by applicable stages
|
||||
const templatesByStage: Record<ProcessStage, QualityCheckTemplate[]> = {} as any;
|
||||
|
||||
Object.values(ProcessStage).forEach(stage => {
|
||||
templatesByStage[stage] = allTemplates.templates.filter(template =>
|
||||
!template.applicable_stages ||
|
||||
template.applicable_stages.length === 0 ||
|
||||
template.applicable_stages.includes(stage)
|
||||
);
|
||||
});
|
||||
|
||||
return templatesByStage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate template configuration
|
||||
*/
|
||||
async validateTemplate(
|
||||
tenantId: string,
|
||||
templateData: Partial<QualityCheckTemplateCreate | QualityCheckTemplateUpdate>
|
||||
): Promise<{ valid: boolean; errors: string[] }> {
|
||||
try {
|
||||
const response = await apiClient.post(`${this.baseURL}/validate`, templateData, {
|
||||
headers: { 'X-Tenant-ID': tenantId }
|
||||
});
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
if (error.response?.status === 400) {
|
||||
return {
|
||||
valid: false,
|
||||
errors: [error.response.data.detail || 'Validation failed']
|
||||
};
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default template suggestions based on product type
|
||||
*/
|
||||
async getDefaultTemplates(
|
||||
tenantId: string,
|
||||
productCategory: string
|
||||
): Promise<QualityCheckTemplate[]> {
|
||||
const templates = await this.getTemplates(tenantId, {
|
||||
is_active: true,
|
||||
category: productCategory
|
||||
});
|
||||
|
||||
// Return commonly used templates for the product category
|
||||
return templates.templates.filter(template =>
|
||||
template.is_required || template.weight > 5.0
|
||||
).sort((a, b) => b.weight - a.weight);
|
||||
}
|
||||
}
|
||||
|
||||
export const qualityTemplateService = new QualityTemplateService();
|
||||
173
frontend/src/api/types/qualityTemplates.ts
Normal file
173
frontend/src/api/types/qualityTemplates.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
// frontend/src/api/types/qualityTemplates.ts
|
||||
/**
|
||||
* Quality Check Template types for API integration
|
||||
*/
|
||||
|
||||
export enum QualityCheckType {
|
||||
VISUAL = 'visual',
|
||||
MEASUREMENT = 'measurement',
|
||||
TEMPERATURE = 'temperature',
|
||||
WEIGHT = 'weight',
|
||||
BOOLEAN = 'boolean',
|
||||
TIMING = 'timing'
|
||||
}
|
||||
|
||||
export enum ProcessStage {
|
||||
MIXING = 'mixing',
|
||||
PROOFING = 'proofing',
|
||||
SHAPING = 'shaping',
|
||||
BAKING = 'baking',
|
||||
COOLING = 'cooling',
|
||||
PACKAGING = 'packaging',
|
||||
FINISHING = 'finishing'
|
||||
}
|
||||
|
||||
export interface QualityCheckTemplate {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
name: string;
|
||||
template_code?: string;
|
||||
check_type: QualityCheckType;
|
||||
category?: string;
|
||||
description?: string;
|
||||
instructions?: string;
|
||||
parameters?: Record<string, any>;
|
||||
thresholds?: Record<string, any>;
|
||||
scoring_criteria?: Record<string, any>;
|
||||
is_active: boolean;
|
||||
is_required: boolean;
|
||||
is_critical: boolean;
|
||||
weight: number;
|
||||
min_value?: number;
|
||||
max_value?: number;
|
||||
target_value?: number;
|
||||
unit?: string;
|
||||
tolerance_percentage?: number;
|
||||
applicable_stages?: ProcessStage[];
|
||||
created_by: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface QualityCheckTemplateCreate {
|
||||
name: string;
|
||||
template_code?: string;
|
||||
check_type: QualityCheckType;
|
||||
category?: string;
|
||||
description?: string;
|
||||
instructions?: string;
|
||||
parameters?: Record<string, any>;
|
||||
thresholds?: Record<string, any>;
|
||||
scoring_criteria?: Record<string, any>;
|
||||
is_active?: boolean;
|
||||
is_required?: boolean;
|
||||
is_critical?: boolean;
|
||||
weight?: number;
|
||||
min_value?: number;
|
||||
max_value?: number;
|
||||
target_value?: number;
|
||||
unit?: string;
|
||||
tolerance_percentage?: number;
|
||||
applicable_stages?: ProcessStage[];
|
||||
created_by: string;
|
||||
}
|
||||
|
||||
export interface QualityCheckTemplateUpdate {
|
||||
name?: string;
|
||||
template_code?: string;
|
||||
check_type?: QualityCheckType;
|
||||
category?: string;
|
||||
description?: string;
|
||||
instructions?: string;
|
||||
parameters?: Record<string, any>;
|
||||
thresholds?: Record<string, any>;
|
||||
scoring_criteria?: Record<string, any>;
|
||||
is_active?: boolean;
|
||||
is_required?: boolean;
|
||||
is_critical?: boolean;
|
||||
weight?: number;
|
||||
min_value?: number;
|
||||
max_value?: number;
|
||||
target_value?: number;
|
||||
unit?: string;
|
||||
tolerance_percentage?: number;
|
||||
applicable_stages?: ProcessStage[];
|
||||
}
|
||||
|
||||
export interface QualityCheckTemplateList {
|
||||
templates: QualityCheckTemplate[];
|
||||
total: number;
|
||||
skip: number;
|
||||
limit: number;
|
||||
}
|
||||
|
||||
export interface QualityCheckCriterion {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
check_type: QualityCheckType;
|
||||
required: boolean;
|
||||
weight: number;
|
||||
acceptable_criteria: string;
|
||||
min_value?: number;
|
||||
max_value?: number;
|
||||
unit?: string;
|
||||
is_critical: boolean;
|
||||
}
|
||||
|
||||
export interface QualityCheckResult {
|
||||
criterion_id: string;
|
||||
value: number | string | boolean;
|
||||
score: number;
|
||||
notes?: string;
|
||||
photos?: string[];
|
||||
pass_check: boolean;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
export interface QualityCheckExecutionRequest {
|
||||
template_id: string;
|
||||
batch_id: string;
|
||||
process_stage: ProcessStage;
|
||||
checker_id?: string;
|
||||
results: QualityCheckResult[];
|
||||
final_notes?: string;
|
||||
photos?: string[];
|
||||
}
|
||||
|
||||
export interface QualityCheckExecutionResponse {
|
||||
check_id: string;
|
||||
overall_score: number;
|
||||
overall_pass: boolean;
|
||||
critical_failures: string[];
|
||||
corrective_actions: string[];
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
export interface ProcessStageQualityConfig {
|
||||
stage: ProcessStage;
|
||||
template_ids: string[];
|
||||
custom_parameters?: Record<string, any>;
|
||||
is_required: boolean;
|
||||
blocking: boolean;
|
||||
}
|
||||
|
||||
export interface RecipeQualityConfiguration {
|
||||
stages: Record<string, ProcessStageQualityConfig>;
|
||||
global_parameters?: Record<string, any>;
|
||||
default_templates?: string[];
|
||||
}
|
||||
|
||||
// Filter and query types
|
||||
export interface QualityTemplateFilters {
|
||||
stage?: ProcessStage;
|
||||
check_type?: QualityCheckType;
|
||||
is_active?: boolean;
|
||||
category?: string;
|
||||
search?: string;
|
||||
}
|
||||
|
||||
export interface QualityTemplateQueryParams extends QualityTemplateFilters {
|
||||
skip?: number;
|
||||
limit?: number;
|
||||
}
|
||||
Reference in New Issue
Block a user